文章目录
1. 懒加载
1.1 懒加载的介绍
1️⃣ 什么是懒加载?
懒加载也叫作延迟加载,指的是在长网页中延迟加载图像,是一种很好优化网页性能的方式。
当访问一个页面的时候,先把 img
元素或者其它元素的背景图片路径设置成本地默认图片(充当占位图,减少请求次数),可视区域外的图像不会加载,只有当图片出现在浏览器的可视区域内时,才设置图片的真正路径,让图片显示出来。
2️⃣ 为什么要使用懒加载?
✔ 提升用户体验:比如像在淘宝、京东这种有大量图片的网页中,如果所有图片都一起加载,会导致用户的等待时间,严重影响了用户体验。
✔ 提升页面加载速度:分批加载图片可以提升页面的加载速度。
✔ 减轻服务器的压力:分批加载图片也能够减轻服务器的压力。
1.2 懒加载的原理
首先将图片的 src
属性值设为空字符串,图片的真实路径设置在自定义属性 data-xxx
中,并且监听页面滚动 scroll
事件,判断图片是否进入可视区域,当图片进入可视区域时,就设置图片的 src
属性值为 data-xxx
的值。
1.3 懒加载的实现
实现懒加载需要知道元素对于视口的位置表示方法。如图所示:
当图片满足 top < H && bottom > 0
条件时,就可以认为在可视区域内:
.image-item {
display: block;
margin-bottom: 50px;
height: 200px;
}
<body>
<div class="lazyLoad">
<img
class="image-item"
data-src="https://img-blog.csdnimg.cn/814f007a6771418a937f6685ff0c5b37.png"
/>
<img
class="image-item"
data-src="https://img-blog.csdnimg.cn/5cfc7b6a04e845aa9fe1e9c6968df8d3.png"
/>
<img
class="image-item"
data-src="https://img-blog.csdnimg.cn/ac97b2b86b0c4829ad328ca947742e6c.png"
/>
<img
class="image-item"
data-src="https://img-blog.csdnimg.cn/4297a45efc6a4aab833a3ec50505f61e.png"
/>
<img
class="image-item"
data-src="https://img-blog.csdnimg.cn/5ab835374e9746c8ad7a5b42cb22ffdc.png"
/>
<img
class="image-item"
data-src="https://img-blog.csdnimg.cn/a7cc370c82f441c5a8ee386290e06d59.png"
/>
<img
class="image-item"
data-src="https://img-blog.csdnimg.cn/346190fed3a541d38697ecef92adbcac.png"
/>
<img
class="image-item"
data-src="https://img-blog.csdnimg.cn/76987a5ca66c4704b7744c6f120baf51.png"
/>
</div>
<script>
var viewHeight = document.documentElement.clientHeight; // 可视区域高度
var loadArr = []; // 存储已被加载过的图片的索引号(index),之后只遍历没被加载过的图片。
// 懒加载函数
function lazyLoad() {
// 把类数组转成数组
var eles = Array.from(document.querySelectorAll(".image-item"));
// 过滤掉已加载过的图片
var newEles = eles.filter((v, i) => {
return loadArr.every((x) => {
return x !== i;
});
});
for (var j = 0; j < newEles.length; j++) {
let position = newEles[j].getBoundingClientRect();
if (position.bottom >= 0 && position.top < viewHeight) {
newEles[j].src = newEles[j].getAttribute("data-src");
loadArr.push(eles.indexOf(newEles[j]));
}
}
}
lazyLoad(); // 刚开始还没滚动屏幕,要先触发一次函数,初始化首页的页面图片
window.onscroll = lazyLoad;
</script>
</body>
🚀 使用节流函数进行性能优化
如果直接将懒加载函数绑定到 scroll
事件上,当页面滚动时,函数会被高频率触发,这会非常影响性能。
节流:如果持续触发事件,每隔一段时间才执行一次事件。
// 代码差异
// 节流函数(有头有尾)
// fun:要节流的函数,time:多少秒执行一次
function debounce(fun, time) {
var timeout;
var flag = true;
return function () {
var _this = this;
var args = arguments;
if (!timeout) {
timeout = setTimeout(function () {
fun.apply(_this, args);
timeout = null;
}, time);
}
if (flag) {
// 实现有头
fun.apply(_this, args);
flag = false;
}
};
}
window.addEventListener("scroll", debounce(lazyLoad, 500));
2. 预加载
2.1 预加载的介绍
1️⃣ 什么是预加载?
预加载就是将所需的资源提前请求加载到本地,这样后面在需要用到的时候就直接从缓存读取资源。
2️⃣ 为什么要使用预加载?
对网页的图片内容进行预加载,保证了图片快速、无缝的加载,以提供更好的用户体验,减少等待时间。
2.2 预加载的实现
2.2.1 使用纯 CSS 实现
使用 CSS 的 background
属性将图片加载,设置容器的宽高,使图片不显示出来。但是这些图片会跟随文档一起加载,所以会影响页面的加载速度。
body:after {
content: "";
display: block;
width: 0;
background: url("https://img-blog.csdnimg.cn/814f007a6771418a937f6685ff0c5b37.png"),
url("https://img-blog.csdnimg.cn/5cfc7b6a04e845aa9fe1e9c6968df8d3.png"),
url("https://img-blog.csdnimg.cn/ac97b2b86b0c4829ad328ca947742e6c.png");
}
2.2.2 CSS + JS
为了解决第一个方法提到的影响页面加载速度的问题,可以通过 window.onload
事件推迟预加载时间,直到页面加载完毕才去预加载图片。
var preloadImgArr = [
"https://img-blog.csdnimg.cn/814f007a6771418a937f6685ff0c5b37.png",
"https://img-blog.csdnimg.cn/5cfc7b6a04e845aa9fe1e9c6968df8d3.png",
"https://img-blog.csdnimg.cn/ac97b2b86b0c4829ad328ca947742e6c.png",
];
// 预加载函数
function preloadImg(list) {
if (document.getElementById) {
var bodyEl = document.getElementsByTagName("body")[0];
for (let i = 0; i < list.length; i++) {
let el = document.createElement("div");
el.style.width = 0;
el.style.background = `url(${list[i]})`;
bodyEl.appendChild(el);
}
}
}
function addLoadEvent(fun, list) {
var oldOnload = window.onload; // 存储原生的 onload 事件
// 判断其它库是否改写了 onload 方法
if (typeof window.onload !== "function") {
// 其它库未改写 onload 方法
window.onload = function () {
fun(list);
};
} else {
window.onload = function () {
// 若其它库改写了 onload,则先执行其它库的 onload 方法,再执行 fun
if (oldOnload) {
oldOnload();
}
fun(list);
};
}
}
addLoadEvent(preloadImg, preloadImgArr);
2.2.3 new Image()
function preload() {
for (let i = 0; i < arguments.length; i++) {
new Image().src = arguments[i];
}
}
preload(
"https://img-blog.csdnimg.cn/814f007a6771418a937f6685ff0c5b37.png",
"https://img-blog.csdnimg.cn/76987a5ca66c4704b7744c6f120baf51.png"
);
2.2.4 使用 Ajax 实现
window.onload = function () {
setTimeout(function () {
// 预加载 js
var xhr = new XMLHttpRequest();
xhr.open('GET', 'xxx');
xhr.send(null);
// 预加载 css
xhr = new XMLHttpRequest();
xhr.open('GET', 'xxx');
xhr.send(null);
// 预加载 img
new Image().src = 'xxx';
})
}
3. 懒加载和预加载的对比
1️⃣ 两者行为是相反的,一个是提前加载,一个是延迟加载。
2️⃣ 懒加载对服务器前端有一定的缓解压力作用,预加载则会增加服务器前端的压力。