Miloer の 闲言碎语

读书笔记:高性能网站建设指南(1)


图片来源于简书App

前言

关于雅虎的14条军规。

关于个人对前端性能优化的认识。

主要记载学习笔记。

读书也并不意味着照本宣科,大部分内容都是根据书中理解然后进行知识拓展,也多聊一聊自己对前端性能的理解,所以理解难免有错,如果有错误,希望不吝指正。

绪言

跟踪Web页面性能

我们首次访问网站时,缓存是空的。浏览器会解析HTML文档并下载网站需要的组件。用户需要大部分的时间来等待组件的下载,还有小部分时间解析HTML,脚本以及样式表上面。

性能黄金法则

我们访问页面时,只有10%-20%的最终用户的响应时间花在下载HTML文档上,其余的时间都是在下载页面所需的所有组件上。

这么看来,怎么减少这80%-90%的时间,是我们很重要的任务。

规则一:减少HTTP请求

随便打开一个门户网站,看看它们的网站都加载了多少的组件。
我记得最早的时候我写页面时,需要引入图片来做小图标,我把下载的图片都放入一个文件夹里,等用到那个时候就在需要引用的资源里引入这个图片。这样就增加了HTTP的请求。
书里对于我这种问题,提供了图片地图与雪碧图以及内联图片的解决方案。

图片地图

图片地图这种使用方法我是没用过的,我看了看代码,在定义图片地图上的位置坐标时,很容易出错,而且劳动力还很大,性价比不高。

官方提供的小例子,来对比使用该方法,和没有使用的时间对比。
图片地图demo。
我尝试了几次,在排除浏览器缓存的情况下,图片地图的响应时间还是优于没有使用的。在有缓存的情况下访问时间还是相差不多的。
我用浏览器在不同的网络环境测试了一下 3G(good)网络下,使用图片地图明显优于没有使用的。
可见在移动端,我们使用方法来解决问题还是很有必要的。

CSS Sprites

CSS雪碧图,这个方法大部分都还使用这种方法来解决问题。
将多个图片组合成一张图片,在页面中通过background-position来引用图片的偏移量。
我觉得种这方法使用起来还是优于图片地图的,最起码我觉得使用起来更方便。

我试了几次,和图片地图比起来,响应时间略微也是有一点优势的。
雪碧图demo

内联图片

很多网站也在用这种方法了,我也在用,如果你不知道这种方法的话,我猜你肯定看过 src=”data:imgage/gif;base64…”一长串的图片资源吧,我第一次看到时,感觉这个URL怎么这么长,然后就特意去查了一下。
我通常用这种方法和HTML5的localstorage联合起来,把不经常换的图片直接储存来客户端,下次访问时忽略加载时间。我曾经也听人说过使用这种方法在存图片时也比较方便。

我也看到书中介绍文件被缓存时有意外的收获。

补一个小知识点:关于浏览器加载CSS时,CSS的大小对页面性能是有影响的,也就是说在样式表里不建议这么写。
在这里我举个小例子,

1
margin:20px

其实Chrome在解析CSS时,会把margin:20px这个属性拆成4个属性的,但是为了减少CSS里的样式大小,但最后还是建议这么写。
所以可见CSS文件的大小还是对页面性能有及其重要的影响的。

内联图片demo

合并脚本和样式表

我们在学习工作中,经常会用到各种插件,各种样式表。
然后再页面中引入多个脚本插件,有自己写的,也有外部引入的。至少我记得我以前这样过的。
军规中阐述将这些单独的文件合并到一个文件中,可以减少HTTP请求数量并缩短最终的响应时间。
看了这个demo对比真的能感受到合并脚本和样式表的必要性。
合并脚本和样式表demo

现在webpack这么流行,解决这种问题真是让人舒服。

小结

这是军规的第一条,同时作者认为这是最重要的规则,因为遵守该规则可以同时改善首次浏览和后续浏览的网站响应时间。而首次访问页面时的响应时间决定着用户是放弃你的网站还是不停地进行回访。

规则二:使用内容发布网络

使用CDN(Content Delivery Network)。

CDN用于发布静态内容(图片,样式表,脚本,Flash。)
优势:缩短响应时间,缓和Web流量峰值的压力。
缺点:你的响应时间可能受到其他网站的影响。CDN服务提供商在其所有的客户之间共享Web服务器组。无法控制组件服务器所带来的特殊麻烦(修改HTTP响应头.)

书里给了2个demo就不贴地址了,demo里的CDN都是国外的,小伙伴们可以自己找免费的CDN测试一下。

但不要在本地测试(笑哭)。

规则三: 添加Expires头

我记得去年,去一个网站查东西,那个网站首页有一张挺大的图,我当时特意看了看响应时间,3S左右,搞的每次访问体验都不好。我想就是缓存没搞,最起码把图片压一压啊,这么大就仍上来。。。

在这条规则里,介绍了Expires头。
浏览器使用缓存来减少HTTP的请求数量,来减小HTTP的响应大小,从而提升访问速度。

1
Expires:Mon ,15 Apr 2024 20:00:00 GMT

如果一张图片返回了这个头,那么代表在这个时间内,浏览器会再后续的页面浏览中一直使用这张图片。

同时Expires也有一个的限制,它要求服务器和客户端的始终必须严格同步。

当然还有另外一种选择,HTTP1.1可以通过引入Cache-Control头使用max-age指令来指定组件应该缓存多久。
对于不支持HTTP1.1的浏览器可以通过mod_expirseApache模块可以让Expires可以像max-age一样来设置相对的缓存时间。

如果这两个指令同时出现,HTTP规定max-age指令将重写Expires头。

像我访问的那个网站,完全可以把图片放入缓存头里嘛,让用户多次访问时减少访问时间。
在这里补充一句,只有在用户已经访问过你的网站之后,长久的Expires头才会对页面浏览产生影响。

缓存的文件不限于图片,包括样式表,脚本都可以尽可能的缓存。

书的作者对美国的十大网站进行了调查:

5个网站使其大部分图片可缓存30天以上。
4个网站使其大部分样式表可缓存30天以上。
5个网站使其大部分脚本可缓存30天以上。

修订文件名

如过我们将组件配置为让浏览器代理缓存,我们又需要新的样式了?怎么办呢?
这个我想即使没设置缓存的同学也遇到过吧,微信浏览器~~。
最简单的方法就是改文件名的版本号了。

规则四:压缩组件

从规则名就能想象出来我们需要干什么,压缩组件不就是为了减少数据传输的大小,从而提升前端性能吗。

文中提到两种压缩格式gzip和deflate。推荐gzip的压缩格式。一:浏览器普遍支持;二:压缩效果相对更卓越。

不过我刚才乱看时,又发现了个SDCH,然后科普了一下,粘过来:

sdch是Shared Dictionary Compression over HTTP的缩写,即通过字典压缩算法对各个页面中相同的内容进行压缩,减少相同的内容的传输。如:一个网站中一般都是共同的头部和尾部,甚至一些侧边栏也是共同的。之前的方式每个页面打开的时候这些共同的信息都要重新加载,但使用SDCH压缩方式的话,那些共同的内容只用传输一次就可以了。

sdch主要分为3个部分:首次请求,下载字典,之后的请求。

gzip压缩是什么?
先把文件在服务器就行压缩,然后再进行传输文件,传输完毕后,浏览器会对文件进行解压缩。

文中主要讲述了配置方面,以及性能方面的对比,美国十大流行的网站使用情况。
放几个官方压缩的实例。

无压缩的实例.

压缩HTML的实例

压缩所有组件的实例

对比很明显,不是么?

(未完待续)