![]()
性能黄金法则
- 网页加载时间80%耗费在html文档所引用的组件的请求和解析上
HTTP简介
- 超文本传输协议,客户端/服务器协议,规定了客户端、服务器之间的请求响应方式
- 请求由URL和请求头组成
- 响应由状态码、响应头和响应体组成
- 常用状态码
- 200: 成功
- 304: 缓存未改变
- 301: 永久重定向 //3xx表示用户代理必须执行进一步操作才能完成请求
- 302: 暂时重定向
- 404: 找不到网页
- 503: 服务器不可用
- 500: 服务器内部错误
// 请求
GET /assets/js/common.js
HTTP 1.1
Host: cnblogs.com
User-Agent: Mozilla/ 5.0
//响应
HTTP 1.1 200 OK
Content-Type: application/x-javascript
Last-Modified: Wed Mar 02 2016 21:32:34 GMT
Content-Length: 255
var ...
规则一:减少HTTP请求
<img usemap="map1" src="map.jpg">
<map>
<area shape="rect" coords="0, 0, 31, 31" href="home.html" title="Home">
<area shape="rect" coords="36, 0, 66, 31" href="gifts.html" title="Gifts">
</map>
<span style="background-image: url(); background-position: -260px -90px; width: 26px; height: 26px;"></span>
<img src="data:image/png;base64,iVAGRw0KGDCFGNSUhEUgACBBQAVGADCAIATYJ7ljmRGGAAGElEVQQIW2P4DwcMDAxAfBvMAhEQMYgcACEHG8ELxtbPACCCTElFTEVBQmGA" />
规则二:使用内容发布网络(CDN)
- 将组件Web服务器分散开
- 访问速度与客户端到服务器的距离有关
规则三:添加Expires头
// Expires头规定了被缓存的组件的到期时间
// 由于它使用了一个特定的时间,所以要求客户端和服务器时间完全同步
// HTTP1.1引用了Cache-Controll来弥补这一点
Expires: Thu Mar 03 2020 09:06:31 GMT
// Cache-Controll规定了被缓存组件的持续时间,被网站广泛使用
// 下面是taobao.com某一组件的响应头
// 不希望被缓存的组件,则设置max-age=0
Cache-Controll: max-age=7200,s-maxage=3600
- 条件GET请求:判断在本地缓存后被请求组件的版本是否有更新
没有添加Expire和Cache-Controll响应头的组件,它仍然会储存在浏览器的缓存中。在后续的请求中,浏览器会检查缓存并发现组建已经过期。为了提高效率,浏览器会向原始服务器发送一个条件GET请求。如果组建没有改变,原始服务器可以免于发送整个组件,而是发送一个很小的头,告诉浏览器可以使用其缓存的组件。
// 条件GET请求
If-Modified-Since:Wed, 16 Dec 2015 06:19:38 GMT
//服务器响应
Last-Modified:Wed, 16 Dec 2015 06:19:38 GMT
- 修订文件名:设置完Expire后,当需要进行组件更新时,要更改文件名(将版本号嵌入组件的文件名)来保证用户能获取组件的最新版本。
规则四:压缩组件
- 压缩通常能将响应的数据量减少70%,在10个被统计的主流网站中,7个压缩了其HTML文档和大部分的脚本和样式表
- Web服务器基于Accept-Encoding来检测是否对响应进行压缩
//请求
Accept-Encoding: gzip, deflate
//响应
Content-Encoding: gzip
- 压缩由服务器进行,而解压缩由浏览器来进行,通常对大于1K或2K的文件进行压缩。已经压缩的图片和pdf不要进行二次压缩,否则会占用服务器资源。
规则五:将样式表放在顶部
- 当把不需要即刻加载的样式表放在底部时,并没有如预想的那样提高加载速度,反而出现了白屏
- 因为在使用样式表时,页面逐步呈现会被阻止知道所有样式表,以防止出现无样式内容的闪烁
- 所以请遵循HTML规范,将样式表放在顶部
规则六:将脚本放在底部
- HTTP1.1建议浏览器从每台主机并行地下载两个组件
- 脚本的加载会阻塞其他组件的并行下载,因为浏览器认为脚本有可能会重写页面,或并行地下载脚本会引发执行顺序发生错误
- 所以将脚本放在页面顶部同样会导致白屏现象,因为整个页面的加载都被阻塞了
规则七:避免CSS表达式
规则八:使用外部Javascript和CSS
- 实际上,将JS和CSS都写在页面中,网页载入速度比较快
- 然而大部分情况下,html并不会被缓存在本地,所以当用户访问网站较为频繁时(也就是会重复用到本地缓存时),应当使用外部JS与CSS
规则九:减少DNS查找
- DNS(Domain Name Search)用于解析域名
- 使用Keep-Alive来保证DNS缓存,减少花在DNS查找的时间
- 使用更少的域名
规则十:精简Javascript
- 精简代码最流行的工具是:JSMin(老道开发的)
- 对JS和CSS代码进行压缩带来的性能提升远没有gzip带来的多
规则十一:避免重定向
// 包含重定向的响应
HTTP 1.1 301 Moved Permanently
Location: https://m.taobao.com/
Content-Type: text/html
- 重定向会增加请求次数,延缓网页响应
- 使用重定向的原因主要有跟踪网页流量、记录广告点击和建立易于记忆的URL
- 还有一种程序员比较常犯的错误:URL后面缺少斜杠(/)引起的重定向
- 跟踪网页流量:
- 将要访问的链接进行重定向包装,可以通过分析该中间地址的Web服务器日志来跟踪用户的进站和出站流量
- 其他方法:使用Referer日志跟踪流量来源;使用信标跟踪出站流量
规则十二:避免重复脚本
规则十三:配置ETag
规则十四:使Ajax可缓存
- Ajax(异步加载Javascript和XML)是DHTML(动态HTML)中的一项技术,客户端可以获取和显示用户请求的信息而不需重新加载页面
- Ajax核心技术是XMLHttpRequest,还有IFrame。(建议使用YUI Connection Manager进行Ajax开发)
- Ajax请求可以分为被动请求和主动请求,被动请求是为了将来的使用而预先发起的,主动请求是基于用户当前的操作发起的,所以用户可能需要等待响应
- 找出Web应用程序中的所有主动请求——使用Web抓包工具(IBM Page Detailer)
- 为Ajax请求添加缓存,可以提升用户体验。然而有可能破坏数据隐私性(有些数据不允许缓存)和不能及时更新数据。
- 数据安全性解决办法:使用安全通信协议,如安全套接字层(SSL)
- 及时更新数据的解决办法:将一个表示末次修改时间的时间戳嵌入到Ajax请求的查询字符串中