前言
对于图片量比较大的点上首页APP等,在打开商品展示页面的时候需要再加大量图片,在这种场景下如果直接全量加载,必然会造成页面性能消耗过大,白屏或者卡顿,用户体验非常糟糕,用户真的需要我们显示所有图片一起展示吗?其实并不是,用户看到的只是浏览器可视区域的内容。所以从这个情况我们可以做一些优化,只显示用户可视区域内的图片,当用户触发滚动的瞬间再去请求显示给用户
图片懒加载的实现:
- 给所有需要展示的 img 标签添加自定义属性: data-src ,同时不要设置 src 属性,data-src的值为图片url。
- 当页面加载完后,我们需要获取所有需要懒加载的图片的元素集合,判断是否在可视区域,如果是在可视区域的话,再重新设置元素的src属性值为真正图片的地址。
- 可视化区域的判断:是通过获取元素的getBoundingClientRect属性的top值和页面的clientHeight进行对比,如果top值小于clientHeight,则说明元素出现在可视区域之内。
- 当用户滚动窗口的时候,此时应该通过每个元素的BoundingClientRect属性来判断元素是否出现在可视区域内,如果在可视区域内,就渲染图片展示在可是区域内。
懒加载的实现:
<!-- 只在可视化区域内加载图片 --> <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>Document</title> </head> <body> <img style="width: 250px;height: 250px;background-color: grey; display: block;" data-src="./img/test01.PNG" alt=""> <img style="width: 250px;height: 250px;background-color: grey; display: block;" data-src="./img/test01.PNG" alt=""> <img style="width: 250px;height: 250px;background-color: grey; display: block;" data-src="./img/test01.PNG" alt=""> <img style="width: 250px;height: 250px;background-color: grey; display: block;" data-src="./img/test01.PNG" alt=""> <img style="width: 250px;height: 250px;background-color: grey; display: block;" data-src="./img/test01.PNG" alt=""> <img style="width: 250px;height: 250px;background-color: grey; display: block;" data-src="./img/test01.PNG" alt=""> <img style="width: 250px;height: 250px;background-color: grey; display: block;" data-src="./img/test01.PNG" alt=""> <img style="width: 250px;height: 250px;background-color: grey; display: block;" data-src="./img/test01.PNG" alt=""> <img style="width: 250px;height: 250px;background-color: grey; display: block;" data-src="./img/test01.PNG" alt=""> <img style="width: 250px;height: 250px;background-color: grey; display: block;" data-src="./img/test01.PNG" alt=""> <img style="width: 250px;height: 250px;background-color: grey; display: block;" data-src="./img/test01.PNG" alt=""> <img style="width: 250px;height: 250px;background-color: grey; display: block;" data-src="./img/test01.PNG" alt=""> </body> <script> var viewHeight = document.documentElement.clientHeight; // 可视化区域的高度 var viewWidth = document.documentElement.clientWidth; // 可视化区域的宽度 function lazyload() {
//获取所有要进行懒加载的图片 let eles = document.querySelectorAll('img[data-src]'); // 获取属性名中有data-src的 console.log('获取所有的信息', eles) Array.prototype.forEach.call(eles, function (item, index) {
let rect; if (item.dataset.src === '') {
return; } rect = item.getBoundingClientRect(); // 返回元素的大小及其相对于视口的位置 console.log('返回元素的大小及其相对于视口的位置', rect) //图片一进入可视区,动态加载 if (rect.bottom >= 0 && rect.top < viewHeight) {
! function () {
let img = new Image(); img.src = item.dataset.src; img.onload = function () {
item.src = img.src; } item.removeAttribute('data-src'); }(); } }) } lazyload(); </script> </html>
上述代码中,我们已经初步完成图片懒加载,但是我们大家都知道,scroll这个事件,用户滚动鼠标就会触发很多次,这也会导致我们的性能急剧下降,所以这就引出了我们的混合体 防抖函数优化我们的性能:
function debounce(fn, gapTime) {
let timer = null; return function () {
if (timer) {
clearTimeout(timer); timer = null; } timer = setTimeout(function () {
fn(); }, gapTime) } }
最后贴出完整代码:
<!-- 只在可视化区域内加载图片 --> <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>Document</title> </head> <body> <img id="img" style="width: 250px;height: 250px;background-color: grey; display: block;" data-src="./img/test01.PNG" alt=""> <img style="width: 250px;height: 250px;background-color: grey; display: block;" data-src="./img/test01.PNG" alt=""> <img style="width: 250px;height: 250px;background-color: grey; display: block;" data-src="./img/test01.PNG" alt=""> <img style="width: 250px;height: 250px;background-color: grey; display: block;" data-src="./img/test01.PNG" alt=""> <img style="width: 250px;height: 250px;background-color: grey; display: block;" data-src="./img/test01.PNG" alt=""> <img style="width: 250px;height: 250px;background-color: grey; display: block;" data-src="./img/test01.PNG" alt=""> <img style="width: 250px;height: 250px;background-color: grey; display: block;" data-src="./img/test01.PNG" alt=""> <img style="width: 250px;height: 250px;background-color: grey; display: block;" data-src="./img/test01.PNG" alt=""> <img style="width: 250px;height: 250px;background-color: grey; display: block;" data-src="./img/test01.PNG" alt=""> <img style="width: 250px;height: 250px;background-color: grey; display: block;" data-src="./img/test01.PNG" alt=""> <img style="width: 250px;height: 250px;background-color: grey; display: block;" data-src="./img/test01.PNG" alt=""> <img style="width: 250px;height: 250px;background-color: grey; display: block;" data-src="./img/test01.PNG" alt=""> </body> <script> var viewHeight = document.documentElement.clientHeight; // 可视化区域的高度 var viewWidth = document.documentElement.clientWidth; // 可视化区域的宽度 console.log('可视化区域的高度', viewHeight) console.log('可视化区域的宽度', viewWidth) let imgDom = document.getElementById('img'); console.log(window.getComputedStyle(imgDom, null).color); // 用来取所有的 function lazyload () {
//获取所有要进行懒加载的图片 let eles = document.querySelectorAll('img[data-src]'); // 获取属性名中有data-src的 console.log('获取所有的信息', eles) Array.prototype.forEach.call(eles, function(item, index) {
let rect; if(item.dataset.src === '') {
return; } rect = item.getBoundingClientRect(); // 返回元素的大小及其相对于视口的位置 console.log('返回元素的大小及其相对于视口的位置', rect) //图片一进入可视区,动态加载 if(rect.bottom >= 0 && rect.top < viewHeight) {
!function () {
let img = new Image(); img.src = item.dataset.src; img.onload = function () {
item.src = img.src; } item.removeAttribute('data-src'); }(); } }) } lazyload(); // 添加滚动事件触发图片加载 document.addEventListener('scroll', debounce(lazyload, 500), false); // 通过函数防抖来持续优化: function debounce(fn, gapTime) {
let timer = null; return function() {
if(timer) {
clearTimeout(timer); timer = null; } timer = setTimeout(function() {
fn(); }, gapTime) } } </script> </html>
掘金链接:
- https://juejin.cn/post/
发布者:全栈程序员-站长,转载请注明出处:https://javaforall.net/221135.html原文链接:https://javaforall.net
