performance-column
performance-column copied to clipboard
雅虎 35 条军规
原文: Best Practices for Speeding Up Your Web Site 译文:雅虎前端优化35条规则翻译 译者:@creeperyang
如何让web页面更快,雅虎团队实践总结了7类35条规则,下面一一列出。
1. Content
1.1 Make Fewer HTTP Requests
Minimize HTTP Requests减少/最小化 http 请求数。
到终端用户的响应时间80%花在前端:大部分用于下载组件(js/css/image/flash等等)。减少组件数就是减少渲染页面所需的http请求数。这是更快页面的关键。
减少组件数的一个方法就是简化页面设计。保持富内容的页面且能减少http请求,有以下几个技术:
- Combined files。合并文件,如合并js,合并css都能减少请求数。如果页面间脚本和样式差异很大,合并会更具挑战性。
- CSS Sprites。雪碧图可以合并多个背景图片,通过background-image 和 background-position 来显示不同部分。
- Image maps。合并多个图片到一个图片,一般用于如导航条。由于定义坐标的枯燥和易错,一般_不推荐_。
- Inline images。使用data:url scheme来內连图片。
减少请求数是为第一次访问页面的用户提高性能的最重要的指导。
1.2 Reduce DNS Lookups
减少DNS查询。
就像电话簿,你在浏览器地址栏输入网址,通过DNS查询得到网站真实IP。
DNS查询被缓存来提高性能。这种缓存可能发生在特定的缓存服务器(ISP/local area network维护),或者用户的计算机。DNS信息留存在操作系统DNS缓存中(在windows中就是 DNS Client Serve )。大多浏览器有自己的缓存,独立于操作系统缓存。只要浏览器在自己的缓存里有某条DNS记录,它就不会向操作系统发DNS解析请求。
IE默认缓存DNS记录30分钟,FireFox默认缓存1分钟。
当客户端的DNS缓存是空的,DNS查找次数等于页面中的唯一域名数。
减少DNS请求数可能会减少并行下载数。避免DNS查找减少响应时间,但减少并行下载数可能会增加响应时间。指导原则是组件可以分散在至少2个但不多于4个的不同域名。这是两者的妥协。
1.3 Avoid Redirects
避免跳转。
跳转用301或302状态码来达成。一个301响应http头的例子:
HTTP/1.1 301 Moved Permanently
Location: http://example.com/newuri
Content-Type: text/html
浏览器自动跳转到Location指定的路径。跳转所需的所有信息都在http头,所以http主体一般是空的。301302响应一般不会被缓存,除非有额外的头部信息,比如Expires或Cache-Control指定要缓存。meta刷新标签或 JavaScript 也可以跳转,但如果真要跳转,3xx跳转更好,主要是保证返回键可用。
跳转显然拖慢响应速度。在跳转的页面被获取前浏览器没什么能渲染,没什么组件能下载。
最浪费的跳转之一发生在url尾部slash(/)缺失。比如http://astrology.yahoo.com/astrology会301跳转到http://astrology.yahoo.com/astrology/。这可以被Apache等服务器修复,用Alias,mod_rewrite等等。
1.4 Make Ajax Cacheable
让Ajax可缓存。
使用ajax的好处是可以向用户提供很快的反馈,因为它是向后台异步请求数据。但是,这些异步请求不保证用户等待的时间——异步不意味着瞬时。
提高ajax性能的最重要的方法是让响应被缓存,即在Add an Expires or a Cache-Control Header中讨论的 Expires 。其它方法是:
- gzip组件
- 减少DNS查找
- 压缩JS
- 避免跳转
- 设置ETags
1.5 Post-load Components
延迟加载组件。
再看看你的页面然后问问自己,“什么是页面初始化必须的?”。剩下的内容和组件可以延迟。
JavaScript是理想的(延迟)候选者,可以切分到onload事件之前和之后。比如拖放的js库可以延迟,因为拖动必须在页面初始化之后。其它可延迟的包括隐藏的内容,折叠起来的图片等等。
1.6 Preload Components
预加载组件。
预加载看起来与延迟加载相反,但它的确有个不同的目标。通过预加载你可以利用浏览器的空闲时间来请求你将来会用到的组件。这样当用户访问下一个页面时,你会有更多的组件已经在缓存中,这样会极大加快页面加载。
有几种预加载类型:
- 无条件预加载:一旦onload触发,你立即获取另外的组件。比如谷歌会在主页这样加载搜索结果页面用到的雪碧图。
- 有条件预加载:基于用户动作,你推测用户下一步会去哪里并加载相应组件。
- 预期的预加载:在发布重新设计(的网站)前提前加载。在旧网页预加载新网页的部分组件,那么切换到新网页时就不会是没有任何缓存了。
1.7 Reduce the Number of DOM Elements
减少dom数。
一个复杂的页面意味着更多的内容要下载,以及更慢的dom访问。比如在有500dom数量的页面添加事件处理就和有5000dom数量的不同。
如果你的页面dom元素很多,那么意味着你可能需要删除无用的内容和标签来优化。
1.8 Split Components Across Domains
把组件分散到不同的域名。
把组件分散到不同的域名允许你最大化并行下载数。由于DNS查询的副作用,最佳的不同域名数是2-4。
1.9 Minimize the Number of iframes
最小化iframe的数量。
iframe允许html文档被插入到父文档。