性能黄金法则:
只有10%~20%的最终用户响应时间花在了下载HTML文档上。其余的80%~90%时间花在了下载页面中的所有组件上。
Rule 1——减少HTTP请求(降低用户第一次访问网站时的响应时间):
- 图片地图:图片地图(Image Map)允许在一个图片上关联多个URL。目标URL的选择取决于用户单击了图片上的哪个位置。例如:下图使用图片地图后将原来的5个请求减少为1个请求。
缺点:1)在定义图片地图上的区域坐标时,如果采取手工的方式很难完成且容易出错,而且除了矩形几乎无法定义其他形状。2)图片必须是连续的。
- CSS Sprites:通过使用CSS的background-position属性,可以将HTML元素放置到背景图片中期望的位置上。不要求图片必须是连续的。此外,它的优点还在于降低了下载量。因为合并后的图片会比分离的图片的总和要小(因为降低了图片自身的开销,例如颜色表、格式信息等)。
如果需要在页面中为背景、按钮、导航栏、链接等提供大量图片,CSS Sprites绝对是一种优秀的解决方案。
- 内联图片:内联图片(Inline Image)可以通过使用data:URL模式在Web页面中包含图片并且无需任何额外的HTTP请求。但IE目前不支持这种方式。由于内联图片在跨越不同页面时不会被缓存,在这种情况下,聪明的做法是使用CSS并将内联图片作为背景。将该CSS规则放在外部样式表中,意味着数据可以缓存在样式表内部。
缺点:1)不受IE的支持。2)Base64编码会增加图片的大小,整体下载量会增加。
- 合并脚本和样式表:因为每个文件都需要一个额外的HTTP请求,所以将单独的文件合并到一个文件中,可以减少HTTP请求的数量并缩短最终用户响应时间。
ps:对响应时间影响最大的是页面中组件的数量。当缓存为空时,每个组件都会产生一个HTTP请求。学习的相关知识:get和post请求的区别。
Rule 2——使用内容发布网络(通过将HTTP响应拉近用户来减少响应时间): Rule3——添加Expires头(最大化的利用浏览器的缓存能力):
- 内容发布网络(CDN)是一组分布在多个不同地理位置的Web服务器,用于更加有效地向用户发布内容。CDN用于发布静态内容:如图片、脚本、样式表和Flash。
- 优势:
1)缩短响应时间。2)CDN服务包括备份、扩展存储能力和进行缓存。3)缓和Web流量峰值压力。
- 使用CDN服务提供商的缺点:
1)响应时间可能会受到其他网站的影响。
2)无法直接控制组件服务器。例如,修改HTTP响应头必须通过服务提供商来完成,而不是由自己的工作团队完成。
学习的相关知识:静态网页和动态网页的区别。
- Max-Age和mod_expires:Expires使用一个特定的时间,要求服务器和客户端的时钟严格同步。带有max-age的Cache-Control可以消除这一限制,max-age的单位是秒。对于不支持HTTP1.1的浏览器,仍需要提供Expires头。因此在抓包时可以看到两个响应头同时存在的情况。在两者都出现的情况下,HTTP规范规定max-age指令将重写Expires头。
mod_expires Apache模块可以令Expires头像max-age那样以相对的方式设定日期,通过Expires-Default指令完成。 使用ExpiresDefault设置Expires头是跨浏览器改善缓存的最佳解决方案。
- 合适添加长久Expires头的组件:脚本、样式表、Flash以及不怎么需要更新的图片。Html文件不应该使用长久的Expires头,因为它包含动态内容。
学习的相关知识:Cache策略的原理。Rule4——压缩组件(减小HTTP响应的大小)
- 压缩什么:HTML文档,脚本和样式表。图片和PDF不应该压缩,因为它们本来就已经压缩过了。试图对它们进行压缩只会浪费CPU资源,还有可能会增加文件大小。
- 代理缓存:当浏览器通过代理来发送请求时,代理缓存的响应会根据浏览器是否支持gzip,缓存压缩或未压缩的响应。当访问同一个url时,不支持gzip的浏览器可能从代理缓存中读取压缩后的响应。为了解决这一问题,需要在Web服务器的响应中添加Vary头,这将使得代理缓存响应的多个版本。
ps: 平衡压缩和代理支持的关键在于建设的网站类型~
Rule5——将样式表放在顶部(尽快显示网页内容,增强用户体验)
- 白屏(blank white screen):在浏览器和用户等待位于底部的样式表时,浏览器会延迟显示任何可视化组件,即所谓的白屏现象。出现白屏的场景:在新窗口中打开;重新加载;作为主页。
- 无样式内容闪烁(FOUC):页面在样式表下载解析之前,组件就已经逐步加载显示,当样式表解析完成后,已经显示的组件就要用新的样式进行绘制,这就导致所谓的无样式内容闪烁。出现FOUC的场景:单击链接;使用书签;键入URL。
- 为了避免出现白屏和FOUC,建议使用link标签将样式表放在文档head中。
学习的相关知识:样式表链接和嵌入的区别;link和@import的区别。Rule6——将脚本放在底部(提高下载的并行度,使页面可以逐步呈现)
- 并行下载:HTTP1.1规范建议浏览器从每个主机名并行地下载两个组件。因此如果一个Web页面平均地将其组件分别放在两个主机名下,整体响应时间可以减少大约一半。
特别注意: 在下载脚本时并行下载是被禁用的。脚本会阻塞其后面内容的呈现;会阻塞其后面组件的下载。 原因有二:
1)脚本可能使用document.write来修改页面内容,因此浏览器会等待,以确保页面能够恰当的布局。2)为了保证脚本能够按照正确的顺序执行。如果并行下载多个脚本,就无法保证响应是按照特定顺序到达浏览器的,如果脚本间存在依赖关系,不按顺序执行就会导致js错误。(一般将function的定义放在head中也是由于这个原因。)
- 延迟(Defferred)脚本:DEFER属性表明脚本不包含document.write,浏览器得到这一线索就可以继续进行呈现。但实际运用中还是会出现延迟现象。如果一个脚本可以延迟,那么它一定可以移到页面的底部。这是加速Web页面的最佳方式。
Rule7——避免CSS表达式(减少求值频率,减少页面加载时间)
- 两种避免CSS表达式的技术:
1)一次性表达式。
2)时间处理器。
学习的相关知识:CSS表达式。
Rule8——使用外部JavaScript和CSS(改善响应时间)
- 组件重用:
- 取内联&外置之长的两项技术:
1) 加载后下载:在主页加载完成后动态下载外部组件来实现(通过onload事件)。注意:JavaScript和CSS会被加载到页面中两次。
2) 动态内联:使用cookies做指示器,让服务器知道一个组件是否在浏览器的缓存中。这样,就可以在内联或是使用外部文件之间做出最佳的选择。
Rule9——减少DNS查找(减少响应时间)
- 影响DNS缓存的因素:
1)服务器可以表明记录可以被缓存多久——TTL值。该值告诉客户端可以对该记录缓存多久。2)浏览器设置自己的时间限制。3)HTTP协议中的Keep-Alive特性可以同时覆盖TTL和浏览器的时间限制。4)浏览器对缓存的DNS还有数量的限制。
- 通过使用Keep-Alive和较少的域名来减少DNS查找。
- 从代码中移除不必要的字符以减小其大小,从而改善加载时间的实践。
学习的相关知识:精简和混淆。
Rule11——避免重定向(重定向会使页面变慢)
- 常用的重定向类型状态码是301和302,301和302响应在实际中都不会被缓存,除非有附加的头如Cache-Control要求它这么做。此外通过设置HTML文档头中的meta refresh标签和js中的document.location 也可以实现重定向功能。
- 重定向的优点:1)使得连接两个网站变得简单。2)便于跟踪用户流量的流向。3)使URL更加美观并且易于记忆。
- 重定向的弊端:延迟整个HTML文档的传输,在用户和HTML文档之间插入重定向会延迟页面中的所有东西。
- 重定向的替代方案:1)使用Alias、mod_rewrite、DirectorySlash和直接链接代码来避免重定向。2)使用Referer日志和信标(beacon)来跟踪内部和出站流量。在跟踪弹出式广告的点击量时,信标是一种很好的方式。
- 重复脚本损伤性能的方式有两种:1)不必要的HTTP请求(IE)。2)执行js所浪费的时间。
- 避免重复脚本的方法:在模版系统中实现一个脚本管理模块。
Rule13——配置ETag(消除不必要的下载)
- ETag的优势:当组件必须通过最新修改日期之外的一些东西来进行验证时,ETag是一种强大的方法。
- ETag的弊端:当在多台服务器上寄宿网站的时候,使用默认的ETag会具有很高的负载、消耗大量的带宽,而且代理也不能有效的缓存内容(不同的Apache服务器inode不同,不同的IIS服务器ChangeNumber不太可能相同)。
Rule14——使Ajax可缓存
- Ajax请求分为主动请求和被动请求。改善主动请求的最重要方式是使响应可缓存。在缓存被动请求时,需要考虑到当前请求是否有必要进行缓存,同时,在缓存中必须体现出响应的个性化和动态本质(使用查询字符串参数)。
学习的相关知识:Ajax技术。