当前位置:网站首页>[web page performance optimization] - about lazy image loading
[web page performance optimization] - about lazy image loading
2022-07-22 17:06:00 【Cherry pill peach】
List of articles
Preface
Tips : Here you can add the general content to be recorded in this article :
Lazy loading is a Web performance optimization
The way , It can greatly improve the user experience . Like pictures , Images have always been a major culprit in web page performance , Now it's very common for a picture to exceed a few megabytes . If every time you enter the page, request all the image resources , Then the user may have left long ago when the image is loaded . therefore , We need lazy loading , When entering the page , Only request image resources in the visual area .
There are two points to sum up :
- Loading it all will affect the user experience
- Waste user traffic , Some users don't want to see it all , Full loading consumes a lot of traffic
Tips : The following is the main body of this article , The following cases can be used for reference
Realization way
html Realization
The simplest way to implement it is to img
Tag plus loading="lazy"'
, such as
<img src="./example.jpg" loading="lazy">
The compatibility of this attribute is ok , You can use the production environment
js Realization
We go through js The scrolling of the monitoring page can also be realized .
Use js The principle of implementation is to judge whether the current picture has reached the visual area :
- Get all the pictures dom
- Traverse each image to determine whether the current image is within the scope of the visual area
- If you get there, set the picture src attribute
- binding window Of scroll event , Monitor it for events
During page initialization ,<img>
The image src
It's actually on data-src
On the properties , When the element is in the visible range , Just put data-src
Assign a value to src
attribute , Complete lazy loading of pictures .
// At the beginning of loading
<img data-src="http://xx.com/xx.png" src="" />
// When entering the visual range
<img data-src="http://xx.com/xx.png" src="http://xx.com/xx.png" />
<div>
Use the background map to achieve , The principle is the same , hold background-image
When placed in the visible range , Just put data-src
Assign a value to src attribute , Finish loading pictures
// At the beginning of loading
<div data-src="http://xx.com/xx.png" style="background-image: none; background-size: cover;" ></div>
// When entering the visual range
<div data-src="http://xx.com/xx.png" style="background-image: url(http://xx.com/xx.png); background-size: cover;" ></div>
Here's a demo:
<html lang="en">
<head>
<meta charset="UTF-8" />
<title>Lazyload</title>
<style> img{
display: block; margin-bottom: 50px; height: 200px; width: 400px; } </style>
</head>
<body>
<img src="./img/default.png" data-src="./img/1.jpg" />
<img src="./img/default.png" data-src="./img/2.jpg" />
<img src="./img/default.png" data-src="./img/3.jpg" />
<img src="./img/default.png" data-src="./img/4.jpg" />
<img src="./img/default.png" data-src="./img/5.jpg" />
<img src="./img/default.png" data-src="./img/6.jpg" />
<img src="./img/default.png" data-src="./img/7.jpg" />
<img src="./img/default.png" data-src="./img/8.jpg" />
<img src="./img/default.png" data-src="./img/9.jpg" />
</body>
</html>
( The relevant content of judging the visual area is introduced at the end of the text )
Get all the pictures first dom , adopt document.body.clientHeight
Get the height of the viewing area , Reuse element.getBoundingClientRect()
API Get the element relative to the browser directly top value , Traverse each image to determine whether the current image is within the scope of the visual area . The code is as follows :
function lazyload() {
let viewHeight = document.body.clientHeight // Get the height of the viewing area
let imgs = document.querySelectorAll('img[data-src]')
imgs.forEach((item, index) => {
if (item.dataset.src === "") return
// It is used to get the left , On , The position of the right and bottom relative to the browser window respectively
let rect = item.getBoundingClientRect()
if (rect.bottom >= 0 && rect.top < viewHeight) {
item.src = item.dataset.src
item.removeAttribute('data-src')
}
})
}
Finally, give window
binding onscroll
event
window.addEventListener('scroll', lazyload)
This completes the lazy loading operation of an image . But there are big performance problems , because scroll
The event will trigger many times in a short time , Serious impact on page performance , We need a throttling function to control the multiple triggering of the function , Over a period of time ( Such as 200ms) Only one callback is executed .
Next, we implement a throttling function
function throttle(fn, delay) {
let timer
let prevTime
return function (...args) {
const currTime = Date.now()
const context = this
if(!prevTime) prevTime = curTime
clearTimeout(timer)
if(currTime - preTime > delay) {
prevTime = currTime
fn.apply(context, args)
clearTimeout(timer)
return
}
timer = setTimeout(function () {
prevTime = Date.now()
timer = null
fn.apply(context, args)
}, delay)
}
}
Then make a change scroll
event
window.addEventListener('scroll', throttle(lazyload, 200))
expand :IntersectionObserver
Through the implementation of the above example , We need to monitor if we want to implement lazy loading scroll
event , Although we can use function throttling to prevent high-frequency execution of functions , But we still need to calculate scrollTop
,offsetHeight
Equal attribute , Is there a simple way to avoid calculating these properties , The answer is IntersectionObserver
.
IntersectionObserver
It's a relatively new API, Can be automatically " Observe " Whether elements are visible ,Chrome 51+ Has supported . Because it's visible (visible) The essence is , The target element creates an intersection with the viewport , So this API be called " Cross viewer ". Let's take a look at its usage :
var io = new IntersectionObserver(callback, option)
// Start to observe
io.observe(document.getElementById('example'))
// Stop observing
io.unobserve(element)
// Turn off the viewer
io.disconnect()
IntersectionObserver
It's the browser's native constructor , Take two parameters :callback
Is a callback function when visibility changes ,option
It's the configuration object ( This parameter is optional ).
When the visibility of the target element changes , The viewer's callback function is called callback
.callback
It usually triggers twice . Once the target element has just entered the viewport ( Start to see ), The other is to leave the view completely ( It's not visible at first ).
Now let's use IntersectionObserver
Lazy image loading
const imgs = document.querySelectorAll('img[data-src]')
const config = {
rootMargin: '0px',
threshold: 0,
}
let observer = new IntersectionObserver((entries, self) => {
entries.forEach((entry) => {
if (entry.isIntersecting) {
let img = entry.target
let src = img.dataset.src
if (src) {
img.src = src
img.removeAttribute('data-src')
}
// Release observation
self.unobserve(entry.target)
}
})
}, config)
imgs.forEach((image) => {
observer.observe(image)
})
Judgment of visual area
As shown in the figure above , Let the image in the viewable area of the browser display , Those outside the visible area are not displayed .
Here are a few api function :
The visible area of the page is wide :
document.body.clientWidth;
Page visible area high :document.body.clientHeight;
Page visible area width :document.body.offsetWidth
( Including the width of the sideline );
Page visible area high :document.body.offsetHeight
( Including the width of the sideline );
Full text width of web page body :document.body.scrollWidth
Page body full text height :document.body.scrollHeight
Web pages are rolled high :document.body.scrollTop
Left side of web page :document.body.scrollLeft
On the body of the page :window.screenTop
Page body left :window.screenLeft
High screen resolution :window.screen.height
Width of screen resolution :window.screen.width
Screen available workspace height :window.screen.availHeight
getBoundingClientRect()
Used to get the left side of an element in the page , On , The position of the right and bottom relative to the browser window respectively .HTMLElement.offsetTop
Is a read-only property , It returns the current element relative to itsoffsetParent
The distance from the top of the element .window.innerHeight
The viewport of the browser window (viewport) Height ( In pixels ); If there is a horizontal scroll bar , It also includes the height of the scroll bar .
边栏推荐
- Web 应用程序渗透测试的四个主要步骤
- 微信支付项目实战、创建订单到支付退款代码详解
- 5 minutes to talk about the enterprise PAAS platform hzero!
- I, AI doctoral student, online crowdfunding research topic
- 线程系列协程原理
- FPGA - memory resources of internal structure of 7 Series FPGA -02- FIFO resources
- Codeforce d2. RGB substring (hard version) sliding window
- CF1635F Closest Pair
- 5. SSH Remote Service
- ORA-16525 dg broker不可用
猜你喜欢
1143. 最长公共子序列
TensorFlow 各优化器在鸢尾花分类任务中的应用
Is there anyone who can't analyze these data cases? A trick to teach you how to visualize recruitment data~
数字化路径与实践思考
UE4 设置夜晚(根据DirectionalLight方向更新SkySphere)
LVS, this is enough
通过删除注册表破解plsql
【vs】如何查看线程阻塞在哪里
Concis组件库 | 暗黑模式设计
Hzero enterprise level digital PAAS platform (II) | enterprise level authority system
随机推荐
网络基础原理概述
Overview of basic principles of network
lvs看这篇就够了
codeforce D2. RGB Substring (hard version) 滑動窗口
Use ffmpeg to push and pull streams
AT2336 [ARC069D] Flags
【红队】ATT&CK - 浏览器扩展实现持久化
Hande enterprise PAAS platform hzero released version 1.5.0.release
numpy.random.seed()
汉得集成平台 集星獭 1.4.0 版本正式发布!
2022/7/19-日报
Yuanqi Digitalization: existing mode or open source innovation Lixia action
UE4 将画刷制作的物体合并成一个整体
codeforce D2. RGB Substring (hard version) 滑动窗口
Model compression, acceleration and mobile deployment
Visual system design example (Halcon WinForm) -8. matching search
汉得企业级数字化PaaS平台 HZERO 1.9.0 版本正式发布!
Hande x Jiuli special materials | work together to create a collaborative office portal and help it internal standardized management
14_响应模型
Ora-16525 DG broker not available