概念
图片懒加载(Lazy Loading)是一种优化网页或应用性能的技术,其核心思想是延迟加载非关键资源,即只有当用户实际需要查看这些资源时,才去加载它们。在网页设计中,这通常指的是图片和视频等大型媒体文件。
图片懒加载不仅提升了用户体验,还有助于提高SEO排名,因为快速加载的页面通常会被搜索引擎更加青睐。同时,懒加载也是响应式设计中的一个重要组成部分,有助于创建更加高效和适应不同设备的网站。
在传统的网页加载过程中,所有的资源(包括图片)都会在页面加载时一并加载,这可能会导致网页加载速度变慢,尤其是对于那些大型图片或者在页面滚动时才出现在视口中的图片。
改善用户体验和提高网页性能
图片懒加载通过以下方式改善用户体验和提高网页性能:
- 提升首屏加载速度:用户在访问页面时,首先加载页面上方的内容,下方的内容只有在用户滚动到相应位置时才会加载,这样可以加快用户看到页面主要内容的速度。
- 减少不必要的数据传输:对于那些用户可能不会查看的内容,比如页面底部的图片,如果不采用懒加载,这些图片也会被加载,造成带宽的浪费。而懒加载可以避免这种情况,只有用户实际需要查看时,这些图片才会加载。
- 提高交互性能:通过减少同时加载的资源数量,可以减轻浏览器的负担,提高页面的交互性能,使用户在使用网页应用时感觉更加流畅。
实现图片懒加载的技术手段
实现图片懒加载的技术手段有多种,包括但不限于:
- 使用
Intersection Observer
API:这是一个原生的浏览器API,可以监听元素与其祖先元素或顶级文档视窗(viewport)的交叉状态,从而实现懒加载。 - 使用
loading="lazy"
属性:在HTML中,可以在img
和iframe
标签上使用loading="lazy"
属性,让浏览器自动实现懒加载。 - 使用第三方库:比如
lozad.js
、lazysizes
等,这些库提供了更多的功能和更好的兼容性。
淘宝怎样实现图片懒加载?
不在可视区域: 使用默认的灰色加载图片
出现在可视区域: 1.jpg -> 放在src中 -> 删除data-src
思路
- 遍历特定的图片
- 看图片是不是在可视区域: 看图片的offsetTop 是不是等于 可视高度 + 滚动条高度
讲解
html
实现以下效果的所需操作
/*
renderList 渲染列表:
第一次要显示默认的灰色图片
用数据去替换模版中的变量 list就是拼接好的模版: src是默认的灰色图片 data-src才是要渲染的图片
return list
*/
; (function (win, doc) {
// 拿到放图片的容器 拿到数据 拿到要组装和替换的模版
var oImgList = doc.getElementsByClassName('J_imgList')[0],
data = JSON.parse(doc.getElementById('J_data').innerHTML),
imgTpl = doc.getElementById('J-imgTpl').innerHTML;
var init = function () {
bindEvent();
oImgList.innerHTMl = renderList(data);
}
function bindEvent() {
}
function renderList(data) {
// 防止拼接好的字符串的容器
var list = '';
// 遍历数据
data.forEach(function (elem) {
list += imgTpl.replace(/{{(.*?)}}/g, function (node, key) {
return {
img: elem.img,
name: elem.name
}
})[key]
})
return list;
}
init();
})(window, document);
- 获取数据 , 赋值给变量
- 要用js,把li放进ul里面去 -> 拿到容器
- 把数据拿出来,解析成json对象 -> 遍历的数据data
- 拿到脚本中的模版,要用模版替换的方式把变量替换掉 -> 用数据替换掉imgTpl中的变量
- 肯定要监听鼠标的滚轮滚动 -> bindEvent
- 定义函数 renderList
- 拼接好的list
🌟封装图片懒加载的完整代码
; (function (win, doc) {
// 拿到放图片的容器 拿到数据 拿到要组装和替换的模版 模版中的img标签的类名
var oImgList = doc.getElementsByClassName('J_imgList')[0],
data = JSON.parse(doc.getElementById('J_data').innerHTML),
imgTpl = doc.getElementById('J-imgTpl').innerHTML,
oImg = doc.getElementsByClassName('list-img');
var init = function () {
oImgList.innerHTMl = renderList(data);
// li被添加到ul后,才可以绑定事件
bindEvent();
// 滚动条默认在最顶端
setTimeout(function () {
window.scrollTo(0, 0);
}, 150);
}
function bindEvent() {
//在视口中的图片要加载出来
//鼠标滚动的时候也要加载对应的图片
window.onload = window.onscroll = throttle(imgLazyLoad(oImg), 500);
}
function renderList(data) {
// 防止拼接好的字符串的容器
var list = '';
// 遍历数据
data.forEach(function (elem) {
list += imgTpl.replace(/{{(.*?)}}/g, function (node, key) {
return {
img: elem.img,
name: elem.name
}
})[key]
})
return list;
}
init();
})(window, document);
function imgLazyLoad(image) {
// 肯定要循环这些image
var imgLen = image.length,
n = 0;
return function () {
// 得到可视区域的高度
// 图片的offsetTop < scrollTop + 可视区域的高度clientHeight -> 出现在可视区域
var cHeight = document.documentElement.clientHeight,
sTop = document.documentElement.scrollTop || document.body.scrollTop,
imgItem;
for (var i = n; i < imgLen; i++) {
imgItem = image[i];
if (imgItem.offsetTop < cHeight + sTop) {
// 在可视区域内
// 把属性拿出来 -> 赋值给src
imgItem.src = imgItem.getAttribute('data-src');
// 赋值完毕,没用了 -> 删掉 data-stc
imgItem.removeAttribute('data-src');
// 图片显示好了 n++
n++;
}
}
}
}