ThinkChat🤖让你学习和工作更高效,注册即送10W Token,即刻开启你的AI之旅 广告
## 懒加载 懒加载也叫做延迟加载、按需加载; 优点:减少无用资源的加载、提升用户体验、防止加载过多图片而影响其他资源文件的加载 防止页面一次性向服务器发送大量请求,导致服务器响应面,页面卡顿崩溃 ### 实现 > 图片的加载是由src引起的,当对src赋值时,浏览器就会请求图片资源。 > > 根据这个原理,我们使用HTML5 的data-xxx属性来储存图片的路径,在需要加载图片的时候,将data-xxx中图片的路径赋值给src,这样就实现了图片的按需加载,即懒加载。 图片加载条件:img.offsetTop < window.innerHeight + document.body.scrollTop imgs.offsetTop 是元素顶部距离文档顶部的高度(包括滚动条的距离) window.innerHeight 是浏览器可视区的高度 document.body.scrollTop || document.documentElement.scrollTop 是浏览器滚动的过的距离 ```js <div class="container"> <img src="loading.gif" data-src="pic.png"> <img src="loading.gif" data-src="pic.png"> ... ... </div> <script> var imgs = document.querySelectorAll('img'); function lozyLoad(){ var scrollTop = document.body.scrollTop || document.documentElement.scrollTop; var winHeight= window.innerHeight; for(var i=0;i < imgs.length;i++){ if(imgs[i].offsetTop < scrollTop + winHeight ){ imgs[i].src = imgs[i].getAttribute('data-src'); } } } window.onscroll = lozyLoad(); </script> var viewHeight=document.ducumentElement.clientHeight; // 检测img元素是否在可视区 function inView (img){ var rectObject=document.getBoundingClientRect(); if(rectObject.bottom >= 0 && rectObject.top < viewHeight){ return true } else{ return false } } window.addEventListener('scroll',lazyLoad); ``` ### 懒加载与预加载的区别 懒加载也叫延迟加载,指的是在长网页中延迟加载图片的时机,当用户需要访问时,再去加载, 这样可以提高网站的首屏加载速度,提升用户的体验,并且可以减少服务器的压力 > 预加载指的是将所需的资源提前请求加载到本地,这样后面在需要用到时就直接从缓存取资源。 > > 通过预加载能够减少用户的等待时间,提高用户的体验。 缺点:增加服务器压力,首页加载渲染时间长。 > > 在浏览器加载页面window.onload时创建image对象并赋值src链接 。 ```js var imgs=['./1.jpg','./2.jpg','./3.jpg']; var imgsDom=[]; function preLoad(arr){ for(let i=0;i<arr.length;i++){ let item=new Image(); item.src=imgs[i]; imgsDom.push(item); } } window.onload=function(){ preLoad(imgs); } ``` ------ ---- ----- ----- ----- >图片懒加载原理实现 getBoundingClientRect DOM 元素包含一个getBoundingClientRect 方法, 执行该方法返回当前DOM节点相关的Css边框集合, 其中有一个Top 属性代表当前DOM 节点距离浏览器窗口顶部的高度, 只需判断top值是否小于当前浏览器窗口的高度(window.innerHeight), 若小于说明已经进入用户视野,然后替换为真正的图片即可 ``` 另外使用getBoundingClientRect 作图片懒加载需要注意三点 1。 因为需要监听scroll 事件,不停的判断top 的值和浏览器高度的关系,请对监听事件进行函数节流 2. 当屏幕首次渲染时,不会触发scroll 事件,请主动调用一次事件处理程序,否则若用户不滚动则首屏的图片会一直使用懒加载的默认图片 3. 当所有需要懒加载 的图片都被加载完,需要移除事件监听,避免不必要的内存占用 ``` ### 原理: 先将img标签的src链接设为同一张图片(比如空白图片),然后给img标签设置自定义属性(比如 data-src), 然后将真正的图片地址存储在data-src中,当JS监听到该图片元素进入可视窗口时,将自定义属性中的地址存储到src属性中。达到懒加载的效果。 #### 这样做能防止页面一次性向服务器发送大量请求,导致服务器响应面,页面卡顿崩溃等。 ``` 在vue项目中,可以使用vue的vue-lazyload插件。 * 安装插件:npm install vue-lazyload --save-dev * 引入插件:import VueLazyloadfrom'vue-lazyload' * 使用插件:Vue.use(VueLazyload) * 修改图片显示方式: ``` ~~~xml <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <meta http-equiv="X-UA-Compatible" content="ie=edge"> <title>Document</title> <script src="https://cdn.bootcss.com/jquery/2.1.0/jquery.min.js"></script> <style> .container{ max-width: 800px; margin:0 auto; } .container:after{ content:""; display: block; clear:both; } .container img{ width:50%; height:260px; float:left; } </style> </head> <body> <div class="container"> <img src="http://s4.sinaimg.cn/mw690/006uWPTUgy72CNFYNjB93&690" alt="1" data-src="http://img4.imgtn.bdimg.com/it/u=951914923,777131061&fm=26&gp=0.jpg"> <img src="http://s4.sinaimg.cn/mw690/006uWPTUgy72CNFYNjB93&690" alt="1" data-src="http://img1.imgtn.bdimg.com/it/u=637435809,3242058940&fm=26&gp=0.jpg"> <img src="http://s4.sinaimg.cn/mw690/006uWPTUgy72CNFYNjB93&690" alt="1" data-src="http://img1.imgtn.bdimg.com/it/u=3990342075,2367006974&fm=200&gp=0.jpg"> <img src="http://s4.sinaimg.cn/mw690/006uWPTUgy72CNFYNjB93&690" alt="1" data-src="http://img1.imgtn.bdimg.com/it/u=1813891576,1754763093&fm=26&gp=0.jpg"> <img src="http://s4.sinaimg.cn/mw690/006uWPTUgy72CNFYNjB93&690" alt="1" data-src="http://img4.imgtn.bdimg.com/it/u=2539922263,2810970709&fm=200&gp=0.jpg"> </div> <script> // 一开始没有滚动的时候,出现在视窗中的图片也会加载 start(); // 当页面开始滚动的时候,遍历图片,如果图片出现在视窗中,就加载图片 var clock; //函数节流 $(window).on('scroll',function(){ if(clock){ clearTimeout(clock); } clock = setTimeout(function(){ start() },200) }) function start(){ $('.container img').not('[data-isLoading]').each(function () { if (isShow($(this))) { loadImg($(this)); } }) } // 判断图片是否出现在视窗的函数 function isShow($node){ return $node.offset().top <= $(window).height()+$(window).scrollTop(); } // 加载图片的函数,就是把自定义属性data-src 存储的真正的图片地址,赋值给src function loadImg($img){ $img.attr('src', $img.attr('data-src')); // 已经加载的图片,我给它设置一个属性,值为1,作为标识 // 弄这个的初衷是因为,每次滚动的时候,所有的图片都会遍历一遍,这样有点浪费,所以做个标识,滚动的时候只遍历哪些还没有加载的图片 $img.attr('data-isLoading',1); } </script> </body> </html> ~~~