【web性能优化】雅虎军规

英文:

  1. Make Fewer HTTP Requests
  2. Use a Content Delivery Network (CDN)
  3. Add Expires or Cache-Control Header
  4. Gzip Components
  5. Put Stylesheets at Top
  6. Put Scripts at Bottom
  7. Avoid CSS Expressions
  8. Make JavaScript and CSS External
  9. Reduce DNS Lookups
  10. Minify JavaScript and CSS
  11. Avoid Redirects
  12. Remove Duplicate Scripts
  13. Configure ETags
  14. Make Ajax Cacheable
  15. Flush Buffer Early
  16. Use GET for Ajax Requests
  17. Postload Components
  18. Preload Components
  19. Reduce the Number of DOM Elements
  20. Split Components Across Domains
  21. Minimize Number of iframes
  22. Avoid 404s
  23. Reduce Cookie Size
  24. Use Cookie-Free Domains for Components
  25. Minimize DOM Access
  26. Develop Smart Event Handlers
  27. Choose <link> Over @import
  28. Avoid Filters
  29. Optimize Images
  30. Optimize CSS Sprites
  31. Do Not Scale Images in HTML
  32. Make favicon.ico Small and Cacheable
  33. Keep Components Under 25 KB
  34. Pack Components Into a Multipart Document
  35. Avoid Empty Image src

 

 中文:

内容部分

1.尽可能减小HTTP请求数

  80%的终端用户响应时间都花在了前端上,其中大部分时间都在下载页面上的各类组件:图片,样式表,脚本,Flash等等。减小组件数必然可以减小页面提交的HTTP请求数。这是让页面更快的关键。javascript

  减小页面组件数的一种方式是简化页面设计。但有没有一种方法能够在构建复杂的页面同时加快响应时间呢?嗯,确实有鱼和熊掌兼得的办法。php

  合并文件是经过把全部脚本放在一个文件中的方式来减小请求数的,固然,也能够合并全部的CSS。若是各个页面的脚本和样式不同的话,合并文件就是一项比较麻烦的工做了,但把这个做为站点发布过程的一部分确实能够提升响应时间。css

  CSS Sprites是减小图片请求数量的首选方式。把背景图片都整合到一张图片中,而后用CSS的background-imagebackground-position属性来定位要显示的部分。html

  图像映射能够把多张图片合并成单张图片,总大小是同样的,但减小了请求数并加速了页面加载。图片映射只有在图像在页面中连续的时候才有用,好比导航条。给image map设置坐标的过程既无聊又容易出错,用image map来作导航也不容易,因此不推荐用这种方式。前端

  行内图片(Base64编码)data: URL模式来把图片嵌入页面。这样会增长HTML文件的大小,把行内图片放在(缓存的)样式表中是个好办法,并且成功避免了页面变“重”。但目前主流浏览器并不能很好地支持行内图片。java

  减小页面的HTTP请求数是个起点,这是提高站点首次访问速度的重要指导原则。web

 

2.减小DNS查找

  域名系统创建了主机名和IP地址间的映射,就像电话簿上人名和号码的映射同样。当你在浏览器输入www.yahoo.com的时候,浏览器就会联系DNS解析器返回服务器的IP地址。DNS是有成本的,它须要20到120毫秒去查找给定主机名的IP地址。在DNS查找完成以前,浏览器没法从主机名下载任何东西。ajax

  DNS查找被缓存起来更高效,由用户的ISP(网络服务提供商)或者本地网络存在一个特殊的缓存服务器上,但还能够缓存在我的用户的计算机上。DNS信息被保存在操做系统的DNS cache(微软Windows上的”DNS客户端服务”)里。大多数浏览器有独立于操做系统的本身的cache。只要浏览器在本身的cache里还保留着这条记录,它就不会向操做系统查询DNS。数据库

  IE默认缓存DNS查找30分钟,写在DnsCacheTimeout注册表设置中。Firefox缓存1分钟,能够用network.dnsCacheExpiration配置项设置。(Fasterfox把缓存时间改为了1小时 P.S. Fasterfox是FF的一个提速插件)express

  若是客户端的DNS cache是空的(包括浏览器的和操做系统的),DNS查找数等于页面上不一样的主机名数,包括页面URL,图片,脚本文件,样式表,Flash对象等等组件中的主机名,减小不一样的主机名就能够减小DNS查找。

  减小不一样主机名的数量同时也减小了页面可以并行下载的组件数量,避免DNS查找削减了响应时间,而减小并行下载数量却增长了响应时间。个人原则是把组件分散在2到4个主机名下,这是同时减小DNS查找和容许高并发下载的折中方案。

 

3.避免重定向

重定向用301和302状态码,下面是一个有301状态码的HTTP头:

HTTP/1.1 301 Moved Permanently
      Location: http://example.com/newuri
      Content-Type: text/html

  浏览器会自动跳转到Location域指明的URL。重定向须要的全部信息都在HTTP头部,而响应体通常是空的。其实额外的HTTP头,好比ExpiresCache-Control也表示重定向。除此以外还有别的跳转方式:refresh元标签和JavaScript,但若是你必须得作重定向,最好用标准的3xxHTTP状态码,主要是为了让返回按钮能正常使用。

  牢记重定向会拖慢用户体验,在用户和HTML文档之间插入重定向会延迟页面上的全部东西,页面没法渲染,组件也没法开始下载,直到HTML文档被送达浏览器。

  有一种常见的极其浪费资源的重定向,并且web开发人员通常都意识不到这一点,就是URL尾部缺乏一个斜线的时候。例如,跳转到http://astrology.yahoo.com/astrology会返回一个重定向到http://astrology.yahoo.com/astrology/的301响应(注意添在尾部的斜线)。在Apache中能够用Aliasmod_rewrite或者DirectorySlash指令来取消没必要要的重定向。

  重定向最多见的用途是把旧站点链接到新的站点,还能够链接同一站点的不一样部分,针对用户的不一样状况(浏览器类型,用户账号类型等等)作一些处理。用重定向来链接两个网站是最简单的,只须要少许的额外代码。虽然在这些时候使用重定向减小了开发人员的开发复杂度,但下降了用户体验。一种替代方案是用Aliasmod_rewrite,前提是两个代码路径都在相同的服务器上。若是是由于域名变化而使用了重定向,就能够建立一条CNAME(建立一个指向另外一个域名的DNS记录做为别名)结合Alias或者mod_rewrite指令。

 

4.让Ajax可缓存

  Ajax的一个好处是能够给用户提供即时反馈,由于它可以从后台服务器异步请求信息。然而,用了Ajax就没法保证用户在等待异步JavaScript和XML响应返回期间不会很是无聊。在不少应用程序中,用户可以一直等待取决于如何使用Ajax。例如,在基于web的电子邮件客户端中,用户为了寻找符合他们搜索标准的邮件消息,将会保持对Ajax请求返回结果的关注。重要的是,要记得“异步”并不意味着“即时”。

  要提升性能,优化这些Ajax响应相当重要。最重要的提升Ajax性能的方法就是让响应变得可缓存,就像在添上Expires或者Cache-Control HTTP头中讨论的同样。下面适用于Ajax的其它规则:

  咱们一块儿看看例子,一个Web 2.0的电子邮件客户端用了Ajax来下载用户的通信录,以便实现自动完成功能。若是用户从上一次使用以后再没有修改过她的通信录,并且Ajax响应是可缓存的,有还没有过时的Expires或者Cache-Control HTTP头,那么以前的通信录就能够从缓存中读出。必须通知浏览器,应该继续使用以前缓存的通信录响应,仍是去请求一个新的。能够经过给通信录的Ajax URL里添加一个代表用户通信录最后修改时间的时间戳来实现,例如&t=1190241612。若是通信录从上一次下载以后再没有被修改过,时间戳不变,通信录就将从浏览器缓存中直接读出,从而避免一次额外的HTTP往返消耗。若是用户已经修改了通信录,时间戳也能够确保新的URL不会匹配缓存的响应,浏览器将请求新的通信录条目。

  即便Ajax响应是动态建立的,并且可能只适用于单用户,它们也能够被缓存,而这样会让你的Web 2.0应用更快。

 

5.延迟加载组件

  能够凑近看看页面并问本身:什么才是一开始渲染页面所必须的?其他内容均可以等会儿。

  JavaScript是分隔onload事件以前和以后的一个理想选择。例如,若是有JavaScript代码和支持拖放以及动画的库,这些均可以先等会儿,由于拖放元素是在页面最初渲染以后的。其它能够延迟加载的部分包括隐藏内容(在某个交互动做以后才出现的内容)和折叠的图片。

  工具可帮你减轻工做量:YUI Image Loader能够延迟加载折叠的图片,还有YUI Get utility是一种引入JS和CSS的简单方法。Yahoo!主页就是一个例子,能够打开Firebug的网络面板仔细看看。

  最好让性能目标符合其它web开发最佳实践,好比“渐进加强”。若是客户端支持JavaScript,能够提升用户体验,但必须确保页面在不支持JavaScript时也能正常工做。因此,在肯定页面运行正常以后,能够用一些延迟加载脚本加强它,以支持一些拖放和动画之类的华丽效果。 

6.预加载组件

  预加载可能看起来和延迟加载是相反的,但它其实有不一样的目标。经过预加载组件能够充分利用浏览器空闲的时间来请求未来会用到的组件(图片,样式和脚本)。用户访问下一页的时候,大部分组件都已经在缓存里了,因此在用户看来页面会加载得更快。

实际应用中有如下几种预加载的类型:

  • 无条件预加载——尽快开始加载,获取一些额外的组件。google.com就是一个sprite图片预加载的好例子,这个sprite图片并非google.com主页须要的,而是搜索结果页面上的内容。
  • 条件性预加载——根据用户操做猜想用户将要跳转到哪里并据此预加载。在search.yahoo.com的输入框里键入内容后,能够看到那些额外组件是怎样请求加载的。
  • 提早预加载——在推出新设计以前预加载。常常在从新设计以后会听到:“这个新网站不错,但比之前更慢了”,一部分缘由是用户访问先前的页面都是有旧缓存的,但新的倒是一种空缓存状态下的体验。能够经过在将要推出新设计以前预加载一些组件来减轻这种负面影响,老站能够利用浏览器空闲的时间来请求那些新站须要的图片和脚本。

 7.减小DOM元素的数量

  一个复杂的页面意味着要下载更多的字节,并且用JavaScript访问DOM也会更慢。举个例子,想要添加一个事件处理器的时候,循环遍历页面上的500个DOM元素和5000个DOM元素是有区别的。

  大量的DOM元素是一种征兆——页面上有些内容无关的标记须要清理。正在用嵌套表格来布局吗?仍是为了修复布局问题而添了一堆的<div>s?或许应该用更好的语义化标记。

YUI CSS utilities对布局有很大帮助:grids.css针对总体布局,fonts.css和reset.css能够用来去除浏览器的默认格式。这是个开始清理和思考标记的好机会,例如只在语义上有意义的时候使用<div>,而不是由于它可以渲染一个新行。

  DOM元素的数量很容易测试,只须要在Firebug的控制台里输入:

document.getElementsByTagName('*').length

 

  那么多少DOM元素才算是太多呢?能够参考其它相似的标记良好的页面,例如Yahoo!主页是一个至关繁忙的页面,但只有不到700个元素(HTML标签)。

 8.跨域分离组件

  分离组件能够最大化并行下载,但要确保只用不超过2-4个域,由于存在DNS查找的代价。例如,能够把HTML和动态内容部署在www.example.org,而把静态组件分离到static1.example.orgstatic2.example.org

9.尽可能少用iframe

  用iframe能够把一个HTML文档插入到父文档里,重要的是明白iframe是如何工做的并高效地使用它。

<iframe>的优势:

  • 引入缓慢的第三方内容,好比标志和广告
  • 安全沙箱
  • 并行下载脚本

<iframe>的缺点:

  • 代价高昂,即便是空白的iframe
  • 阻塞页面加载
  • 非语义

10.杜绝404

  HTTP请求代价高昂,彻底没有必要用一个HTTP请求去获取一个无用的响应(好比404 Not Found),只会拖慢用户体验而没有任何好处。

  有些站点用的是有帮助的404——“你的意思是xxx?”,这样作有利于用户体验,,但也浪费了服务器资源(好比数据库等等)。最糟糕的是连接到的外部JavaScript有错误并且结果是404。首先,这种下载将阻塞并行下载。其次,浏览器会试图解析404响应体,由于它是JavaScript代码,须要找出其中可用的部分。

css部分

11.避免使用CSS表达式

 

用CSS表达式动态设置CSS属性,是一种强大又危险的方式。从IE5开始支持,但从IE8起就不推荐使用了。例如,能够用CSS表达式把背景颜色设置成按小时交替的:

1
background-color : expression( (new Date()).getHours()% 2  "#B8D4FF"  "#F08A00"  );

12.选择<link>舍弃@import

  前面提到了一个最佳实践:为了实现逐步渲染,CSS应该放在顶部。

  在IE中用@import与在底部用<link>效果同样,因此最好不要用它。

13.避免使用滤镜

  IE专有的AlphaImageLoader滤镜能够用来修复IE7以前的版本中半透明PNG图片的问题。在图片加载过程当中,这个滤镜会阻塞渲染,卡住浏览器,还会增长内存消耗并且是被应用到每一个元素的,而不是每一个图片,因此会存在一大堆问题。

最好的方法是干脆不要用AlphaImageLoader,而优雅地降级到用在IE中支持性很好的PNG8图片来代替。若是非要用AlphaImageLoader,应该用下划线hack:_filter来避免影响IE7及更高版本的用户。

14.把样式表放在顶部

  在Yahoo!研究性能的时候,咱们发现把样式表放到文档的HEAD部分能让页面看起来加载地更快。这是由于把样式表放在head里能让页面逐步渲染。

  关注性能的前端工程师想让页面逐步渲染。也就是说,咱们想让浏览器尽快显示已有内容,这在页面上有一大堆内容或者用户网速很慢时显得尤其重要。给用户显示反馈(好比进度指标)的重要性已经被普遍研究过,而且被记录下来了。在咱们的例子中,HTML页面就是进度指标!当浏览器逐渐加载页面头部,导航条,顶部logo等等内容的时候,这些都被正在等待页面加载的用户看成反馈,可以提升总体用户体验。

js部分

15.去除重复脚本

  页面含有重复的脚本文件会影响性能,这可能和你想象的不同。在对美国前10大web站点的评审中,发现只有2个站点含有重复脚本。两个主要缘由增长了在单一页面中出现重复脚本的概率:团队大小和脚本数量。在这种状况下,重复脚本会建立没必要要的HTTP请求,执行无用的JavaScript代码,而影响页面性能。

  IE会产生没必要要的HTTP请求,而Firefox不会。在IE中,若是一个不可缓存的外部脚本被页面引入了两次,它会在页面加载时产生两个HTTP请求。即便脚本是可缓存的,在用户从新加载页面时也会产生额外的HTTP请求。

  除了产生没有意义的HTTP请求以外,屡次对脚本求值也会浪费时间。由于不管脚本是否可缓存,在Firefox和IE中都会执行冗余的JavaScript代码。

  避免不当心把相同脚本引入两次的一种方法就是在模版系统中实现脚本管理模块。典型的脚本引入方法就是在HTML页面中用SCRIPT标签:

 
1
< script  type="text/javascript" src="menu_1.0.17.js"></ script >
 

 

16.尽可能减小DOM访问

用JavaScript访问DOM元素是很慢的,因此,为了让页面反应更迅速,应该:

  • 缓存已访问过的元素的索引
  • 先“离线”更新节点,再把它们添到DOM树上
  • 避免用JavaScript修复布局问题

 

17.用智能的事件处理器

  有时候感受页面反映不够灵敏,是由于有太多频繁执行的事件处理器被添加到了DOM树的不一样元素上,这就是推荐使用事件委托的缘由。若是一个div里面有10个按钮,应该只给div容器添加一个事件处理器,而不是给每一个按钮都添加一个。事件可以冒泡,因此能够捕获事件并得知哪一个按钮是事件源。

 

18.把脚本放在底部

  脚本会阻塞并行下载,HTTP/1.1官方文档建议浏览器每一个主机名下并行下载的组件数不要超过两个,若是图片来自多个主机名,并行下载的数量就能够超过两个。若是脚本正在下载,浏览器就不开始任何其它下载任务,即便是在不一样主机名下的。

  有时候,并不容易把脚本移动到底部。举个例子,若是脚本是用document.write插入到页面内容中的,就没办法再往下移了。还可能存在做用域问题,在多数状况下,这些问题都是能够解决的。

  一个常见的建议是用推迟(deferred)脚本,有DEFER属性的脚本意味着不能含有document.write,而且提示浏览器告诉他们能够继续渲染。不幸的是,Firefox不支持DEFER属性。在IE中,脚本可能被推迟,但不尽如人意。若是脚本能够推迟,咱们就能够把它放到页面底部,页面就能够更快地载入。

javascript, css 

19.把JavaScript和CSS放到外面

  不少性能原则都是关于如何管理外部组件的,然而,在这些顾虑出现以前你应该问一个更基础的问题:应该把JavaScript和CSS放到外部文件中仍是直接写在页面里?

实际上,用外部文件可让页面更快,由于JavaScript和CSS文件会被缓存在浏览器。HTML文档中的行内JavaScript和CSS在每次请求该HTML文档的时候都会从新下载。这样作减小了所需的HTTP请求数,但增长了HTML文档的大小。另外一方面,若是JavaScript和CSS在外部文件中,而且已经被浏览器缓存起来了,那么咱们就成功地把HTML文档变小了,并且尚未增长HTTP请求数。

  

20.压缩JavaScript和CSS

  压缩具体来讲就是从代码中去除没必要要的字符以减小大小,从而提高加载速度。代码最小化就是去掉全部注释和没必要要的空白字符(空格,换行和tab)。在JavaScript中这样作可以提升响应性能,由于要下载的文件变小了。两个最经常使用的JavaScript代码压缩工具是JSMin和YUI Compressor,YUI compressor还能够压缩CSS。

  混淆是一种可选的源码优化措施,要比压缩更复杂,因此混淆过程也更容易产生bug。在对美国前十的网站调查中,压缩能够缩小21%,而混淆能缩小25%。虽然混淆的缩小程度更高,但比压缩风险更大。

  除了压缩外部脚本和样式,行内的<script><style>块也能够压缩。即便启用了gzip模块,先进行压缩也可以缩小5%或者更多的大小。JavaScript和CSS的用处愈来愈多,因此压缩代码会有不错的效果。

图片

21.优化图片

  • 尝试把GIF格式转换成PNG格式,看看是否节省空间。在全部的PNG图片上运行pngcrush(或者其它PNG优化工具)

22.优化CSS Sprite

  • 在Sprite图片中横向排列通常都比纵向排列的最终文件小
  • 组合Sprite图片中的类似颜色能够保持低色数,最理想的是256色如下PNG8格式
  • “对移动端友好”,不要在Sprite图片中留下太大的空隙。虽然不会在很大程度上影响图片文件的大小,但这样作能够节省用户代理把图片解压成像素映射时消耗的内存。100×100的图片是1万个像素,而1000×1000的图片就是100万个像素了。

23.不要用HTML缩放图片

  不要由于在HTML中能够设置宽高而使用本不须要的大图。若是须要

1
< img  width="100" height="100" src="mycat.jpg" alt="My Cat" />

  那么图片自己(mycat.jpg)应该是100x100px的,而不是去缩小500x500px的图片。

 

24.用小的可缓存的favicon.ico(P.S. 收藏夹图标)

  favicon.ico是放在服务器根目录的图片,它会带来一堆麻烦,由于即使你无论它,浏览器也会自动请求它,因此最好不要给一个404 Not Found响应。并且只要在同一个服务器上,每次请求它时都会发送cookie,此外这个图片还会干扰下载顺序,例如在IE中,当你在onload中请求额外组件时,将会先下载favicon。

因此为了缓解favicon.ico的缺点,应该确保:

    • 足够小,最好在1K如下
    • 设置合适的有效期HTTP头(之后若是想换的话就不能重命名了),把有效期设置为几个月后通常比较安全,能够经过检查当前favicon.ico的最后修改日期来确保变动能让浏览器知道。

 cookie

25.给Cookie减肥

  使用cookie的缘由有不少,好比受权和个性化。HTTP头中cookie信息在web服务器和浏览器之间交换。重要的是保证cookie尽量的小,以最小化对用户响应时间的影响。

  • 清除没必要要的cookie
  • 保证cookie尽量小,以最小化对用户响应时间的影响
  • 注意给cookie设置合适的域级别,以避免影响其它子域
  • 设置合适的有效期,更早的有效期或者none能够更快的删除cookie,提升用户响应时间

26.把组件放在不含cookie的域下

  当浏览器发送对静态图像的请求时,cookie也会一块儿发送,而服务器根本不须要这些cookie。因此它们只会形成没有意义的网络通讯量,应该确保对静态组件的请求不含cookie。能够建立一个子域,把全部的静态组件都部署在那儿。

  若是域名是www.example.org,能够把静态组件部署到static.example.org。然而,若是已经在顶级域example.org或者www.example.org设置了cookie,那么全部对static.example.org的请求都会含有这些cookie。这时候能够再买一个新域名,把全部的静态组件部署上去,并保持这个新域名不含cookie。Yahoo!用的是yimg.com,YouTube是ytimg.com,Amazon是images-amazon.com等等。

  把静态组件部署在不含cookie的域下还有一个好处是有些代理可能会拒绝缓存带cookie的组件。有一点须要注意:若是不知道应该用example.org仍是www.example.org做为主页,能够考虑一下cookie的影响。省略www的话,就只能把cookie写到*.example.org,因此由于性能缘由最好用www子域,而且把cookie写到这个子域下。

移动端 

27.保证全部组件都小于25K

 

  这个限制是由于iPhone不能缓存大于25K的组件,注意这里指的是未压缩的大小。这就是为何缩减内容自己也很重要,由于单纯的gzip可能不够。

 

28.把组件打包到一个复合文档里

 

  把各个组件打包成一个像有附件的电子邮件同样的复合文档里,能够用一个HTTP请求获取多个组件(记住一点:HTTP请求是代价高昂的)。用这种方式的时候,要先检查用户代理是否支持(iPhone就不支持)。

服务器

29.Gzip组件

  前端工程师能够想办法明显地缩短经过网络传输HTTP请求和响应的时间。毫无疑问,终端用户的带宽速度,网络服务商,对等交换点的距离等等,都是开发团队所没法控制的。但还有别的可以影响响应时间的因素,压缩能够经过减小HTTP响应的大小来缩短响应时间。

从HTTP/1.1开始,web客户端就有了支持压缩的Accept-Encoding HTTP请求头。

1
Accept-Encoding: gzip, deflate

  若是web服务器看到这个请求头,它就会用客户端列出的一种方式来压缩响应。web服务器经过Content-Encoding相应头来通知客户端。

1
Content-Encoding: gzip

  尽量多地用gzip压缩可以给页面减肥,这也是提高用户体验最简单的方法。

 

 

30.避免图片src属性为空

Image with empty string src属性是空字符串的图片很常见,主要以两种形式出现:

  1. straight HTML
    <img src=””>
  2. JavaScript
    var img = new Image();
    img.src = “”;

这两种形式都会引发相同的问题:浏览器会向服务器发送另外一个请求。

 

31.配置ETags

  实体标签(ETags),是服务器和浏览器用来决定浏览器缓存中组件与源服务器中的组件是否匹配的一种机制(“实体”也就是组件:图片,脚本,样式表等等)。添加ETags能够提供一种实体验证机制,比最后修改日期更加灵活。一个ETag是一个字符串,做为一个组件某一具体版本的惟一标识符。惟一的格式约束是字符串必须用引号括起来,源服务器用相应头中的ETag来指定组件的ETag:

1
2
3
4
HTTP/1.1 200 OK
       Last-Modified: Tue, 12 Dec 2006 03:03:59 GMT
       ETag: "10c24bc-4ab-457e1c1f"
       Content-Length: 12195

  而后,若是浏览器必须验证一个组件,它用If-None-Match请求头来把ETag传回源服务器。若是ETags匹配成功,会返回一个304状态码,这样就减小了12195个字节的响应体。

GET /i/yahoo.gif HTTP/1.1
      Host: us.yimg.com
      If-Modified-Since: Tue, 12 Dec 2006 03:03:59 GMT
      If-None-Match: "10c24bc-4ab-457e1c1f"
      HTTP/1.1 304 Not Modified

 

 

32.对Ajax用GET请求

  Yahoo!邮箱团队发现使用XMLHttpRequest时,浏览器的POST请求是经过一个两步的过程来实现的:先发送HTTP头,在发送数据。因此最好用GET请求,它只须要发送一个TCP报文(除非cookie特别多)。IE的URL长度最大值是2K,因此若是要发送的数据超过2K就没法使用GET了。

POST请求的一个有趣的反作用是实际上没有发送任何数据,就像GET请求同样。正如HTTP说明文档中描述的,GET请求是用来检索信息的。因此它的语义只是用GET请求来请求数据,而不是用来发送须要存储到服务器的数据。

 

 

33.尽早清空缓冲区

 当用户请求一个页面时,服务器须要用大约200到500毫秒来组装HTML页面,在这期间,浏览器闲等着数据到达。PHP中有一个flush()函数,容许给浏览器发送一部分已经准备完毕的HTML响应,以便浏览器能够在后台准备剩余部分的同时开始获取组件,好处主要体如今很忙的后台或者很“轻”的前端页面上(P.S. 也就是说,响应时耗主要在后台方面时最能体现优点)。

  较理想的清空缓冲区的位置是HEAD后面,由于HTML的HEAD部分一般更容易生成,而且容许引入任何CSS和JavaScript文件,这样就可让浏览器在后台还在处理的时候就开始并行获取组件。

例如:

 ... <!-- css, js -->
    </head>
    <?php flush(); ?>
    <body>
      ... <!-- content -->

 

34.使用CDN(内容分发网络

  用户与服务器的物理距离对响应时间也有影响。把内容部署在多个地理位置分散的服务器上能让用户更快地载入页面。但具体要怎么作呢?

  实现内容在地理位置上分散的第一步是:不要尝试去从新设计你的web应用程序来适应分布式结构。这取决于应用程序,改变结构可能包括一些让人望而生畏的任务,好比同步会话状态和跨服务器复制数据库事务(翻译可能不许确)。缩短用户和内容之间距离的提议可能被推迟,或者根本不可能经过,就是由于这个难题。

  记住终端用户80%到90%的响应时间都花在下载页面组件上了:图片,样式,脚本,Flash等等,这是业绩黄金法则。最好先分散静态内容,而不是一开始就从新设计应用程序结构。这不只可以大大减小响应时间,还更容易表现出CDN的功劳。

  内容分发网络(CDN)是一组分散在不一样地理位置的web服务器,用来给用户更高效地发送内容。典型地,选择用来发送内容的服务器是基于网络距离的衡量标准的。例如:选跳数(hop)最少的或者响应时间最快的服务器。

 

35.添上Expires或者Cache-Control HTTP头

这条规则有两个方面:

  • 对于静态组件:经过设置一个遥远的未来时间做为Expires来实现永不失效
  • 多余动态组件:用合适的Cache-ControlHTTP头来让浏览器进行条件性的请求

  网页设计愈来愈丰富,这意味着页面里有更多的脚本,图片和Flash。站点的新访客可能仍是不得不提交几个HTTP请求,但经过使用有效期能让组件变得可缓存,这避免了在接下来的浏览过程当中没必要要的HTTP请求。有效期HTTP头一般被用在图片上,但它们应该用在全部组件上,包括脚本、样式和Flash组件。

  浏览器(和代理)用缓存来减小HTTP请求的数目和大小,让页面可以更快加载。web服务器经过有效期HTTP响应头来告诉客户端,页面的各个组件应该被缓存多久。用一个遥远的未来时间作有效期,告诉浏览器这个响应在2010年4月15日前不会改变。

1
Expires: Thu, 15 Apr 2010 20:00:00 GMT

  

若是你用的是Apache服务器,用ExpiresDefault指令来设置相对于当前日期的有效期。下面的例子设置了从请求时间起10年的有效期:

ExpiresDefault "access plus 10 years"

 

 

 

相关资料:

相关文章
相关标签/搜索