一般来说,一个网站的资源文件中图片占据较大比例,特别是面向用户的网站,图片特别直观,无图无真相,有时候一张图片胜过千言万语。图片被广泛使用到了网页中,但是图片占据的字节相当于js,css等资源来说特别的大,数量也多。如果能从图片上进行优化,能够比较大幅度的提升网页加载速度。

本文主要介绍网站性能优化中对图片的优化,包括图片的类型介绍、选择、压缩裁剪、根据客户端使用相应的新图片格式、以及一些提高首屏加载速度的方案。

一、图片的格式

图片分矢量图和光栅图,矢量图svg,最适用于包含几何形状的图像;光栅图,应用于包含大量不规则形状和细节的复杂场景,包含GIF,PNG、JPEG,以及比较新的webp,JPEG XR等。下图是他们的浏览器兼容情况

没有一个绝对好用的图片格式,都是根据实际需求而定,不同的图片类型使适用不同场景,比如:GIF用于动画;PNG用于支持高分辨率或者需要保留精细细节的图片(如会放大查看的),压缩时只会是无损压缩,需要谨慎使用;JPEG可用于需要进行优化的图片(如背景图片,照片,屏幕截图等),调节压缩参数可以压缩到较小的体积;新的webp和JPEG可以压缩到更小的体积,但是目前都是部分浏览器支持的情况。

附:具体浏览器对图片的支持情况,可以到Can I use这个网站查看,举例如下

二、图片格式选择

介绍了图片的类型,我们明确了我们可以有的选择,接下来我们将详细的讨论如何最正确的选择图片格式,其实上文已经蜻蜓点水般的提到,但是还需要更多细节。下图是判断选择图片的流程,根据这个流程图可以找到你需要的格式。


图片来自google性能优化相关章节

1、先判断是否需要动画,如果需要,GIF是唯一的选择
当然,动画可以通过其他方式实现,比如使用多个连贯的静态图片通过根据帧数切换显示,也能得到动画的效果,动画本质如此。

2、需要保留精细细节、支持高分辨率屏幕的选择PNG
图片压缩有有损压缩和无损压缩,无损压缩只会去除对图片清晰度不会有损耗的压缩,例如只是去除照片的时间,地理位置等无关信息。有损压缩则是根据压缩工具本身的算法进行压缩,可能把颜色数量降低,相近的颜色进行合并等。深入理解可以查看https://developers.google.com的图片优化部分。
(1)、png是无损压缩,因此能产生高质量的图片,但是其相应的是要付出图片体积较大的代价。png适用于要保留精细细节的图片,压缩体积不会很明显,所以需要判断是否确实有此需要,慎用png,勿滥用png。
(2)、如果图片由几何图形组成使用矢量图片svg更佳,矢量图片不会因为放大而模糊。
(3)、如果图片包含文本,该文本无法缩放、搜索、复制等,请考虑使用网页字体。但是由于汉字字体好看的较少,用网页字体做出来的效果往往低于预期。
(4)、png还分PNG 8,PNG 24。他们的区别是颜色的种类,PNG 8 颜色种类比PNG 24少的多,压缩体积自然小的多。如果你的图片需要丰富多彩的颜色,如自然景观、生活照片,花鸟鱼虫物等绝大多数照片使用PNG 24。如果是logo等纯色图片,使用PNG 8.

3、那么,不需要保留高质量的图片就都可以用JPEG了
JPEG用于需要进行图片优化的图片,改格式的图片压缩工具会采用有损压缩算法,压缩出来的体积能够较大幅度的降低。具体压缩到什么程度,需用什么参数根据你的需要而定,没有特定的标准。不要害怕,大胆的调节参数,选择最适合你的压缩结果,压缩后的效果也往往令人满意。

4、考虑使用新图片格式webp、jpeg XR 等
webp,jpeg XR,jpeg 2000与JPEG相比可以压缩更大的体积,大概30%左右。但是由于webp和jpeg XR,jpeg 2000等未普遍得到支持。往往需要借助客户端或者服务端判断浏览器选择对应支持的格式,不支持的采用其他格式。那么岂不是要准备多套图片?也可以这么认为。但是图片基本存放在CDN上,现在的主流CDN基本也提供转换的图片,如阿里云OSS,七牛云等。
阿里转换例子:http://image-demo.oss-cn-hangzhou.aliyuncs.com/panda.png?x-oss-process=image/format,jpg

三、图片优化步骤

1、如果图片中包含非特殊字体,使用网页字体
图片中包含字体,除了上诉中所说的无法缩放、搜索、复制等的问题以外,文字在图片中的编码占用的字节永比网页字体实现要来的大(当然,如果引入了字体文件体积较大就另当别论)。

2、剪裁适当大小的图片
从上图可以看到,图片此时显示的是314*418,但是原图是1080*1440px。较大的图片是一种资源的浪费,使用适当的大小能够减少体积。(当然,也要考虑业务场景,比如iphone上,往往用2倍natural的图片,这个读者可自行验证)。

3、使用自动化工具进行压缩
前端工作是繁琐的,如果一个个图片根据参数进行调优,那么无疑浪费了很多时间。要利用CDN服务商或者自动化工具进行压缩,压缩工具推荐ImageOptim软件,或者在线压缩网站https://tinypng.com/https://imageresize.org/compress-images,是我用过的感觉比较好的网站,如有更好欢迎推荐。

4、如果使用webp,根据用户浏览器选择格式。
对于支持webp的客户端,选择webp。可以在服务端做,也可以在客户端做。但是在服务端做效果更佳,当用户请求服务端时,判断用户window.navigator.userAgent的值,进行浏览器类型选择对于的图片格式。

举例我的工作中使用的场景,我们使用node.js做服务端,使用ejs模板做服务端渲染页面,使用阿里云oss做转换。
服务端根据请求判断浏览器类型选择相应页面。

router/dingkundan.js

module.exports = {
  init:init
}

function init(app) {
  app.get("/dingkundan",(req,res,next)=>{
      var imgSuffix = '';
      var userAgent = req.headers['user-agent'];
      var browser = getBrowser(userAgent);
      if(browser === 'chrome' || browser === 'android'){
        imgSuffix = 'x-oss-process=image/format,webp';
      }
      res.render("dingkundan/index",{imgSuffix:imgSuffix})
  });
}

//判断用户浏览器类型
function getBrowser(userAgent){
  //此处写方法判断用户浏览器类型
  //...
}

注意:此此可写成中间件

客户端根据后缀做png->webp的转换
view/dingkundan.html

<img class="bg-img" src="../images/bg.png?<%- imgSuffix -%>" alt="">

这样,如果不支持webp的,src则是”../images/bg.png?”,如果支持webp,则是”../images/bg.png?x-oss-process=image/format,webp“。

注:如果使用webpack的url-loader编译图片会导致后缀丢失,请使用meetyou-url-loader

总结:
经过上面的陈述,开发中我们需要根据实际业务场景选择合适的图片格式;通过工具选择适当的参数进行压缩,根据客户端浏览器选择新的图片格式利用CDN做转换,通过这几步骤我们已经可以生产出在不影响视觉效果的情况下的最小体积的图片,也就是我们的图片资源已经最大限度的进行压缩,节约了http传输过程的时间,以及缓解了服务器带宽的限制,这较大幅度的提升了网页加载速度。但是往往压缩后图片的大小仍然非常大,200-300kb大小的如背景图片等还非常普遍,在mobile环境中还需要加载好几秒,而且经常一个页面中有十几到几十张图片,网页的首屏渲染时间还有提高的空间。这就需要利用图片渐进显示懒加载来提高首屏渲染速度和增强用户体验。请看我另一片文章极致性能 – 图片的渐进显示和懒加载

 

 

 

 

Categories: 前端性能优化

2 Comments

shytong · 2017年12月1日 at 下午2:48

    yitala · 2017年12月1日 at 下午3:30

    数语科技公司董事长亲自光临,蓬荜生辉啊!

发表评论

电子邮件地址不会被公开。 必填项已用*标注