前端项目分析:我是如何做图片优化的(预加载、懒加载和延迟加载)

前端项目分析:我是如何做图片优化的(预加载、懒加载和延迟加载)众所周知 前端页面上的图片是优化时最重要也是最令人头疼的部分 图片的优化有两种方式 预加载和懒加载 本文结合实际案例 为大家讲述网站中图片的优化妙方 文章不短 但没有废话 肯定令你耳目一新啦

众所周知:前端页面上的图片是优化时最重要也是最令人头疼的部分,花费了几个月的时间才优化到令自己满意的一半程度,,,唉,一言难尽啊! 在此将几种方法总结一下,希望能帮到不少人吧…

图片的优化有两种方式: 预加载懒加载

先说说 预加载 :我以前到是写过关于预加载的博客,但是吧,,,里面很多内容不是让我很满意,因为后期发现有些内容在特定情况下才能显现出作用。
预加载的常用场景:在开发的过程,我们经常会遇到这样的要求,当鼠标hover上去的时候,更改菜单的背景。如果没有进行图片预加载的话,会出现闪烁。那么拥有1px的眼睛的设计师们不会放过你的。为什么会出现这张情况?因为hover的时候,图片才会去加载。
这个时候,就需要用预加载(在hover之前加载完(但会增加页面加载时间))了,
比如下面的:






如果需要预加载的图片太多的话可以这样:

var imgSrcArr=[ '要预加载的图片路径'(可以多个啊) ]; var imgWrap=[]; function preloadImg(arr) { for(var i=0;i 
  

也是预加载的经典了,最下面那三行意思是:或者等到文字加载完再加载图片。

网上还有人说可以采用ajax请求的方式,呵!你有那么多带宽何必做优化呢。。。

试验了很多场景,发现:预加载其实更适合如hover变换后的图片加载(解决闪屏问题),在网页刚打开的那个图片环境要求下其实作用不大。所以,我们可以将其放在需要响应鼠标事件(说白了,就是刚上去时不需要看见)的地方。

何为 “懒加载”?
在图片由于某些原因没有显示出来时,用一个占位符去显示,这是提高用户体验的不错方式,目前,京东等商城网站上就用了此技术。
懒加载的精髓:不要将真正图片放在src中引入,src中放“占位图”!




为什么使用懒加载:
在一个页面中,假设有20张图片,每张为100kb,用户在不点滚动条的时候看到的只有4张,如果这20张图片都设置了真正的src,那么当页面首次加载的时候浏览器会立即请求这20张图片资源,需要2000kb的流量;
但是我们做懒加载只请求用户看到的4张图片的话,浏览器只请求这4张图片资源,需要的流量只有400kb。这种手段可以大大减少首屏时间。




使用代码展示:(如何使用及js插件文件)

index.html

 
   
    
      /*用http方式引入jQuery文件(min指压缩过的)*/   
  

如上,在几张图片中,我们将 真正的图片 放在picAddress中,在src中放 占位图
在js中,页面加载完成后,根据scrollTop(滚动事件)重复判断图片是否在用户的视野内,如果在,则将picAddress属性中的值取出存放到src属性中。
lazyLoadImg.js(可直接使用)




/* * @example * 前端项目分析:我是如何做图片优化的(预加载、懒加载和延迟加载) * @param src里面写的是占位图或者说兜底图地址(一张默认填充图) * @param class="lazyLoadImg" 是必须的标识 * @param picAddress里面写的是真正需要懒加载的图片地址 */ const lazyLoadImg = { initConfig() { const self = this; self.imgObject.srcFlag = 'picAddress'; // 图片地址 self.imgObject.class = 'lazyLoadImg'; // 惰性加载的图片需要添加的class self.imgObject.sensitivity = 40; // 鼠标滚动敏感度,该值越小,惰性越强(加载越少) self.imgObject.init(); }, imgObject: { trigger() { const self = this; const eventType = (self.isPhone && 'touchend') || 'scroll'; self.imgListData = $('img.' + self.class + ''); $(window).trigger(eventType); }, init() { var self = this; $(window).on('scroll', function() { self.isLoadImg(); }); self.trigger(); }, isLoadImg() { const self = this; function loadNeedImg(img) { // 判断哪些img元素需要加载 const windowPageYOffset = window.pageYOffset; // 滚动条距离窗口顶部的偏移量 const offsetAddInner = window.pageYOffset + window.innerHeight; // window.innerHeight返回窗口的文档显示区的高度 const imgOffsetTop = img.offset().top; // 当前img元素距离窗口顶部的偏移量 return ( imgOffsetTop >= windowPageYOffset && // 确保img元素在窗口内 imgOffsetTop - self.sensitivity <= offsetAddInner //当前img元素是不是在窗口可见范围内,不可见返回:false ); } function loadImg(img, index) { const imgUrl = img.attr(self.srcFlag); const imgLazy = img.attr('src'); img.attr('src', imgUrl); img[0].onload || // 开始向服务器请求加载图片 ((img[0].onload = function() { $(this) .removeClass(self.class) .removeAttr(self.srcFlag), (self.imgListData[index] = null), (this.onerror = this.onload = null); }), (img[0].onerror = function() { (this.src = imgLazy), $(this) .removeClass(self.class) .removeAttr(self.srcFlag), (self.imgListData[index] = null), (this.onerror = this.onload = null); })); } self.imgListData.each(function(index, val) { if (!val) return; const img = $(val); if (!loadNeedImg(img)) return; const aa = img.attr(self.srcFlag); if (!img.attr(self.srcFlag)) return;// 判断是否有规定的picAddress属性,没有则退出当次循环 loadImg(img, index); }); }, }, }; lazyLoadImg.initConfig(); 

(这里说明一下,网上有很多jQuery的.lazyload的包,但是个人使用过感觉兼容性和效果都巨差,故而提倡自己封装一个js)

这里要提一下jQuery封装过的代码(先引入jQuery包,极其简单):

林允儿 
     

当然,我们也可以用js使图片以 渐进式 方式显示出来,就是从非常模糊(如 filter: blur(20vw) 玻璃模糊)逐步清晰。有位前辈告诉我说,这种方式本质上和 懒加载 是一个原理: 在“视图区”让一个属性(图片)替换另一个属性(图片)

 

懒加载咯 - 下面代码尤其适用于移动端页面开发(因为js-for中循环图片的判断方式,对竖直排列的图片最有利!)

图片说明
...

SVG: 在测验中发现,貌似svg格式的图片“更能使人疯狂”,这还不是重点。重要的是 ,我们可以把hover写在svg标签里,来解决hover时才加载图片的困境:

 
   
    
   

但是 ,这种方法劣势极大,一旦图片和文字是“一体”的,事情就会非常棘手,要么变成跨域问题,要么会倍增HTML文件的体积。不管怎样,这里只是提一下这种方法,并不推荐使用,关于hover的困境,还是要靠预加载实现。


2020-08-11插入
其实除了上面的预加载和懒加载,我们还可借助 es6 – promise 实现 图片延迟加载

<body> <img src="img/loading.gif" data-src="https://dss1.baidu.com/6ONXsjip0QIZ8tyhnq/it/u=,&fm=58" alt=""> <img src="img/loading.gif" data-src="https://dss2.baidu.com/6ONYsjip0QIZ8tyhnq/it/u=,&fm=58" alt=""> <img src="img/loading.gif" data-src="https://dss1.baidu.com/6ONXsjip0QIZ8tyhnq/it/u=,&fm=58" alt=""> <script> let imgDoms=document.querySelectorAll('img') let arr=[] for(let i in imgDoms){ 
     let p=new Promise((resolve,reject)=>{ 
     var img=new Image(); img.src=imgDoms[i].getAttribute('data-src'); img.onload=()=>{ 
     resolve(img) } img.onerror=(e)=>{ 
     reject(e) } }) arr.push(p) } Promise.all(arr).then((res)=>{ 
     console.log(res) for(let i in res){ 
     imgDoms[i].setAttribute('src',res[i].getAttribute('src')) } }).catch((err)=>{ 
     console.log('图片加载失败') }) </script> </body> 

  1. http://cjxnsb.cn/mxc/UCgzs/1.html
  2. http://cjxnsb.cn/mxcf/index.html
版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请联系我们举报,一经查实,本站将立刻删除。

发布者:全栈程序员-站长,转载请注明出处:https://javaforall.net/215586.html原文链接:https://javaforall.net

(0)
上一篇 2026年3月18日 下午1:55
下一篇 2026年3月18日 下午1:55


相关推荐

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注

关注全栈程序员社区公众号