✍️性能优化之图片加载篇 您所在的位置:网站首页 deviantart图片加载不出来 ✍️性能优化之图片加载篇

✍️性能优化之图片加载篇

2023-11-16 23:58| 来源: 网络整理| 查看: 265

在这里插入图片描述

建议阅读花时间阅读,加深你对前端图片性能优化的知识点学习😜

在这里插入图片描述

1、前言

我们知道,性能优化的一个指标就是打开网页的快慢,因为网页渲染得快能够给用户更好的体验效果。但当网速不给力的时候,难免会出现资源加载的问题。特别是加载图片的时候,本文主要讨论的就是有关图片加载的一些性能优化问题。

先总览一下全文知识👇 (文后总结有具体分类哦)

2、图片加载性能优化 2.1 图片懒加载 2.1.1 为什么要使用懒加载?🧐

创建一个新的html文件,我们首先加载3张图片,来看看它的网络请求。 使用live-server打开页面,分析在web端,http协议有关的性能问题

在这里插入图片描述

可以看到,这里加载的三张图片进行了三次的网络请求 每个img 都会独立的打开一个http通道,这是十分好性能的,因为此时页面由3个并发的http并发数。

当我们的图片数量很多的时候,如果每次进入页面就请求所有的图片资源,给浏览器带来很大压力,同时可能等图片加载出来用户也早就走了。 因此我们要做的就是尽量减少并发数,进入页面的时候,只请求可视区域的图片资源

2.1.2 懒加载实现原理😏 图片的来源主要是src属性

当我们把src换成data-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、我么给便签同时加上src和data-src属性,当网页加载的时候,它会加载src属性设置的图片,此时我们设置的为同一张图片,之后会进行缓存,因此只需要一次请求,。如下图 在这里插入图片描述

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)

看看效果

在这里插入图片描述

2.1.4 完善❣️

代码写到这里,我们似乎实现了懒加载,在页面开始加载的时候没有把全部的图片都加载完,而是先判断图片是否滚动到了视窗,从而进行加载图片的操作。

但是,我们监听的是滚动的事件,只有滚动才会触发。

在这里插入图片描述

因此在上面的代码基础上,让我们再来添加一下首屏加载:

window.addEventListener('load',lazyload,false);

当页面加载完之后,就自动执行一次加载,就可以了。

在这里插入图片描述

但实际上依旧存在一个弊端。在我们滚动的时候事件触发的十分频繁,会造成性能问题,需要优化一下去。

来到我们的下一个话题:节流

2.2 节流 2.2.1 概念🧐

高频事件触发,但在n秒内只会执行一次,节流会减少函数的执行频率 在上面滚动事件多次触发时,我们需要利用节流方法,减少函数执行次数。

我们可以看一下当我们滚动鼠标时, lazyload()执行的情况:随便滚动一下就会触发这么多事件 在这里插入图片描述

2.2.2 实现一个简易版节流😲

在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函数

在这里插入图片描述 更完善的节流可以看这哦

2.3 雪碧图

雪碧图被运用在使用了很多小图标的网站上。相对于把每张小图标以.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; }

在这里插入图片描述

2.4 图片Base64编码

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 字节)

`在这里插入图片描述

创建index.js const webp = require('webp-converter'); webp.cwebp("1.jpg","output.webp","-q 80%",function(status,error) { console.log(status); })

引入webp-converter,将命名为1的jpg格式图片,优化成80%的webp图片,并且把结果命名为output.webp,很明显,大小缩小了很多。

在这里插入图片描述

总结

在优化图片加载的方法上,前面介绍了可以通过减少http请求次数,和减少图片的大小来进行优化。

减少http请求数: 1、 lazyload 延迟加载 (throttle 优化懒加载过程的节流)

2、图片Base64编码

3、 雪碧图

减少图片大小

1、 使用webp格式

然后当它们结合一起使用更加可以提高性能,比如webp格式+懒加载等。

本次有关前端图片加载的性能优化篇就先到这里,文章可能有很多不足或者不完善的地方。还请大佬评论区反映建议下,我会试着改一下。💦💦💦

在这里插入图片描述

文章有一丢丢长,码字时间也有一丢丢长。如果可以的话,厚个脸皮求个赞。🙈🙈🙈

在这里插入图片描述

好的,今天就到这❤️

在这里插入图片描述



【本文地址】

公司简介

联系我们

今日新闻

    推荐新闻

    专题文章
      CopyRight 2018-2019 实验室设备网 版权所有