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

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

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

<script type="text/javascript"><!--//--><![CDATA[//><!--if (document.images) {img1 = new Image();img2 = new Image();img1.src = "img/QQ图片20190521233736.jpg";img2.src = "img/Cache_3fa28786e3750c51..jpg";}//--><!]]></script>

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

var imgSrcArr=['要预加载的图片路径'(可以多个啊)
];
var imgWrap=[];
function preloadImg(arr) {for(var i=0;i<arr.length;i++){imgWrap[i]=new Image();imgWrap[i].src=arr[i];}
}
preloadImg(imgSrcArr);$(function () {preloadImg(imgSrcArr);
})

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

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

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

但是我的主要要求是首屏加载图片优化,提高用户体验,怎么办呢?
预加载好像帮不了我,,,
思量再三,我决定 “投靠” 懒加载 大军!

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

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

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

index.html

<html><head><meta charset="utf-8"></head><body><style>body{text-align: center;}.game-detail-logo{width: 750px;height: 430px;text-align: center;margin-top:30px;}</style><img src="https://ss1.bdstatic.com/70cFuXSh_Q1YnxGkpoWK1HF6hhy/it/u=4259389730,3152819071&fm=26&gp=0.jpg" class="game-detail-logo lazyLoadImg" picAddress="https://ss3.bdstatic.com/70cFv8Sh_Q1YnxGkpoWK1HF6hhy/it/u=4003935283,4035293154&fm=27&gp=0.jpg"><img src="https://ss1.bdstatic.com/70cFuXSh_Q1YnxGkpoWK1HF6hhy/it/u=4259389730,3152819071&fm=26&gp=0.jpg" class="game-detail-logo lazyLoadImg" picAddress="https://ss3.bdstatic.com/70cFv8Sh_Q1YnxGkpoWK1HF6hhy/it/u=2390937513,1169699994&fm=27&gp=0.jpg"></body><script src="http://libs.baidu.com/jquery/2.0.0/jquery.min.js"></script>   /*用http方式引入jQuery文件(min指压缩过的)*/<script type="text/javascript" src="lazyLoadImg.js"></script>
</html>

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

/*
* @example
* <img src="" class="lazyLoadImg" picAddress="">
* @param src里面写的是占位图或者说兜底图地址(一张默认填充图)
* @param class="lazyLoadImg" 是必须的标识
* @param picAddress里面写的是真正需要懒加载的图片地址
*/
const lazyLoadImg = {initConfig() {const self = this;self.imgObject.srcFlag = 'picAddress'; // 图片地址self.imgObject.class = 'lazyLoadImg'; // 惰性加载的图片需要添加的classself.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包,极其简单):

<img src="imag/2.png" width="1920" height="340" alt="林允儿">
<!--有时为什么会有水平之间的空隙?回车符-->
<script>$('img').lazyload({//以“背景”的形式突出占位图placeholder:'imag/loading.gif',//视图滚动到这里时再加载原图effect:'fadeIn',//开始加载位置threshold:-170});
</script>

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

<body>
<h3>懒加载咯 - 下面代码尤其适用于移动端页面开发(因为js-for中循环图片的判断方式,对竖直排列的图片最有利!)</h3>
<div class="imgs"><div><img src="占位图" data-src="真正图片" alt="图片说明"></div>...
</div>
<script>window.onload=function () {var imgs=document.querySelectorAll('img');function offset(el){let top=el.offsetTopwhile(el.offsetParent){el=el.offsetParenttop+=el.offsetTop   //scrollTop:设置或获取位于对象最顶端和窗口中可见内容的最顶端之间的距离}return{top}}function lazyload(imgs) {var h=window.innerHeight;   //innerheight   返回窗口的文档显示区的高度var s=document.documentElement.scrollTop || document.body.scrollTop;   //document.body.scrollTop 网页被卷去的高for(var i=0;i<imgs.length;i++){if((h+s)>offset(imgs[i]).top){   //窗口文档显示去高度+向上滚动的高度,判断是否到达了图片的位置,如果到了,才去加载,并在加载中 用一个动图去“占位”(function (i) {setTimeout(function () {var tmp=new Image();tmp.src=imgs[i].getAttribute("data-src");   //   直接获取tmp.onload=function () {imgs[i].src=imgs[i].getAttribute("data-src");   //   如果直接获取不了(还没加载完),就等加载完前面的再去获取}},1300)})(i)}}}lazyload(imgs);window.onscroll=function () {lazyload(imgs);}}
</script>
</body>

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

<svg><style type="text/css">.st0{fill:#282828;}.st0:hover{fill:#3399cc;}</style>
</svg>

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


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

<body><img src="img/loading.gif" data-src="https://dss1.baidu.com/6ONXsjip0QIZ8tyhnq/it/u=2860774393,2141973361&fm=58" alt=""><img src="img/loading.gif" data-src="https://dss2.baidu.com/6ONYsjip0QIZ8tyhnq/it/u=1069388867,2729276042&fm=58" alt=""><img src="img/loading.gif" data-src="https://dss1.baidu.com/6ONXsjip0QIZ8tyhnq/it/u=1188214717,3310596202&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>

现在让我们来想这样一个场景:我们将这段代码放在 页面加载complete 中,这样页面在初始环境加载时会只去请求占位极小的“GIF图”,在真正去加载图片时又因为promise而不得不异步地一个一个请求。

这对页面的性能体验也是极有帮助的。


分析适用场景,选择合适的方式才能将一个网站打造的更完美。
项目地址:

  1. http://cjxnsb.cn/mxc/UCgzs/1.html
  2. http://cjxnsb.cn/mxcf/index.html

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

  1. vue2首屏性能优化(splitChunks/externals/gzip/路由懒加载)

    首屏加载慢原因: Vue只有第一次会加载页面, 以后的每次页面切换,只需要进行组件替换.因为Vue 是SPA,所以首页第一次加载时会把所有的组件以及组件相关的资源全都加载了,造成网站首页打开速度变慢的 ...

  2. 前端开发:浅谈图片优化的方法

    在网站优化中,如果图片优化得好,不但可以提高页面的加载速度,提升网站的用户体验,而且还可以通过图片优化来节省网站的带宽.那么作为页面构建工程师应该采用什么方法来优化图片,既能保证UI的还原度,又使图片 ...

  3. web前端高级React - React从入门到进阶之组件的懒加载及上下文Context

    第二部分:React进阶 系列文章目录 第一章:React从入门到进阶之初识React 第一章:React从入门到进阶之JSX简介 第三章:React从入门到进阶之元素渲染 第四章:React从入门到 ...

  4. vue-photo-preview踩坑,el-table中一张错误图片导致全部图片无法放大,并且与懒加载v-lazy不兼容

    需求:el-table中展示的图片,可以点击放大,并且使用懒加载(偶尔会有404的图片路径) 坑一: 一张404图片会导致全部图片无法放大,用@error解决 坑二: 但是马上发现如果用了vue-la ...

  5. 前端实现微信公众号图片上传预览jssdk

    最近做了公众号的项目,需要用jssdk,研究了一段时间也走了一些弯路,现在做一些记录 1.首先引入 <script src = "http://res.wx.qq.com/open/j ...

  6. Android优化方案之--Fragment的懒加载实现

    一.背景 在Android应用中,ViewPager是我们不可避免使用的一个控件,因为它可以使我们在占用较少空间的同时,增强内容的丰富性,同时以其内部流淌着Google的血液,所以它几乎成了每一个Ap ...

  7. 前端优化-网页图片优化

    前端在工作中,一定会经常涉及到图片,甚至很多人认为前端就是切图的,还有人说前端是用div+css布局的,如果从事了这项工作,你一定不这么认为,相信大家都知道前端绝对不是用PS切片工具把网页切成小图片这 ...

  8. 前端性能优化之图片优化

    图片优化的价值 为什么要做图片优化?图片优化的收益有多大? Google官方的最佳实践中关于图片优化有下面这样一段描述: 对于网页来说,在所下载的字节数中,图片往往会占很大比例.因此,优化图片通常可以 ...

  9. 前端性能优化——图片优化

    一.图片优化措施 优化图片是 Web 前端优化的重要一环,因为图片是 Web 页面中最耗费带宽和加载时间的资源之一.以下是一些通过优化图片来优化 Web 前端的方法: 压缩图片:压缩图片可以减少图片的 ...

最新文章

  1. linux特殊系统变量,linux环境几个特殊的shell变量
  2. 【吐血整理】java正则表达式详解
  3. CentOS系统安装配置JDK
  4. ubuntu/linux运行shell脚本sudo自动输入密码(亲测可以)
  5. ASP.NET Core 3.0 gRPC 双向流
  6. WSL+VSCODE体验UBUNTU环境下的开发
  7. nuxt添加.html,Nuxt内导航栏的两种实现方式
  8. ddos常见攻击报文
  9. 端口截听实现端口隐藏 嗅探与攻击
  10. Java 数据结构之双链表
  11. Flash CS4从入门到精通
  12. 独家首发强大的个性生成工具箱微信小程序源码,超多功能的合成
  13. 2022全年PMP考证时间表(预估)收藏版
  14. 将路由器当成交换机使用
  15. 【统计学】用Stata做时间序列分析
  16. 输入法框无法正常显示问题
  17. 服务器测试之RAID/HBA/SAS卡引入测试常见测试指令(案例)
  18. 干货分享!华为模拟器Web配置防火墙
  19. 2018区块链概念股龙头
  20. 2022焊工(初级)试题及在线模拟考试

热门文章

  1. Hash函数经典用法
  2. 国人劝酒经典用语大全
  3. 虹软人证核验增值版-node.js调用C++SDK
  4. 【元胞自动机】元胞自动机模拟交通事故道路通行量【含Matlab源码 356期】
  5. Excel数据筛选匹配
  6. java每日定时任务下载
  7. Photoshop分享| 拼贴海报
  8. 知识付费网站源码可开分站一键更新后台数据
  9. 对大数据量Excel文件自动排版、转换成PDF用于印刷出版
  10. 我如何建立热线电话喀拉拉邦并为抗洪救灾做出了贡献