浅探前端图片优化,web前端性能优化指南

时间: 2018-12-22阅读: 521标签: 图片

最近在看《web全栈工程师的自我修养》一书,作者是来自腾讯的前端工程师。作者在做招聘前端的时候问应聘者web新能优化有什么了解和经验,应聘者思索后回答“在发布项目之前压缩css和 Javascript源代码。这样文件体积就变小了,用户加载必要资源所花费的时间就更短了”。作者追问还有吗,应聘者答不上来了。

时间: 2019-09-07阅读: 175标签: 性能前端需要性能优化么?

性能优化是前端开发必不可少的一环,而图片优化又是性能优化中必不可少的一环,但不知道有多少开发者在网页的开发过程中会注意图片的使用,图片使用不当可能会导致网页加载卡顿、网页加载速度慢等问题,这篇文章将会将我以往对图片的处理做个总结。

作者在书中附上的更多的web性能优化经验。其中我详细补充了很多

性能优化一直以来都是前端工程领域中的一个重要部分。很多资料表明,网站应用的性能优化对于提高用户留存、转化率等都有积极影响。可以理解为,提升你的网站性能,就是提升你的业务数据(甚至是业务收入)。

不同格式图片优劣对比

 

性能优化广义上包含前端优化和后端优化。后端优化的关注点更多的时候是在增加资源利用率、降低资源成本以及提高稳定性上。相较于后端,前端的性能优化会更直接与用户的体验挂钩。从用户体验侧来说,前端服务 5s 的加载时间优化缩减 80%(1s) 与后端服务 50ms 的响应优化缩减 80%(10ms)相比,用户的体验提升会更大。因此很多时候,与体验相关的性能的瓶颈会出现在前端。

有人可能会问说好的图片优化呢?怎么说到图片格式了,其实在不同的场景选择使用不同格式的图片就是对图片的一种优化,这是最直接最重要但是最容易被忽略的,现在网页中常用的图片格式有JPG.PNG.SVG.WebP等,接下来我们就来介绍它们有何优劣

压缩源码和图片 

我和一些同学接触的过程中,发现作为前端工程师,大家其实都具备一定的性能优化意识,同时也有自己的优化“武器库”,例如懒加载、资源合并、避免 reflow等等。虽然大家对性能优化都有自己的思路,不过大多是分散在某几个点,较难形成一个完整的体系。业界也有很多优质的资料,例如雅虎的性能优化 35 条,但是性能优化作为一个系统性工程,大家想要系统性地去学习并不容易。

JPG

  • JavaScript 文件源代码可以采用混淆压缩()的方式,css文件源代码进行普通压缩,jpg图片可以根据质量压缩为50%到70%,PNG可以用一些开源软件来压缩,比如24色变成8色,去掉一些PNG格式信息等。
  • js代码混淆压缩工具  站长工具: 
  • png格式,压缩工具 
  • 腾讯出品的压缩工具:智图   

一、html文档结构标签语义化1、首先什么是语义化呢?

JPG格式的图片应该是使用场景最多的图片的格式了,由于JPG格式采用了极其高效的压缩算法,使其能在压缩50%甚至60%的情况下依旧可以保持不错的图片质量,因此在网站设计中使用类似背景图,轮播图等大图时都会考虑使用JPG格式的图片,但是JPG始终是有损压缩,在对线条感较强或者颜色比较丰富的图片做人为压缩时,可能会出现失真的情况,同时它也不支持透明度处理

选择合适的图片格式

语义化是指用合理HTML标记以及其特有的属性去格式化文档内容。机器在需要更少的人类干预的情况下能够研究和收集信息,让网页能够被机器理解,最终让人类受益。即用正确的标签做正确的事。

PNG

  • 如果图片颜色比较多就用JPG格式,如果图片颜色比较多就用JPG格式,较少就用PNG格式,透明的图片都用PNG格式,如果能够通过服务器判断浏览器支持webP格式,那就用WebP格式和SVG。
  • 其中webP格式是谷歌大力推崇的图片格式,体积比PNG小45%。关于WebP格式的具体请看

2、语义化的好处或者说存在的意义

PNG格式的图片特点大家都知道,就是高保真无损压缩,当对图片设计有较高要求时,首选PNG格式,显示高清细腻,但是它也有明显的问题就是体积过大

合并静态资源

① 有利于搜索引擎抓取

SVG

包括CSS,Javascript和小图片,减少HTTP请求

② 结构清晰的HTML在团队合作中的作用:代码可读、便于维护、提高开发效率、快速达成共识、利于二次开发。

SVG格式图片有个显著特点就是它是可编程的,是基于xml语法的,同时作为矢量图,它可以无限放大而不变形,因此可以方便的对不同手机屏幕做自适应,相比于PNG和JPG它的体积更小,只有1kb甚至更小,但是它最大的缺陷就是渲染成本过高,因此我们在选择一些小且色彩单一的图标时可以考虑使用SVG格式的图片,如图

其中小图片的优化我我知道的有2种,

③ 有利于盲人屏幕阅读器

一般情况下,我们会将SVG格式的图片上传到iconfont上,这样不仅方便管理而且方便使用,同时iconfont上还有许多其他设计师设计的优秀小图标可以直接拿来使用,是不是很方便呢?

  • 第一种:使用css精灵图sprites(也有人称为雪碧图),将小图标全部放在一张图片上(可以使用这个网站来制作雪碧图 
  • 第二种:使用iconfont字体,图片以字体的形式展现,注明的bootstrap框架就用到了这个技术。国内比较著名的免费开源iconfont是阿里是Iconfont(.

二、css、js文件数量及大小

WebP与gif

开启服务端的Gzip压缩

优化一般对于css、js是建议使用外联式来进行导入。我们可以对css、js做相应的规划也可以减少css、js的个数以减少http请求。同时也要注重减少重复代码,注重代码重复利用,以达到用最少的代码干最多的事。同时当项目要投入上线使用的时候,可以对css、js文件进行压缩,文件的减小可以加速文件的链接导入,以便加速网页的加载渲染。

这两兄弟我们一般都是用来展示动图的,但是WebP也可以用来展示静态图片,WebP最大的优点就是无损压缩,体积小,但是浏览器支持太差,我们来看caniuse的数据:

  • 对文本资源非常有效,对图片资源则没那么大的压缩比率。

通过在线网站对html,css,js文件压缩可参考资料:前端性能优化(一)-- 文件的压缩与合并

从图上可以看到WebP格式在苹果设备和IE上基本不支持,因此浏览器的不支持是它的硬伤,因此在对动图做展示的时候我们不得不选gif,即便它的体积很大,渲染开销也大

使用CDN

可通过使用webpack,gulp等工具对Js文件进行合并。

图片优化方案图片质量压缩

  • 一些公共库可以使用第三方提供的静态资源地址,(比如jquery,Normalize.css),一方面增加并发下载量,另一方面能够和其他网站共享缓存。
  • 免费的cdn网站 

三、图片的数量和大小

图片压缩应该是图片优化时最常用的方案,因为很简单,只需要将图片上传到tinypng或者智图这类的在线压缩图片平台,对图片进行压缩,就可以较小图片质量

延长静态资源缓存时间

多个服务器请求会对站点的性能产生显著的影响。对一张图片进行导入又是一个http请求,因此我们应该减少图片的导入数量以便减少http请求。此处,我们必须提到一个名词“css精灵spirit”。css精灵是指包含多个不同的图标、按钮或图形的单个图像。因此我们可以把多张背景图片合并为一张然后对背景图片进行相应的定位。同时使用PNG8格式的图片相对于GIF来说比较少。而对于内容图片,可以对其进行适当的压缩,可以加快文档内容加载,或者如果是需要用户下载的图片,小的图片可以加快用户下载的速度。

雪碧图

  • 这样频繁访问网站的访客就能够更快的访问,不过这里要通过修改文件名的方式,确保在资源更新的时候,用户会拉取到最新的内容。

使用较为广泛的web图片格式有:JPEG/JPG、PNG、WEBP、Base64、SVG。

雪碧图经常用来将多个小图标和成一张图片,然后将合成的图片当作背景图片是使用,这样可以减少图片的网络请求,使用之前可能需要请求10个网络小图标,而使用之后请求一个就可以搞定,我个人通常使用gopng这个网站在线生成,还可以自动生成对应的css代码

把css放在页面头部,把JavaScript 放在页面底部

1.JPEG/JPG

base64

  • 这样就不会阻塞页面渲染,让页面长时间的空白。

特点是有损压缩,体积小,加载快,不支持透明。

将一个图片地址进行base64编码后会得到一串字符串,将这个字符直接放到img的src属性上,你会发现浏览器是可以识别这一串字符的,不需要发送网络请求直接解析,这样就可以达到减少网络请求的目的,但是base64编码后的图片质量比原图图片质量要大,因此也只会在一些质量较小的图标类图片上面使用,否则得不偿失,常见使用base64编码的方案就是webpack的url-loader,举个例子:

使用场景:JPG适合用于呈现热菜丰富的图片,在日常的开发中,JPG图片经常作为大的背景图、轮播图或是Banner图。比如两大电商网站对大图片的处理,就是对JPG图片应用场景的最佳写照。用JPG来呈现大图片,既可以保留图片的质量,又不会担心图片的体积,是一种比较广泛使用的方案。

module.exports = { module: { rules: [ { test: /.(png|jpg|gif)$/, use: [ { loader: 'url-loader', options: { limit: 8192 } } ] } ] }}

缺点:在处理一些矢量图形和logo等这些线条感很强、颜色对比强烈的图片时,认为压缩就导致图片模糊非常明显。另外,JPG图像不支持透明度处理,透明图片只能用PNG来呈现了。

上面的这个配置就是把8k一下的通过url-loader进行base64编码,转换成一串DataUrl

2.PNG-8和PNG-24

css替换简单图标

特点是无损压缩、质量高、体积大、支持透明

这个优化方案应该都懂,其实就是在写代码之前先考虑一下设计稿里面的哪些内容是可以通过代码来实现的,能通过代码实现的尽量用代码实现,同时实现的时候多考虑绘制性能,能使用css3做GPU硬件加速的就尽量使用css3属性,这些都能减少图片使用而且不影响渲染性能

优点:无损压缩的高保真图片格式。8和24都是二进制数的位数,8位的PNG支持256中颜色,24位的PNG可以支持1600万种颜色。在不考虑文件大小只在乎最佳的显示效果时,推荐使用PNG-24。但是在适合使用PNG时会优先选择PNG-8

响应式图片加载

应用场景:主要用PNG来呈现小的LOGO、颜色简单对比强烈的图片或是背景。

什么是响应式图片加载?其实就是在不同分辨率的设备上显示不同尺寸的图片,避免资源的浪费,常用的方法就是css3的媒体查询(media query),来看个例子:

3.SVG

@media screen and (max-width: 375px) { img { background-image: url('phone.png'); }}@media screen and (max-width: 768px) { img { background-image: url('tablet.png'); }}

特点是文本文件,体积小,不失真,兼容性好

懒加载

优点:SVG是一种基于XML语法的图像格式。SVG对图像的处理不是基于像素,而是基于对图像的形状描述。

图片懒加载的目的就是为加快页面加载速度而做的,为了不让图片一次全部加载出来,通过将图片地址存放在一个img标签的属性上,当图片被滚动到页面上时,在将src属性替换成图片地址来达到懒加载的效果

和JPG、PNG相比较,SVG文件体积更小,可压缩性更强。SVG作为矢量图最大的优点在于图片可以无限放大还不失真,一张SVG图片可以适配多种分辨率。另外SVG是文本文件,可以像写代码一样定义SVG,放在HTML中称为DOM的一部分。也可以把对图像的描述写入以.svg为后缀的文件中,在img标签中引入即可。img src="文件名.svg" alt=""

webpack图片优化图片压缩

4.WebP

webpack也可以对图片进行压缩操作,通过image-webpack-loader可以对输出的图片进行指定质量的压缩,来看具体例子:

优点:WebP是一款比JPG、PNG等在压缩方面更加优越的图片格式,同时也不会影响其图片质量,使用该格式时最好将同名文件格式化,当检测浏览器不兼容时自动切换jpg格式

{test: /.(png|jpg|gif|svg)$/,use: [ 'file-loader', { loader: 'image-webpack-loader', options: { bypassOnDebug: true, mozjpeg: { progressive: true, quality: 65 }, optipng: { enabled: false, }, pngquant: { quality: '65-90', speed: 4 }, gifsicle: { interlaced: false, }, // the webp option will enable WEBP webp: { enabled: false, }, limit: 1, name: '[name].[ext]?[hash]' } }]}

缺点:是一个相对较新的技术,所以对于目前市面上的浏览器能否完美的兼容,其可用和实用性就变得很现实了,再好的东西如果没有好的兼容性,也是非常难以普及和被广泛使用的

上面的配置指定了各个格式的图片的压缩质量,并且通过hash编码重新命名输出

5.Base64

合成雪碧图

优点:减少请求,加快首屏数据显示。对于jpg格式的图片,每一个图片相当于一次http请求,图片多了的话,服务器耗性能比较严重。而将jpg转化成base64格式的图片,则极大地减少了请求数,因为Base是文本格式。

webpack的webpack-spritesmith插件提供了自动合成雪碧图的功能并且可以自动生成对应的央视文件,非常方便,来看一个具体的例子:

缺点:base64格式图片比原图大,占用更多存储空间,同时,浏览器不会对该资源缓存。

const SpritesmithPlugin = require('webpack-spritesmith')new SpritesmithPlugin({ src: { cwd: path.resolve(__dirname, 'src/asserts'), glob: '*.png' }, target: { image: path.resolve(__dirname, 'src/spritesmith-generated/sprite.png'), css: path.resolve(__dirname, 'src/spritesmith-generated/sprite.css') }, apiOptions: { cssImageRef: "src/sprite.png" }})

使用方法:background:url(data:image/png;base64,{img_data})

通过上面配置就能将asserts目录下的所有png文件合成雪碧图,并且输出到对应目录,同时还可以生成对应的样式文件,样式文件的语法会根据你配置的样式文件的后缀动态生成,比如这里我们配置的是sprite.css,生成的文件内容就是css语法:

应用场景:一般对于小于10KB大小的图片进行base64转码。

.icon-checkout { background-image: url(src/sprite.png); background-position: -96px -56px; width: 34px; height: 32px;}.icon-clock { background-image: url(src/sprite.png); background-position: -96px 0px; width: 56px; height: 56px;}.icon-close { background-image: url(src/sprite.png); background-position: 0px 0px; width: 96px; height: 96px;}

至于动态图有GIF与APNG:后者APNG这东西是mozilla搞出来的, 它是24位的,而且也是动图,可以容纳1680万种颜色,也是为了取代GIF,但是....也就火狐支持,IE10和chrome,safari全部不行, 如果说gif图片是卡片机的话, APNG就是单反,测试浏览器是否支持apng格式

如果将配置中的sprite.css改成sprite.scss那么生成语法就是scss的语法:

四、有效性验证

@mixin sprite-width($sprite) { width: nth($sprite, 5);}@mixin sprite-height($sprite) { height: nth($sprite, 6);}@mixin sprite-position($sprite) { $sprite-offset-x: nth($sprite, 3); $sprite-offset-y: nth($sprite, 4); background-position: $sprite-offset-x $sprite-offset-y;}@mixin sprite-image($sprite) { $sprite-image: nth($sprite, 9); background-image: url(#{$sprite-image});}@mixin sprite($sprite) { @include sprite-image($sprite); @include sprite-position($sprite); @include sprite-width($sprite); @include sprite-height($sprite);}@mixin sprites($sprites) { @each $sprite in $sprites { $sprite-name: nth($sprite, 10); .#{$sprite-name} { @include sprite($sprite); } }}

除了根据语义加标记之外,HTML文档还需要用有效的代码来编写,如果代码是无效的,浏览器会尝试解释标记本身,有时候会产生错误的结果。更糟的是,如果发送具有正确的MIME类型的XHTML文档,理解XML的浏览器将不显示无效的页面。因为浏览器需要知道要使用什么DTD(文档类型定义)才能正确地处理页面,所以对页面进行有效性验证要求有DOCTYPE声明。

这样就可以根据你项目中使用的样式语言去生成所需要的语法,是不是很方便呢?

有效性验证工具径:① W3C验证器(bookmarklet),这是一小段可以存储在浏览器的书签或收藏夹中的Javascript。单击这个书签就会触发Javascript动作。

总结

②可以访问,通过输入自己的URL来对自己的站点来进行在线验证。

这篇文章简单介绍网页开发中的各个图片格式的优缺和一些常用的图片优化,希望这篇文章对大家以后在做图片优化时能有所帮助。

③使用firefox浏览器的可以下载插件Firefox Web Developer Extension

来自:

五、雅虎的Web优化最佳实践

1、内容优化

① 尽量减少HTTP请求:常见方法包括合并多个CSS文件和JavaScript文件,利用CSS Sprites整合图像,Image map(图像中不同的区域设置不同的链接),内联图象(使用 data: URL scheme 在实际的页面嵌入图像数据)等。② 减少DNS查找,一般dns查找需要花费20-120ms,Windows的DNS缓存,可以通过ipconfig /displaydns这个命令来查看。详细资料③ 避免重定向④ 使Ajax可缓存⑤ 延迟加载组件:考虑哪些内容是页面呈现时所必需首先加载的、哪些内容和结构可以稍后再加载,根据这个优先级进行设定。⑥ 预加载组件:预加载是在浏览器空闲时请求将来可能会用到的页面内容(如图像、样式表和脚本)。当用户要访问下一个页面时,页面中的内容大部分已经加载到缓存中了,因此可以大大改善访问速度。⑦ 减少DOM元素数量:页面中存在大量DOM 元素,会导致JavaScript遍历DOM的效率变慢。⑧根据域名划分页面内容:把页面内容划分成若干部分可以使你最大限度地实现平行下载。但要确保你使用的域名数量在2个到4个之间(否则与第2条冲突)。⑨ 最小化iframe的数量:iframes 提供了一个简单的方式把一个网站的内容嵌入到另一个网站中。但其创建速度比其他包括JavaScript和CSS的DOM元素的创建慢了1-2个数量级。⑩ 避免404:HTTP请求时间消耗是很大的,因此使用HTTP请求来获得一个没有用处的响应(例如404没有找到页面)是完全没有必要的,它只会降低用户体验而不会有一点好处。

2、服务器优化

① 使用内容分发网络(CDN):把你的网站内容分散到多个、处于不同地域位置的服务器上可以加快下载速度。添加Expires或Cache-Control信息头:对于静态内容,可设置文件头过期时间Expires的值为“Never expire(永不过期)”;对于动态内容,可使用恰当的Cache-Control文件头来帮助浏览器进行有条件的请求。② Gzip压缩③ 设置ETag:ETags(Entity tags,实体标签)是web服务器和浏览器用于判断浏览器缓存中的内容和服务器中的原始内容是否匹配的一种机制。④ 提前刷新缓冲区:当用户请求一个页面时,服务器会花费200到500毫秒用于后台组织HTML文件。在这期间,浏览器会一直空闲等待数据返回。在PHP中,可以使用flush()方法,它允许你把已经编译的好的部分HTML响应文件先发送给浏览器,这时浏览器就会可以下载文件中的内容(脚本等)而后台同⑤时处理剩余的HTML页面。⑥ 对Ajax请求使用GET方法:当使用XMLHttpRequest时,浏览器中的POST方法会首先发送文件头,然后才发送数据。因此使用GET最为恰当。⑦ 避免空的图像src

3、Cookie优化

① 减小cookie大小:去除不必要的coockie,并使coockie体积尽量小以减少对用户响应的影响② 针对Web组件使用域名无关的Cookie:对静态组件的Cookie读取是一种浪费,使用另一个无Cookie的域名来存放静态组件是一个好方法,或者也可以在Cookie中只存放带www的域名。

4、CSS优化

① 将CSS代码放在HTML页面的顶部② 避免使用CSS表达式:CSS表达式在执行时候的运算量非常大,会对页面性能产生大的影响③ 使用link来代替@import④ 避免使用Filters:IE独有属性AlphaImageLoader用于修正IE 7以下版本中PNG图片的半透明效果,但它的问题在于浏览器加载图片时它会终止内容的呈现并且冻结浏览器。

5、JavaScript优化

① 将JavaScript脚本放在页面的底部② 将JavaScript和CSS作为外部文件来引用:在实际应用中使用外部文件可以提高页面速度,因为JavaScript和CSS文件都能在浏览器中产生缓存。③ 缩小JavaScript和CSS④ 删除重复的脚本⑤ 最小化DOM的访问:使用JavaScript访问DOM元素比较慢⑥ 开发智能的事件处理程序

6、图像优化

① 优化图片大小② 通过CSS Sprites优化图片③ 不要在HTML中使用缩放图片④ favicon.ico要小而且可缓存

7、针对移动优化

① 保持组件大小在25KB以下:主要是因为iPhone不能缓存大于25K的文件(注意这里指的是解压缩后的大小)。② 将组件打包成为一个复合文档:把页面内容打包成复合文本就如同带有多附件的Email,它能够使你在一个HTTP请求中获取多个组件。

本文由澳门威斯尼人平台登录发布于Web前端,转载请注明出处:浅探前端图片优化,web前端性能优化指南

相关阅读