Lazy loading of first screen optimization
Lazy-Load. It is optimized for the timing of image loading: On some websites with a large amount of images (such as the homepage of e-commerce websites, or group buying websites, small game homepages, etc.), if we try to put all the image resources when the user opens the page After loading, it may cause a blank screen, freezes, etc., because there are too many pictures, and the browser can't handle so many tasks in one go!
purpose
The purpose of lazy loading is an optimized way to load pictures when the picture on the page enters the user's visible range.
It can increase the loading speed of the first screen. After all, the moment the user clicks on the page, only the first screen is presented to him. We only need to load the resource image of the first screen. As for the image below, when the user slides down, it will be the current position. When it is loaded, there is no problem when it is loaded, the performance pressure is also less, and the user experience has not deteriorated.
principle
When the page is initialized,<img>
picture src
actually put data-src
on the property when the element is in the visible range, put data-src
assigned to src
property, complete the picture loaded.
// 在一开始加载的时候
<img data-src="http://xx.com/xx.png" src="" />
// 在进入可视范围内时
<img data-src="http://xx.com/xx.png" src="http://xx.com/xx.png" />
Use the background image to achieve the same principle. Put background-image
in the visible range and assign src
data-src
to complete the image loading.
// 在一开始加载的时候
<div
data-src="http://xx.com/xx.png"
style="background-image: none;background-size: cover;"
></div>
// 在进入可视范围内时
<div
data-src="http://xx.com/xx.png"
style="background-image: url(http://xx.com/xx.png);background-size: cover;"
></div>
Implement a lazy loading
Based on the above implementation ideas, implement a lazy loading by yourself.
Create a new index.html
img
tags for these pictures:
<head>
<style>
.img {
width: 200px;
height: 200px;
background-color: gray;
margin-bottom: 20px;
}
.pic {
width: 100%;
height: 100%;
}
</style>
</head>
<!-- 图片来自网络,侵删。 -->
<body>
<div class="container">
<div class="img">
<!-- 注意我们并没有为它引入真实的src -->
<img
class="pic"
alt="加载中"
data-src="https://tse1-mm.cn.bing.net/th/id/OIP.8OrEFn_rKe82kqAWFjTuMwHaEo?pid=Api&rs=1"
/>
</div>
<div class="img">
<img
class="pic"
alt="加载中"
data-src="https://ssl.tzoo-img.com/images/tzoo.94911.0.910013.seoul-nami.jpg?width=1080"
/>
</div>
<div class="img">
<img
class="pic"
alt="加载中"
data-src="https://tse4-mm.cn.bing.net/th/id/OIP.ZitgAuABnwkrGn4lid2ZmQHaEK?pid=Api&rs=1"
/>
</div>
<div class="img">
<img
class="pic"
alt="加载中"
data-src="http://pic34.photophoto.cn/20150315/0034034862056002_b.jpg"
/>
</div>
<div class="img">
<img
class="pic"
alt="加载中"
data-src="http://img.mp.sohu.com/upload/20170724/32d4409f34194b029ed287abf1c99b70_th.png"
/>
</div>
<div class="img">
<img
class="pic"
alt="加载中"
data-src="https://pic6.wed114.cn/20180829/2018082910075991913520.jpg"
/>
</div>
<div class="img">
<img
class="pic"
alt="加载中"
data-src="https://tse4-mm.cn.bing.net/th/id/OIP.PZdPKj3sXEX2jLrepx3MUwHaEo?pid=Api&rs=1"
/>
</div>
<div class="img">
<img
class="pic"
alt="加载中"
data-src="https://pic6.wed114.cn/20180829/2018082910075831439349.jpg"
/>
</div>
<div class="img">
<img
class="pic"
alt="加载中"
data-src="https://pic6.wed114.cn/20180829/2018082910075468043336.jpg"
/>
</div>
<div class="img">
<img
class="pic"
alt="加载中"
data-src="https://tse2-mm.cn.bing.net/th/id/OIP.CRYz5Bv4vylsMh83G4CsLgHaFj?pid=Api&rs=1"
/>
</div>
</div>
</body>
In the implementation of lazy loading, there are two key values: one is the current viewable area of , 1607d318154bfe, and the other is element from the top of the viewable area, .
current highly visible area , in modern browsers and above IE9 browser, you can use window.innerHeight
property acquisition, use low versions of IE document.documentElment.clientHeight
get, here we are compatible in both cases:
const viewHeight = window.innerHeight || document.documentElement.clientHeight;
And the element from the top of the visible area is . Here we use the getBoundingClientRect()
method to get the size of the returned element and the position relative to the size. For this API, MDN’s explanation is:
The Element.getBoundingClientRect() method returns the size of the element and its position relative to the viewport.
top
attributes is the height relative to the top of the visible area, which is the 0607d318154c8f attribute, which is exactly the distance between the element we need and the top.
In this way, both attributes are obtained.
We use , the height of the current viewable area, greater than or equal to , the height of the element from the top of the viewable area, to determine whether the element has entered the viewable range:
<script>
// 获取所有的图片标签
const imgs = document.getElementsByTagName("img");
// 获取可视区域的高度
const viewHeight =
window.innerHeight || document.documentElement.clientHeight;
// num用于统计当前显示到了哪一张图片,避免每次都从第一张图片开始检查是否露出
let num = 0;
function lazyload() {
console.log("滚动...");
for (let i = num; i < imgs.length; i++) {
// 用可视区域高度减去元素顶部距离可视区域顶部的高度
let distance = viewHeight - imgs[i].getBoundingClientRect().top;
// 如果可视区域高度大于等于元素顶部距离可视区域顶部的高度,说明元素露出
if (distance >= 0) {
// 给元素写入真实的src,展示图片
imgs[i].src = imgs[i].getAttribute("data-src");
// 前i张图片已经加载完毕,下次从第i+1张开始检查是否露出
num = i + 1;
}
}
}
// 防抖函数
function debounce(fn, delay = 500) {
let timer = null;
return function (...args) {
if (timer) clearTimeout(timer);
timer = setTimeout(() => {
fn.call(this, args);
}, delay);
};
}
// 是的页面初始化是加载首屏图片
window.onload = lazyload;
// 监听Scroll事件,为了防止频繁调用,使用防抖函数优化一下
window.addEventListener("scroll", debounce(lazyload, 600), false);
</script>
Image Lazy Loading-Online Preview
summary
- First collect all
img
in the page (you can also useclass
). - Get the height of the view, calculate the displayed
img
, and avoid repeated assignment ofsrc
. - When sliding the mouse down, it will trigger the
onScroll
event (anti-shake), and then trigger the calculation of whether to assignsrc
.
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。