花花你为什么不叫海鲜

性能日志 » 使用HTTP2和渐进式JPEG图片更快的加载图像

花花你为什么不叫海鲜 · 2017-01-09翻译 · 865阅读 原文链接

tl;dr: 渐进式图像在HTTP 2上渲染得更快,从而增加感知性能。控制渐进JPEG扫描图层来实现只用25%的图像数据展示具有核心意义的图像内容。对于渐进式JPEG使用HTTP Server Push,来最大化关键图像的渲染性能。

我们有一个关于图像的问题

Engaging, enraging and encouraging images

图像让世界都聚到了一起: 它们吸引我们,激怒我们,也鼓励我们。我们所熟知的网络也依赖着图片。这带来的代价就是: 图片约占每页平均总字节的65%以上 且与页面加载时间速度指数保持着极高的相关度。并且,它们依然按照每年200kb的速度增长着。一句话,图片是笨重的,总是让事物变的很慢。

来压缩它!

HTTP Archive Statistics

减少图片资源加载带来的负面影响的最好方式就是图片压缩: 使用工具,比如像 Kornel LesińskiImageOptim, 利用强大的库,比如 mozjpegpngquant,我们可以在不牺牲视觉质量的基础上减少图片的比特数。当然也要感谢像 DSSIM 这样的库,我们可以在测试不同的压缩程度下确保良好的视觉质量。

坏消息是即使通过以上提到的工具,甚至是使用其他图片格式比如Webp可以让每张图片大小平均减少29%左右 ,图片依然可能成为唯一最大的资源类型,仅次于javascript。为了让这些情绪化的约定更快一些,我们需要一种传递这些重要组件的方法。

加入多路复用

HTTP2 Multiplexing Diagram

解决方案中一部分来自于一个在性能问题方面非常流行的领域:HTTP2\。其中主要受益于“多路复用”:所有使用相同的TCP连接时,可以同时处理多个请求和响应的能力。

通过多路复用的方式,网络资源可以更快加载。依据网站的结构,你也可以在多路复用的连接中,将资源区分优先级:在HTTP2中标记一些资源,比如像实时CSS这样具有高优先级的资源,可以使他们更快的加载出来。基于以上,当正确运用时,推送不再仅仅是请求而是可以通过 HTTP2 Server Push创建超级快感知体验性能的重要资源。稍后详述。

HTTP2 Waterfall demo on WebPagetest

当涉及加载时,多路复用有一个奇怪的特点:在感知性能方面某一种图片加载速度明显提高,因为初始图像信息可以通过HTTP2 多路复用的方式下载下来。渐进式 JPEG 和 交错 PNG都是利用了这一点。

优化所有的事物

Baseline sequential image loading example

Progressive JPEG image loading example

渐进式和交错图片就像是千层蛋糕:他们包含的不是从左上到右下的方式呈现图像的单个流的信息,而是作为层的堆叠,每一层会在上一层的运输的信息的基础上进行改善。

由于通过HTTP2 多路复用加载网站资源将同时启动所有的图片下载,渐进式图片和交错图片的初始轻量层的渲染速度比循序编码的图片的速度要快很多。循序编码图片以窗口方式呈现:逐行显示直到所有的图片信息传输完成。 John Mellor's SPDY test demo

这种通过HTTP2 多路复用传递渐进式JPEG的扫描图层来提高感知性能和速度指数的方式已经早在2012年被Google的John Mellor 注意到了。他一直在实验SPDY协议,HTTP2的前身。如今,我们在这个发现的基础上进行改进,让渐进式图片展现的更快:

收集起来力量!或扫描文件

Demo of 10 scan layers

逐行编码的JPEG图片默认包含是个图层。也就是说10个图片信息的迭代层建立在彼此之上,以实现最终的图片是视觉质量。渐进式JPEG的第一个视觉图层通常是高像素黑白的因为它节省了颜色通道信息。如果你想查看每一个图层的效果,使用Frédéric Kayser的“jsk”工具将一张渐进式JPEG分隔成独立的图层

为什么是10层呢?这是所有JPEG编码器的默认设置。在霍夫曼表的优化过程中,这是考虑到每层的比特大小,视觉质量和帮助JPEG解码器实现总尺寸更小的图片文件的兼容方案。

Default scan layers script

不像PNG图片会使用固定的方法叫做Adam7编码创建交错图层,我们可以使用自定义指令为JPEG编码器补充创建扫描层:“-scans”代表JPEG编码器。你可以像这样使用它:“cjpeg -quality 75 -scans customscans.txt -outfile output.jpg input.jpg”。现在,JPEG编码器就接收了包含图层创建自定义命令的文本文件

在图层文件里每一行定义一个新的图层。他们包含了颜色通道,矩阵指数和损耗多部分信息。

三个颜色通道分别是亮度(‘Y’),蓝色(‘Cb’)和红色(‘Cr’),它们在图像文件中的数字分别是0,1,2。在图像文件中矩阵指数变化范围从0到63,覆盖64个像素块。(JPEG编码具有原始的8×8块级设定。)

开始创建

Custom scan layers script

我们的目标是尽快显示有意义的图片内容,同时使浏览器能够快速布局。因此,为了尽可能大量增长的视觉质量,我们的初始扫描层应该是少而有意义的。

通常这里展示的扫描文件是确保第一个扫描层的适当颜色。在第二个扫描层,我们就可以拥有一个高度可接受的预览层了。三层和四层传递了必要的颜色信息:红色通道在蓝色通道之前,因为红色信息对于提高视觉效果如展示人脸,更加重要。在第四个图层之后,图像看上去就很完整了,最后的第五个图层提高的只是对精细高频细节有提高。这些改进体现在速度只是大约提高6%,反映了更好的感知性能。

WebPagetest results

Progressive JPEG image loading example

上面的扫描脚本只是一个常见的渐进式JPEG编码时的例子:使用同样的方式,你可以在渐进式JPEG图片中重新创建Guy Podjarny's LQIP 技术

推送!推送!推送!

HTTP2提供了另一个工具,可以让我们更加快速的传递图片信息:服务器推送。在支持启用HTTP2web服务中,标记渐进式JPEG的图像扫描层为高优先级,并且让服务推送这些扫描层到客户端浏览器的push缓存中即使是在开始对相应的图片请求之前成为了一种可能。

查阅在本年度关于性能日志到来的非常棒的一篇文章来发现更多关于HTTP2 服务推送。 WebPagetest results

Progressive JPEG image loading example

这种技术只在整体策略上使用:找到哪些图片对于在你的网站上创建用户体验至关重要,比如一个引人瞩目的英雄形象或者是一个产品预览图像,只要提供对这些JPEG图片的初始扫描层的服务推送。这样你就可以提高用户体验,从而在不损耗整体网站资源的下载的基础上,实现成功转化。

总结

  • 因为有了多路复用,多个渐进式图片或交错图像在HTTP2上渲染的更快

  • 控制渐进式JPEG的创建可以提供给用户更好的视觉体验

  • HTTP2 服务推送可以提高重要图片的感知性能

声明: 感谢 Corinna Baldauf 证明和编辑。感谢Colin BendellYoav Weiss 的想法和支持。

相关文章