✍️性能优化之图片加载篇 | 您所在的位置:网站首页 › deviantart图片加载不出来 › ✍️性能优化之图片加载篇 |
建议阅读花时间阅读,加深你对前端图片性能优化的知识点学习😜 我们知道,性能优化的一个指标就是打开网页的快慢,因为网页渲染得快能够给用户更好的体验效果。但当网速不给力的时候,难免会出现资源加载的问题。特别是加载图片的时候,本文主要讨论的就是有关图片加载的一些性能优化问题。 先总览一下全文知识👇 (文后总结有具体分类哦) 创建一个新的html文件,我们首先加载3张图片,来看看它的网络请求。 使用live-server打开页面,分析在web端,http协议有关的性能问题 可以看到,这里加载的三张图片进行了三次的网络请求 每个img 都会独立的打开一个http通道,这是十分好性能的,因为此时页面由3个并发的http并发数。 当我们的图片数量很多的时候,如果每次进入页面就请求所有的图片资源,给浏览器带来很大压力,同时可能等图片加载出来用户也早就走了。 因此我们要做的就是尽量减少并发数,进入页面的时候,只请求可视区域的图片资源 2.1.2 懒加载实现原理😏 图片的来源主要是src属性当我们把src换成data-src,由于浏览器是否发送请求就是根据是否有src属性决定的。所以此时页面并不会出现像刚才一样的图片请求。 因此我们可以利用这一点,在没进入可视区域的时候,我们先给 可视区域就是:就是你可以看到的区域。 浏览器窗口显示网页的部分(即不包括地址栏、工具栏)就是可视区 在不同浏览器获取可视区宽高都实用的JavaScript方案: var w = document.documentElement.clientWidth || document.body.clientWidth; var h = document.documentElement.clientHeight || document.body.clientHeight; 相关api addEventListener:EventTarget.addEventListener() 方法将指定的监听器注册到 EventTarget 上,当该对象触发指定的事件时,指定的回调函数就会被执行。 DOMContentLoaded:当初始的 HTML 文档被完全加载和解析完成之后,DOMContentLoaded 事件被触发,而无需等待样式表、图像和子框架的完全加载。 getBoundingClientRect:Element.getBoundingClientRect() 方法返回元素的大小及其相对于视口的位置。 getAttribute:getAttribute() 方法返回指定属性名的属性值。 ——MDN 2.1.3 具体操作🖐️1、我么给 2、当页面进入可视区后我们就要进行真正需要展示的图片的加载。 1、监听页面加载,获取视窗大小 当HTML 文档被完全加载和解析完成之后,DOMContentLoaded 事件被触发,此时将所有的图片通过document.getElementsByTagName('img')获取到,在获取浏览器视窗的高度。 document.addEventListener('DOMContentLoaded', () => { imgs = document.getElementsByTagName('img'); // 取得所有图片 const viewHeight = window.innerHeight || docuemnt.documentElement.clientHeight; // JS 浏览器嗅探,兼容浏览器 } 监听滚动事件 同时触发lazyload回调函数,再函数里面判断图片是否出现在在视窗当中,或者已经出现过。 window.addEventListener('scroll',lazyload,false); 懒加载函数: function lazyload() { for (let i = 0;i < imgs.length;i++) { let distance = viewHeight - imgs[i].getBoundingClientRect().top; //当图片出现在视窗当中,或者之前已经出现了。 //将data-src属性的值赋给src属性,从而在页面上显示真正的图片 if (distance > 0) { imgs[i].src = imgs[i].getAttribute('data-src'); } } }代码: html: css: * { margin: 0; padding: 0; } .container { width: 1200px; margin: 0 auto; } .img { width: 500px; height: 500px; }js: let imgs; document.addEventListener('DOMContentLoaded', () => { imgs = document.getElementsByTagName('img'); // 把所有的图片抓住 const viewHeight = window.innerHeight || docuemnt.documentElement.clientHeight; // JS 浏览器嗅探 console.log(viewHeight) function lazyload() { for (let i = 0;i < imgs.length;i++) { let distance = viewHeight - imgs[i].getBoundingClientRect().top; if (distance > 0) { imgs[i].src = imgs[i].getAttribute('data-src'); } } } window.addEventListener('scroll',lazyload,false); },false)看看效果 代码写到这里,我们似乎实现了懒加载,在页面开始加载的时候没有把全部的图片都加载完,而是先判断图片是否滚动到了视窗,从而进行加载图片的操作。 但是,我们监听的是滚动的事件,只有滚动才会触发。 因此在上面的代码基础上,让我们再来添加一下首屏加载: window.addEventListener('load',lazyload,false);当页面加载完之后,就自动执行一次加载,就可以了。 但实际上依旧存在一个弊端。在我们滚动的时候事件触发的十分频繁,会造成性能问题,需要优化一下去。 来到我们的下一个话题:节流 2.2 节流 2.2.1 概念🧐高频事件触发,但在n秒内只会执行一次,节流会减少函数的执行频率 在上面滚动事件多次触发时,我们需要利用节流方法,减少函数执行次数。 我们可以看一下当我们滚动鼠标时,
lazyload()执行的情况:随便滚动一下就会触发这么多事件
在n秒内只会执行一次 当我们监听滚动事件的时候,调用的是throttle函数,接收两个参数分别是 最开始的lazyload函数,变成了一个回调函数,和一个100ms时间 window.addEventListener('scroll',throttle(lazyload,1000),false); 在throttle函数里面,设置,在interval时间内执行一次fn,节约了执行次数 const throttle = (fn,interval) => { let last = 0;//上一次触发回调的时间 return function () { let now = +new Date(); if(now - last >= interval){ last = now fn(); } } }就算滑到底部,也只是触发了9次lazyload函数
雪碧图被运用在使用了很多小图标的网站上。相对于把每张小图标以.png格式文件的形式引用到页面上,使用雪碧图只需要引用一张图片。 下面这张图是截取京东官网使用的一张雪碧图: 这样的话我们就可以将很多张图片请求合并到一张图片上,有效减少http请求。再加上css中图片属性background-position将需要的图片展示出来。 这里介绍一下这个background-position属性: background-position:设置背景图像的起始位置 取得右下角的图标: { background-image:url('https://iknow- pic.cdn.bcebos.com/faedab64034f78f0cbe417637b310a55b2191cb6?x-bce- process=image/resize,m_lfit,w_600,h_800,limit_1'); background-repeat:no-repeat; background-attachment:fixed; background-position: -340px -255px; }Base64 是一种编码格式 比起懒加载的延迟加载,这种方法直接都不需要请求。 不过它是有局限性:针对尺寸很小的图标,并且又不能与其他图片合成雪碧图的,以Base64编码的形式使用,是一个不错的选择,毕竟它可以减少http请求开销。 2.5 webp图片格式可以看到图片的大小明显减少了很多。 这种格式的图片:适用大图,特别是头图,banner图,商品详情页的图片可以使用webp格式,在大小上可以减少25%,同时在清晰度上不怎么受损,这样的话就可以结合我们前面的lazyload懒加载,在http请求数量和图片大小上都实现了一定的优化。 2.5.1 webp-converter😁使用工具进行图片性能优化 首先 使用npm i webp-converter安装 在网上找了一张.jpg的图片,图片大小`16.7 KB (17,194 字节)` 引入webp-converter,将命名为1的jpg格式图片,优化成80%的webp图片,并且把结果命名为output.webp,很明显,大小缩小了很多。 在优化图片加载的方法上,前面介绍了可以通过减少http请求次数,和减少图片的大小来进行优化。 减少http请求数: 1、 lazyload 延迟加载 (throttle 优化懒加载过程的节流) 2、图片Base64编码 3、 雪碧图 减少图片大小 1、 使用webp格式 然后当它们结合一起使用更加可以提高性能,比如webp格式+懒加载等。 本次有关前端图片加载的性能优化篇就先到这里,文章可能有很多不足或者不完善的地方。还请大佬评论区反映建议下,我会试着改一下。💦💦💦 文章有一丢丢长,码字时间也有一丢丢长。如果可以的话,厚个脸皮求个赞。🙈🙈🙈 好的,今天就到这❤️ |
CopyRight 2018-2019 实验室设备网 版权所有 |