高性能网站:网络篇

性能黄金法则:只有10%~20%的最终用户响应时间花在了下载HTML文档上。其余的80%~90%时间花在了下载页面中的所有组件上。

通过网络层面去优化这80%~90%的下载组件时间,比优化代码带来的效果要好得多。实际操作也并不困难,你可以通过使用CDN、Keep-Alive、减少DNS查找、避免重定向和使用HTTP2来优化你的网站的网络访问。

1. CDN


CDN现在已经是网站开发的标配。大公司都是自建CDN,小公司则使用CDN服务提供商(如:七牛云、又拍云等)或者免费的CDN服务(如:BootCDN、360CDN等)。

CDN用于发布静态内容,如图片、脚本、样式表和Flash等。提供动态HTML页面会引入特殊的存储需求,如数据库连接、状态管理、验证、硬件和OS优化等。这些复杂性超越了CDN的能力范围。

2. 减少HTTP请求


最快的请求就是没有请求。减少HTTP请求,本质上就是减少组件的数量。对于绝大多数网站,组件就是JS文件CSS文件图片。你可以通过打包构建工具,把所有JS文件打包成一个文件,CSS打包成一个文件,这就大大减少了请求的数量(事实上,现在很多的SPA就是这么做的)。减少图片请求就是 CSS Sprite,将小图标和图片合并成一个文件,不仅图片总大小会减少,请求也大大减少了。

此外,使用SVG技术和内联图片也可以减少请求的数量。但是你必须清楚自己在做什么,因为SVG图片和内联图片是无法缓存的,所以只有在用到一次的场景下使用。此外,对于简单的图片样式和背景,你甚至可以直接用CSS3做出来(CSS3真的很强大,强大到超乎你的想象)。关于图片的优化,我会在《高性能网站:图片篇》做更加详细的介绍。

3. 减少DNS查找


我们知道,浏览器在单个域名下可以并发的请求数4~8个。不同浏览器可并发请求数量不同,并且HTTP/1.0和HTTP/1.1下同一浏览器可并发请求数也不同,但你必须知道,可以通过将资源分布在不同域名下,能够增加并发请求的数量

但是域名数量多了,响应的DNS查找时间也就上去了(尽管有DNS缓存)。一般来说,DNS查找时间在10ms~100ms之间。我的建议是将你的资源分别放到至少2个,但不要超过4个主机名下。这是在减少DNS查找和允许高度并行下载之间作出的很好的权衡。

简书的某个请求的DNS Lookup 时间

4. Keep-Alive


我们知道HTTP协议是底层是基于TCP协议,而建立TCP连接的三次握手和断开连接的四次挥手是非常消耗时间的。Web客户端经常会打开到同一个站点的连接。比如,一个Web页面上的大部分内嵌图片通常来自同一个Web站点,而且相当一部分指向其他对象的超链通常都指向同一个站点。因此,初始化了对某服务器HTTP请求的应用程序很可能会在不久的将来对那台服务器发起更多的请求(比如,获取在线图片)。这种性质被称为站点局部性(site locality)

Initial connection 花费了49.78ms

关于Keep-Alive的更多信息,你可以参阅《HTTP权威指南》的第4.5节“持久连接”。我在这里要告诉你的是,很多的CDN和Web服务器会默认帮你加上 Connection:keep-alive,所以你不必太担心如何操作。此外,通过使用Keep-Alive重用现有连接还可以避免重复的DNS查找。

5. 避免重定向


实现重定向可能有很多不同的原因,包括但不限于网站重新设计、跟踪流量、记录广告点击和易于记忆的URL,但是请记住,重定向会使你的页面变慢

来看一个重定向的例子,访问 http://toolbar.google.com 会发生302跳转,在响应主页面之前有3秒的时间用户将看不到页面。当然,因为我使用了代理所以才这么慢,但是你要记住,重定向确实会在响应实际页面之前拖慢网站的速度,应该避免。

http://toolbar.google.com

如果是为了跟踪流量,完全没必要使用重定向。你可以分析Web服务器日志来跟踪流量,或者使用信标(beacon),它是一个HTTP请求,其URL中包含有跟踪信息。跟踪信息可以从信标Web服务器的访问日志中提取出来。信标响应通常是一个 1px X 1px 的透明图片;不过204响应更为优秀,因为它更小、从来不会被缓存,而且绝对不会改变浏览器的状态。

6. HTTP/2


HTTP/2 是基于Google SPDY协议,它的设计目标是降低50%的页面加载时间。当下很多著名的互联网公司,例如百度、淘宝、UPYUN 都在自己的网站或 APP 中采用了 SPDY 系列协议(当前最新版本是 SPDY/3.1),因为它对性能的提升是显而易见的。主流的浏览器(谷歌、火狐、Opera)也都早已经支持 SPDY,它已经成为了工业标准,HTTP Working-Group 最终决定以 SPDY/2 为基础,开发 HTTP/2。

但是,HTTP/2 跟 SPDY 仍有不同的地方,主要是以下两点:

  • HTTP/2 支持明文 HTTP 传输,而 SPDY 强制使用 HTTPS
  • HTTP/2 消息头的压缩算法采用 HPACK,而非 SPDY 采用的 DELEFT

相比 HTTP/1.x,HTTP/2 在底层传输做了很大的改动和优化:

  • HTTP/2 采用二进制格式传输数据,而非 HTTP/1.x 的文本格式。二进制格式在协议的解析和优化扩展上带来更多的优势和可能。
  • HTTP/2 对消息头采用 HPACK 进行压缩传输,能够节省消息头占用的网络的流量。而 HTTP/1.x 每次请求,都会携带大量冗余头信息,浪费了很多带宽资源。头压缩能够很好的解决该问题。
  • 多路复用,直白的说就是所有的请求都是通过一个 TCP 连接并发完成。HTTP/1.x 虽然通过 pipeline 也能并发请求,但是多个请求之间的响应会被阻塞的,所以 pipeline 至今也没有被普及应用,而 HTTP/2 做到了真正的并发请求。同时,流还支持优先级和流量控制。
  • Server Push:服务端能够更快的把资源推送给客户端。例如服务端可以主动把 JS 和 CSS 文件推送给客户端,而不需要客户端解析 HTML 再发送这些请求。当客户端需要的时候,它已经在客户端了。

HTTP/2 主要是 HTTP/1.x 在底层传输机制上的完全重构,HTTP/2 是基本兼容 HTTP/1.x 的语义的(详细兼容性说明请戳 这里)。 Content-Type 仍然是 Content-Type,只不过它不再是文本传输了。

这些新特性真是好用到哭,任你穷尽奇技淫巧各种Hack,都比不上这历史性的变革,这才是现代互联网的协议。

下图是 caniuse.com 给出的HTTP/2的浏览器支持列表,在全球支持率达到77.44%,在中国只有 59.58%。你可以根据你网站访问用户浏览器分布来考虑是否使用HTTP/2。

参考资料


  1. 《高性能网站建设指南》——Steve Souders
  2. 《HTTP权威指南》——David Gourley,Brian Totty
  3. HTTP/2 新特性浅析

推荐阅读更多精彩内容