当前位置: 首页 > 科技观察

前端性能优化——图片

时间:2023-03-13 15:36:11 科技观察

在电商项目中,往往会有大量的图片,比如banner广告图片、菜单导航图片、美团等商家列表页眉图片。图片过多、图片过大往往会影响页面的加载速度,导致用户体验不好,因此对图片进行优化势在必行。我们先来看一个页面启动时加载的图片信息。http.png如图所示,这个页面在启动时加载了几十张(甚至更多)图片,而且这些图片请求几乎是并发的。在Chrome浏览器中,支持的最大并发请求数是有限制的。其他请求会被推入队列等待或原地不动,直到上一轮请求完成后才会发出新的请求。因此,相当数量的图片资源请求需要排队等待,图片过多势必会影响页面的加载和显示。选择正确的图片格式JPEGJPEG是由联合图像专家组开发的图片。它最大的特点是有损压缩。这种高效的压缩算法使其成为一种非常轻量级的图像格式。另一方面,虽然被称为“有损”压缩,但JPG的压缩方式仍然是一种高质量的压缩方式:当我们将图片体积压缩到原始体积的50%以下时,JPG仍然可以保持60%。%质量。另外,JPG格式以24位存储单张图片,最多可以呈现1600万种颜色,足以满足大部分场景下的色彩需求,这决定了压缩前后的质量损失不易被察觉。我们人类的眼睛所看到的是有意识的。优点一张JPEG格式的图片可以表示数百万种颜色。因此,每当网站需要呈现丰富多彩的图像时,JPEG总是最佳选择。有损压缩,可以通过压缩大大减小图片的尺寸。一般图片用60%的水平比较合适。如果选择大于75%的压缩级别,图片质量将显着降低。不存在兼容性问题,开发者可以自由使用。使用场景JPG适合呈现色彩丰富的图片。在我们日常开发中,JPEG图片经常以大背景图、轮播图或banner图的形式出现。然而,有损压缩后的图像确实很难暴露出缺陷。在处理矢量图、Logo等线条感强、色彩对比强烈的图像时,人工压缩后的图像模糊会非常明显。JPEG图片不支持透明处理,透明图片可以选择使用PNG。PNGPNG(PortableNetworkGraphicsFormat)是W3C制定的一种图像格式,是一种无损压缩的高保真图像格式。它支持8位和24位,这里是二进制数的位数。根据我们前置知识中提到的对应关系,8位PNG最多支持256种颜色,而24位PNG可以显示大约1600万种颜色。PNG图像比JPEG具有更强的色彩表现力,对线条的处理更细腻,对透明度有很好的支持。弥补了我们上面提到的JPEG的局限性,唯一的缺点就是 太大了。应用场景PNG在处理线条和颜色对比方面具有优势。我们主要用它来呈现小Logo,颜色简单,对比强烈的图片或背景等。支持透明处理,透明图片可以选择使用PNGGIFGIF是一种8位无损图片格式,最多支持256色。此限制使GIF格式无法显示多色或摄影图像。优点支持256色,文件体积通常很小支持透明的应用场景支持动画,适合展示一些无限循环的动画,比如图标,表情,广告栏等。非常适合一些只有简单颜色的图片.WebPWebP是一种同时提供有损压缩和无损压缩(可逆压缩)的图像文件格式,源自图像编码格式VP8。它像JPEG一样易于使用细节图像,像PNG一样支持透明度,并且可以像GIF一样显示动态图像,结合了多种图像文件格式的优点。WebP最初于2010年发布,目标是减小文件大小,但达到与JPEG格式相同的图片质量,希望减少图片文件在网络上的发送时间。根据谷歌早先的测试,WebP的无损压缩比在网络上找到的PNG文件减少了45%的文件大小,即使这些PNG文件经过pngcrush和PNGOUT处理,WebP仍然可以将文件大小减少28%。webP虽然有很多优点,但是并不能完全取代JPEG和PNG,因为浏览器对WebP的支持并不通用。特别是移动端IOS系统基本不支持。webp.png图片压缩先看一张图片的加载过程:load.png图片很多,图片过大往往会影响页面加载速度,导致用户体验不好。有的图片达到几百kB,甚至2M(这锅一定要操作回去,还要上传高清大图?),直接导致加载时间过长。因此,对于尺寸过大的图片,可以在将图片保持在可接受的清晰度范围内的情况下,适当压缩图片的尺寸。图像压缩分为有损压缩和无损压缩。有损压缩有损压缩是指在压缩文件大小的过程中,图片的部分信息丢失,即图片质量下降(即图片模糊),这种丢失是不可逆的.一种常见的有损压缩方法是将相邻的像素按照一定的算法进行合并。压缩算法并不对图片的所有数据进行编码压缩,而是在压缩时去除图片中人眼无法识别的细节。因此,有损压缩可以在同等图像质量的情况下大大减小图像的体积。例如,jpg格式的图像使用有损压缩。无损压缩无损压缩是指在不损失图像质量的情况下压缩图像的过程。我们可以随时从无损压缩图片中恢复原始信息。压缩算法对图片的所有数据进行编码压缩,可以在保证图片质量的同时减小图片的体积。例如,png和gif使用无损压缩。以下是各种图片格式的压缩类型image.png工具压缩tinypng[1]免费,批量,极速分块智能图压缩[2]百度好不容易找到官网,免费,批量,好用squoosh[3]在线图片压缩工具compressor[4]支持JPG、PNG、SVG、GIF。webpack压缩工程项目可以在webpack中配置image-webpack-loader进行图片压缩1.安装依赖npminstall--save-devimage-webpack-loader2.配置webpackmodule.exports={...module:{rules:[{test:/\.(png|jpe?g|gif|svg)(\?.*)?$/,use:[{loader:'file-loader',options:{name:'[name].[hash:7].[ext]'},},{loader:'image-webpack-loader',options:{mozjpeg:{progressive:true,quality:50,},optipng:{enabled:true,},pngquant:{quality:[0.5,0.65],speed:4,},gifsicle:{interlaced:false,},webp:{//不支持WEBP的就别写了Aquality:75},},},],},],},}至于是否使用插件自动压缩,见仁见智,因为有些UI和产品会说压缩后的效果图不是自己想要的。使用sprite图像Sprite图像,CSSSprites,国内也叫CSSsprite,是一种CSS图像合成技术,主要用于小图显示。浏览器请求资源时,同源域名请求资源时有最大并发限制。chrome是6的,比如你的页面有10张同CDN域名的小图片,你需要发起10次请求拉取。同时两次。第一个并发请求回来后,再发起第二个并发请求。如果把10张小图组合成一张大图,那么只需要一个请求就可以拉下10张小图的资源。减轻服务器压力,降低并发,减少请求数。优点将很多小图组合成一张大图,使用background-position属性值来确定图片呈现的位置,可以有效减少请求次数,并且在不影响开发体验的情况下,使用build插件可以透明化给开发商。适用于页面图片较多且内容丰富的场景。缺点:生成的图片体积较大,减少请求数也会增加图片体积,不合理的拆分不利于并行加载。合成Sprite在webpack中有一个对应的插件提供了自动合成Sprite的功能,可以自动生成对应的样式文件——webpack-spritesmith,使用方法如下varpath=require('path')varSpritesmithPlugin=require('webpack-spritesmith')module.exports={//...plugins:[newSpritesmithPlugin({src:{cwd:path.resolve(__dirname,'src/ico'),glob:'*.png',},target:{image:path.resolve(__dirname,'src/spritesmith-generated/sprite.png'),css:path.resolve(__dirname,'src/spritesmith-generated/sprite.styl'),},apiOptions:{cssImageRef:'~sprite.png',},}),]}通过上面的配置,可以将src/ico目录下的所有png文件合成为sprite图片,并输出到对应的目录,以及对应的样式文件也可以生成。文件的语法会根据你配置的样式文件的后缀动态生成。使用iconfonticonfont(字体图标),即通过字体来显示图标,多用于渲染图标、简单图形、特殊字体等。优点和使用字体一样,可以设置大小、颜色等样式,不失真,重量轻,易于修改,有效减少HTTP请求次数。推荐使用阿里的字体图标库:iconfont[5]使用base64格式原理:将图片转为base64编码的字符Stringinlineintopage或css。优点提高性能:网页上的每张图片都需要消耗一个http请求来下载。图片的下载总是向服务器发送请求。如果图片下载不需要向服务器发送请求,base64可以跟随HTML下载,同时下载到本地。减少https请求。加密:让用户一眼看不到图片内容,只能看到代码。方便参考:当多个文件同时使用一些图片时,可以将图片转为base64格式文件,把样式放在全局,比如common.css,使用的时候直接加上类名就可以了未来。需要多层查找文件路径,这样会提高效率,但是需要注意的是,如果图片很大,图片的颜色层次很丰富,这种方法就不适用了,因为图片编码的字符串bybase64非常大,它会显着增加HTML页面的大小,影响加载速度。Base64ization最常用于url-loader。module.exports={...module:{rules:[{test:/\.(png|jpe?g|gif|svg)(\?.*)?$/,loader:'url-loader',options:{limit:10240,name:utils.assetsPath('img/[name].[hash:7].[ext]'),}},],},}这会在项目中转换小于10kb的图片使用css而不是应用于页面的base64图像。比如实现半透明、边框、圆角、阴影、渐变等修饰效果,在目前主流浏览器中都可以用CSS实现,可以减少图片请求,达到优化的目的。缺点浏览器兼容性受限于css对于更复杂的模式无能为力,编写起来麻烦,开发成本高使用CDNImageCDN的全称是ContentDeliveryNetwork,即内容分发网络。CDN是建立在互联网上的内容分发网络。依托部署在各地的边缘服务器,通过中心平台的负载均衡、内容分发、调度等功能模块,用户可以就近获取所需内容,减少网络拥塞,提高用户接入。响应速度和命中率。CDN的关键技术主要包括内容存储和分发技术。举个简单的例子:在买火车票之前,大家只能去火车站买。后来我们买火车票的时候,在楼下的火车票售票点就可以买到。基本原理CDN的基本原理是广泛采用各种缓存服务器,将这些缓存服务器分布到用户访问相对集中的区域或网络中,在用户访问网站时,利用全局负载技术将用户访问引导到就近的正常工作。在缓存服务器上,缓存服务器直接响应用户请求。基本思想CND的基本思想是尽可能避开互联网上可能影响数据传输速度和稳定性的瓶颈和链路,从而使内容传输更快更稳定。通过在全网布设节点服务器,在现有互联网基础上形成一层智能虚拟网络,CDN系统可以实时根据网络流量和各节点的连接情况、负载状况、到用户的距离以及响应时间等综合信息,将用户的请求重定向到离用户最近的服务节点。其目的是使用户就近获取所需内容,解决Internet网络拥堵情况,提高用户访问网站的响应速度。CDN的优势CDN节点解决了跨运营商、跨地域的访问问题,访问时延大大降低;大多数请求在CDN边缘节点完成,CDN起到分流的作用,减轻源站的负载。图片延迟加载延迟加载是一种优化网页性能的方式,可以极大地提升用户体验。图片一直是影响网页性能的罪魁祸首,现在一张图片超过几兆非常普遍。如果每次进入页面都请求所有的图片资源,那么用户可能会在图片加载完很久之后就离开了。所以在进入页面时,只请求可见区域的图片资源。总结就是:减少资源的加载,页面启动时只加载首屏的图片,可以显着降低服务器的压力和流量,也可以减轻浏览器的负担。防止并发加载过多的资源阻塞js的加载,影响整个网站的启动,影响用户体验,浪费用户流量。有些用户不想全部看完,全部加载会消耗大量流量。原理图片懒加载的原理是暂时不设置图片的src属性,而是隐藏图片的url,比如先写在data-src中,然后把图片的真实url放入当前图片在可见区域属性后的src,实现图片的懒加载。functionlazyload(){letviewHeight=document.body.clientHeight//获取可见区域的高度letimgs=document.querySelectorAll('img[data-src]')imgs.forEach((item,index)=>{if(item.dataset.src==='')return//用于获取页面中某个元素相对于浏览器窗口的左上右下位置letrect=item.getBoundingClientRect()if(rect.bottom>=0&&rect.top{entries.forEach((entry)=>{if(entry.isIntersecting){letimg=entry.targetletsrc=img.dataset.srcif(src){img.src=srcimg.removeAttribute('data-src')}//取消观察self.unobserve(entry.target)}})},config)imgs.forEach((image)=>{observer.observe(image)})图片预加载图片预加载是指在一些需要显示大量图片的网站上,提前将图片加载到本地缓存中,以提高用户体验。常用的方法有两种,一种是隐藏在css后台的url属性中,一种是通过javascriptImage对象设置实例对象的src属性,实现图片的预加载。1.用CSS和JavaScript实现预加载#preload-01{background:url(http://domain.tld/image-01.png)no-repeat-9999px-9999px;}#preload-02{background:url(http://domain.tld/image-02.png)no-repeat-9999px-9999px;}#preload-03{background:url(http://domain.tld/image-03.png)no-repeat-9999px-9999px;}通过CSSbackground属性在离屏背景上预加载图像。当在网页的其他地方调用它们时,浏览器会在渲染期间使用预加载(缓存)的图像。虽然高效,但该方法仍有改进的空间。使用此方法加载的图像将与页面上的其他内容一起加载,从而增加页面的整体加载时间。为了解决这个问题,我们添加了一些JavaScript代码来延迟预加载,直到页面加载完毕。functionpreloader(){if(document.getElementById){document.getElementById('preload-01').style.background='url(http://domain.tld/image-01.png)no-repeat-9999px-9999px'document.getElementById('preload-02').style.background='url(http://domain.tld/image-02.png)no-repeat-9999px-9999px'document.getElementById('preload-03').style.background='url(http://domain.tld/image-03.png)no-repeat-9999px-9999px'}}functionaddLoadEvent(func){varoldonload=window.onloadif(typeofwindow.onload!='function'){window.onload=func}else{window.onload=function(){if(oldonload){oldonload()}func()}}}addLoadEvent(preloader)2、使用JavaScript实现预加载functionpreloader(){if(document.images){varimg1=newImage()varimg2=newImage()varimg3=newImage()img1.src='http://domain.tld/path/to/image-001.gif'img2.src='http://domain.tld/path/to/image-002.gif'img3.src='http://domain.tld/path/to/image-003.gif'}}functionaddLoadEvent(func){varoldonload=window.onloadif(typeofwindow.onload!='function'){window.onload=func}else{window.onload=function(){if(oldonload){oldonload()}func()}}}addLoadEvent(preloader)响应式图片加载什么是响应式图片加载?其实就是在不同分辨率的设备上显示不同大小的图片。避免资源浪费的常用方法是CSS3媒体查询。@mediascreenand(min-width:1200px){img{background-image:url('1.png');}}@mediascreenand(min-width:992px){img{background-image:url('2.png');}}@mediascreenand(min-width:768px){img{background-image:url('3.png');}}@mediascreenand(min-width:480px){img{background-image:url('4.png');}}另外,HTML5的图片属性可以用于响应式处理。方法如下:创建图片标签。放置多个source标签指定不同的图片文件名,然后根据不同的情况加载。添加后备元素需要注意的是,目前很多浏览器还不支持图片标签,使用时需要注意。picture.png渐进式图片渐进式图片是指在加载高质量图像之前先显示低质量版本。低质量版本由于质量低、压缩率高、体积小,所以加载速度很快。在两者之间,我们还可以根据需要显示不同质量的版本。cat.png渐进式图像会给用户一种图像加载速度更快的印象。用户不再盯着空白区域等待图片加载,而是看到图片越来越清晰,对用户体验也很友好。骨架屏技术也是类似的原理。总结选择合适的图片格式,压缩大图,可以从根本上解决大图截图加载慢的问题。使用sprite、iconfont、base64、css代替图片可以减少http对图片的请求,提高页面加载速度。使用CDN镜像可以达到导流的效果,减轻服务券的压力。图片懒加载、预加载、渐进式图片等可以不同程度减少白屏时间,提升产品体验。本文收录于githubhttps://github.com/Michael-lzg/my--article/blob/master/other/%E5%89%8D%E7%AB%AF%E6%80%A7%E8%83%BD%E4%BC%98%E5%8C%96%E5%9B%BE%E7%89%87%E7%AF%87.md