优化网站性能的35条规则

最新博客站点:欢迎来访javascript

1. 最小化HTTP请求次数php

       最终用户响应时间的80%用于前端。大部分时间都在下载页面中的全部组件:图像,样式表,脚本,Flash等。减小组件数量反过来减小了呈现页面所需的HTTP请求数量。这是更快页面的关键。css

  减小页面中组件数量的一种方法是简化页面设计。但有没有办法构建内容更丰富的页面,同时还能实现快速响应时间?如下是一些减小HTTP请求数量的技术,同时仍支持丰富的页面设计。html

  组合文件是一种经过将全部脚本组合到单个脚本中来减小HTTP请求数量的方法,而且相似地将全部CSS组合到单个样式表中。当脚本和样式表在不一样页面之间变化时,组合文件更具挑战性,但使这部分发布过程能够缩短响应时间。前端

  CSS Sprites是减小图像请求数量的首选方法。将背景图像合并为单个图像,并使用CSSbackground-imagebackground-position属性显示所需的图像片断。java

图像地图将多个图像组合成单个图像。总体大小大体相同,但减小HTTP请求的数量会加快页面的速度。图像映射仅在图像在页面中是连续的时才起做用,例如导航栏。定义图像映射的坐标多是乏味且容易出错的。使用图像地图进行导航也没法访问,所以不建议使用。node

  内联图像使用data:URL方案将图像数据嵌入实际页面中。这能够增长HTML文档的大小。将内嵌图像组合到(缓存的)样式表中是一种减小HTTP请求并避免增长页面大小的方法。并不是全部主流浏览器都支持内嵌图像。算法

  减小页面中HTTP请求的数量是能够开始的地方。这是提升首次访问者性能的最重要指南。正如Tenni Theurer的博客文章浏览器缓存使用 - 暴露!,您网站的每日访问者中有40-60%使用空缓存。让这些首次访问者快速访问页面是得到更好用户体验的关键。数据库

2. 使用内容分发网络(CDN)express

       用户与Web服务器的距离会对响应时间产生影响。在多个地理位置分散的服务器上部署内容将使您的页面从用户的角度加载更快。可是你应该从哪里开始呢?

做为实现地理位置分散的内容的第一步,请勿尝试从新设计Web应用程序以在分布式体系结构中工做。根据应用程序的不一样,更改体系结构可能包括使人生畏的任务,例如同步会话状态和跨服务器位置复制数据库事务。尝试缩短用户与您的内容之间的距离可能会延迟或永远不会经过此应用程序架构步骤。

  请记住,最终用户响应时间的80-90%用于下载页面中的全部组件:图像,样式表,脚本,Flash等。这是性能黄金规则而不是从从新设计应用程序架构的艰巨任务开始,最好先分散静态内容。这不只能够缩短响应时间,并且因为内容交付网络,它更容易实现。

  内容传送网络(CDN)是分布在多个位置的Web服务器的集合,以更有效地向用户传送内容。选择用于向特定用户传送内容的服务器一般基于网络邻近度的度量。例如,选择具备最少网络跳跃的服务器或具备最快响应时间的服务器。

  一些大型互联网公司拥有本身的CDN,但使用CDN服务提供商(如Akamai TechnologiesEdgeCastlevel3)具备成本效益对于初创公司和私人网站来讲,CDN服务的成本可能太高,但随着您的目标受众变得愈来愈大并变得更加全球化,CDN对于实现快速响应时间是必要的。在Yahoo!中,将静态内容从其应用程序Web服务器移动到CDN(如上所述的第三方以及Yahoo本身的CDN)的属性将最终用户响应时间提升了20%或更多。切换到CDN是一个相对容易的代码更改,将显著提升您的网站的速度。

3. 添加Expires或Cache-Control标头

这条规则有两个方面:

  • 对于静态组件:经过设置远期将来Expires标头实现“永不过时”策略
  • 对于动态组件:使用适当的Cache-Control标头来帮助浏览器处理条件请求

       网页设计愈来愈丰富,这意味着页面中有更多的脚本,样式表,图像和Flash。您的页面的首次访问者可能必须发出多个HTTP请求,但经过使用Expires标头,您可使这些组件可缓存。这能够避免后续页面查看中没必要要的HTTP请求。Expires头文件一般与图像一块儿使用,但它们应该用于全部组件,包括脚本,样式表和Flash组件。

浏览器(和代理)使用缓存来减小HTTP请求的数量和大小,从而加快网页加载速度。Web服务器使用HTTP响应中的Expires头来告诉客户端能够缓存组件多长时间。这是一个遥远的将来Expires标题,告诉浏览器这个响应在2010年4月15日以前不会过期。

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

       若是您的服务器是Apache,请使用ExpiresDefault指令设置相对于当前日期的到期日期。ExpiresDefault指令的这个示例将Expires日期设置为距请求时间10年。

ExpiresDefault "access plus 10 years"

       请记住,若是您使用远期的Expires标头,则必须在组件更改时更改组件的文件名。在Yahoo! 咱们常常将此步骤做为构建过程的一部分:版本号嵌入在组件的文件名中,例如,yahoo_2.0.6.js。

使用远期Expires标头仅在用户访问过您的网站后才会影响网页浏览量。当用户第一次访问您的站点而且浏览器的缓存为空时,它对HTTP请求的数量没有影响。所以,此性能改进的影响取决于用户使用已准备好的缓存命中您的页面的频率。(“已准备好的缓存”已包含页面中的全部组件。)咱们在Yahoo!上测量了这一点。并发现带有固定缓存的页面查看次数为75-85%。经过使用远期的Expires标头,您能够增长浏览器缓存的组件数量,并在后续页面视图中重复使用,而无需经过用户的Internet链接发送单个字节。

       4. 使用Gzip组件

       经过前端工程师作出的决策,能够显着减小在网络上传输HTTP请求和响应所需的时间。确实,最终用户的带宽速度,互联网服务提供商,与对等交换点的距离等都超出了开发团队的控制范围。可是还有其余变量会影响响应时间。压缩经过减小HTTP响应的大小来减小响应时间。

从HTTP / 1.1开始,Web客户端表示支持使用HTTP请求中的Accept-Encoding标头进行压缩。

Accept-Encoding:gzip,deflate

       若是Web服务器在请求中看到此标头,它可能会使用客户端列出的方法之一压缩响应。Web服务器经过响应中的Content-Encoding标头向Web客户端通知此状况。

Content-Encoding:gzip

       Gzip是目前最流行,最有效的压缩方法。它由GNU项目开发,并由RFC 1952标准化您可能会看到的惟一其余压缩格式是deflate,但效果较差且不太受欢迎。

       Gzipping一般将响应大小减小约70%。今天大约90%的互联网流量经过声称支持gzip的浏览器传播。若是你使用Apache,配置gzip的模块取决于你的版本:Apache 1.3使用mod_gzip而Apache 2.x使用mod_deflate

       浏览器和代理存在已知问题,这些问题可能致使浏览器指望的内容与压缩内容相关的内容不匹配。幸运的是,随着旧浏览器的使用逐渐减小,这些边缘状况正在逐渐减小。Apache模块经过自动添加适当的Vary响应头来提供帮助。

       服务器根据文件类型选择gzip的内容,但一般在他们决定压缩的内容方面受到限制。大多数网站都会gzip他们的HTML文档。gzip你的脚本和样式表也是值得的,但不少网站都错过了这个机会。实际上,压缩包括XML和JSON在内的任何文本响应都是值得的。不该对图像和PDF文件进行gzip压缩,由于它们已通过压缩。试图对它们进行gzip不只浪费CPU,并且可能会增长文件大小。

       尽量多地压缩文件类型是减轻页面重量和加速用户体验的简便方法。

       5. 将CSS样式表放在顶部

       在研究Yahoo!的性能时,咱们发现将样式表移动到文档HEAD会使页面看起来加载速度更快。这是由于将样式表放在HEAD中容许页面逐步呈现。

       关注性能的前端工程师但愿页面逐步加载; 也就是说,咱们但愿浏览器尽快显示它拥有的任何内容。这对于具备大量内容的页面和对较慢Internet链接的用户尤为重要。为用户提供视觉反馈(例如进度指示器)的重要性已获得很好的研究和记录在咱们的例子中,HTML页面是进度指示器!当浏览器逐步加载页面时,标题,导航栏,顶部的徽标等都做为等待页面的用户的视觉反馈。这改善了总体用户体验。

       将样式表放在文档底部附近的问题是它禁止在许多浏览器(包括Internet Explorer)中逐行渲染。这些浏览器会阻止渲染,以免在样式发生变化时重绘页面元素。用户查看空白页面时卡住了。

       HTML规范明确指出,样式表是被包括在网页的HEAD:“与A,[LINK]能够仅出如今一个文档的HEAD部分,尽管它可能出现任意次数”。这些替代品,空白的白色屏幕或无风格内容的闪光都是值得冒险的。最佳解决方案是遵循HTML规范并在文档HEAD中加载样式表。

       6. 将JavaScript脚本放在底部

       脚本引发的问题是它们阻止了并行下载。HTTP / 1.1规范建议的浏览器下载不超过两种组分在每主机名平行。若是您从多个主机名提供图像,则能够并行执行两次以上的下载。可是,在下载脚本时,即便在不一样的主机名上,浏览器也不会启动任何其余下载。

       在某些状况下,将脚本移到底部并不容易。例如,若是脚本用于document.write插入页面内容的一部分,则没法在页面中向下移动。可能还存在范围问题。在许多状况下,有办法解决这些问题。

       常常出现的另外一种建议是使用延迟脚本。DEFER属性代表该脚本不包含document.write,而且是浏览器能够继续呈现的线索。不幸的是,Firefox不支持该DEFER属性。在Internet Explorer中,脚本可能会延迟,但不是所需的。若是能够延迟脚本,也能够将其移动到页面底部。这将使您的网页加载速度更快。

       7. 避免使用CSS中的expressions

       CSS表达式是一种动态设置CSS属性的强大(且危险)方法。从版本5开始,它们在Internet Explorer中受支持,但从IE8开始不推荐使用例如,可使用CSS表达式将背景颜色设置为每小时交替:  

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

       如此处所示,该expression方法接受JavaScript表达式。CSS属性设置为评估JavaScript表达式的结果。expression其余浏览器会忽略该方法,所以在Internet Explorer中设置属性以在跨浏览器建立一致体验时很是有用。

       表达式的问题在于它们的评估频率高于大多数人的预期。它们不只在页面呈现和调整大小时进行评估,并且在页面滚动时甚至在用户将鼠标移动到页面上时进行评估。在CSS表达式中添加计数器可让咱们跟踪CSS表达式的计算时间和频率。在页面上移动鼠标能够轻松生成10,000多个评估。

       减小CSS表达式求值次数的一种方法是使用一次性表达式,其中第一次计算表达式时,它将style属性设置为显式值,这将替换CSS表达式。若是必须在页面的整个生命周期中动态设置样式属性,则使用事件处理程序而不是CSS表达式是另外一种方法。若是必须使用CSS表达式,请记住它们可能会被评估数千次,并可能影响页面的性能。

       8. 将JavaScript和CSS独立成外部文件

       其中许多性能规则都涉及外部组件的管理方式。可是,在出现这些考虑因素以前,您应该提出一个更基本的问题:JavaScript和CSS是否应该包含在外部文件中,仍是内嵌在页面中?

       在现实世界中使用外部文件一般会产生更快的页面,由于浏览器会缓存JavaScript和CSS文件。每次请求HTML文档时,都会下载HTML文档中内联的JavaScript和CSS。这减小了所需的HTTP请求数,但增长了HTML文档的大小。另外一方面,若是JavaScript和CSS位于浏览器缓存的外部文件中,则HTML文档的大小会减小,而不会增长HTTP请求的数量。

       所以,关键因素是外部JavaScript和CSS组件相对于请求的HTML文档数量的缓存频率。这个因素虽然难以量化,但可使用各类指标进行衡量。若是您站点上的用户每一个会话有多个页面查看,而且您的许多页面重复使用相同的脚本和样式表,则缓存的外部文件可能会带来更大的潜在好处。

       许多网站都处于这些指标的中间。对于这些站点,最佳解决方案一般是将JavaScript和CSS部署为外部文件。内联的惟一例外是主页,例如Yahoo!的首页My Yahoo! 每一个会话具备不多(可能只有一个)页面视图的主页可能会发现内联JavaScript和CSS会致使更快的最终用户响应时间。

       对于一般是许多页面视图中的第一个的首页,有一些技术能够利用内联提供的HTTP请求的减小,以及经过使用外部文件实现的缓存优点。其中一种技术是在首页中内联JavaScript和CSS,但在页面加载完成后动态下载外部文件。后续页面将引用应该已存在于浏览器缓存中的外部文件。

       9. 减小DNS查询

  域名系统(DNS)将主机名映射到IP地址,就像电话簿将人们的姓名映射到他们的电话号码同样。当您在浏览器中键入www.yahoo.com时,浏览器联系的DNS解析器将返回该服务器的IP地址。DNS有成本。DNS一般须要20-120毫秒才能查找给定主机名的IP地址。在DNS查找完成以前,浏览器没法今后主机名下载任何内容。

  缓存DNS查找以得到更好的性能。此缓存能够在由用户的ISP或局域网维护的特殊缓存服务器上进行,但在单个用户的计算机上也存在缓存。DNS信息保留在操做系统的DNS缓存中(Microsoft Windows上的“DNS客户端服务”)。大多数浏览器都有本身的缓存,与操做系统的缓存分开。只要浏览器将DNS记录保存在本身的缓存中,它就不会因操做系统请求记录而烦恼。

  默认状况下,Internet Explorer会将DNS查找缓存30分钟,具体 DnsCacheTimeout取决于注册表设置。Firefox将DNS查找缓存1分钟,由network.dnsCacheExpiration配置设置控制(Fasterfox将此更改成1小时。)

  当客户端的DNS缓存为空(对于浏览器和操做系统)时,DNS查找的数量等于网页中惟一主机名的数量。这包括页面的URL,图像,脚本文件,样式表,Flash对象等中使用的主机名。减小惟一主机名的数量可减小DNS查找的数量。

  减小惟一主机名的数量有可能减小页面中发生的并行下载量。避免DNS查找会缩短响应时间,但减小并行下载可能会缩短响应时间。个人准则是将这些组件分红至少两个但不超过四个主机名。这致使在减小DNS查找和容许高度并行下载之间的良好折衷。

       10. 压缩JavaScript和CSS(包括内联<script>和<style>)

  压缩是从代码中删除没必要要的字符以减少其大小从而改善加载时间的作法。压缩代码时,将删除全部注释,以及不须要的空格字符(空格,换行符和制表符)。在JavaScript的状况下,这改善了响应时间性能,由于下载文件的大小减少了。用于压缩JavaScript代码的两种流行工具是JSMinYUI Compressor。YUI压缩器也能够压缩CSS。

  混淆是能够应用于源代码的替代优化。它比压缩更复杂,所以更容易因混淆步骤自己而产生错误。在对美国十大顶级网站的调查中,压缩规模缩小了21%,而混淆缩小了25%。尽管混淆具备更高的大小缩减,但压缩JavaScript的风险较小。

  除了压缩外部脚本和样式以外,内联<script><style>块也能够而且也应该压缩。即便你gzip你的脚本和样式,压缩它们仍然会减少5%或更多的大小。随着JavaScript和CSS的使用和大小的增长,压缩代码所节省的成本也会增长。

       11. 避免重定向

  使用301和302状态代码完成重定向。如下是301响应中HTTP标头的示例:

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

  浏览器自动将用户带到该Location字段中指定的URL 。重定向所需的全部信息都在标题中。响应的主体一般是空的。尽管有其名称,但实际上不会缓存301或302响应,除非其余标题(例如ExpiresCache-Control表示它应该是)。元刷新标记和JavaScript是将用户定向到不一样URL的其余方法,但若是必须进行重定向,则首选技术是使用标准3xx HTTP状态代码,主要是为了确保后退按钮正常工做。

  要记住的主要事情是重定向会下降用户体验。在用户和HTML文档之间插入重定向会延迟页面中的全部内容,由于页面中的任何内容都没法呈现,而且在HTML文档到达以前不会开始下载任何组件。

  最浪费的重定向之一常常发生,Web开发人员一般不了解它。当URL中缺乏尾部斜杠(/)时会发生这种状况。例如,转到http://astrology.yahoo.com/astrology会产生301响应,其中包含重定向到http://astrology.yahoo.com/astrology/(注意添加的尾部斜杠)。若是您使用的是Apache处理程序,则能够使用Alias 或 mod_rewrite 或 DirectorySlash指令在Apache中修复此问题

  将旧网站链接到新网站是重定向的另外一种常见用途。其余包括链接网站的不一样部分并基于特定条件(浏览器类型,用户账户类型等)指导用户。使用重定向链接两个网站很简单,只须要不多的额外编码。虽然在这些状况下使用重定向会下降开发人员的复杂性,但会下降用户体验。使用重定向的替代方法包括使用Alias以及mod_rewrite两个代码路径是否托管在同一服务器上。若是域名更改是使用重定向的缘由,则另外一种方法是建立CNAME(建立从一个域名指向另外一个域名的别名的DNS记录)与Alias组合mod_rewrite

       12. 删除重复的脚本

  在一个页面中两次包含相同的JavaScript文件会损害性能。这并不像你想象的那么不寻常。对美国十大顶级网站的评论显示,其中两个网站包含重复的脚本。两个主要因素会增长脚本在单个网页中重复的概率:团队规模和脚本数量。当它发生时,重复的脚本会经过建立没必要要的HTTP请求和浪费的JavaScript执行来损害性能。

  没必要要的HTTP请求在Internet Explorer中发生,但在Firefox中不发生。在Internet Explorer中,若是外部脚本包含两次且不可缓存,则在页面加载期间会生成两个HTTP请求。即便脚本是可缓存的,当用户从新加载页面时也会发生额外的HTTP请求。

  除了生成浪费的HTTP请求以外,还浪费了屡次评估脚本的时间。不管脚本是否可缓存,这种冗余的JavaScript执行都会在Firefox和Internet Explorer中执行。

  避免意外包含相同脚本两次的一种方法是在模板系统中实现脚本管理模块。包含脚本的典型方法是在HTML页面中使用SCRIPT标记。

<script type =“text/javascript”src =“menu_1.0.17.js”> </script>

  PHP中的另外一种选择是建立一个名为insertScript的函数

<? php insertScript(“menu.js”)?>

  除了防止屡次插入相同的脚本以外,此函数还能够处理脚本的其余问题,例如依赖性检查和向脚本文件名添加版本号以支持远期的Expires头。

       13. 配置实体标记ETag

  实体标记(ETag)是Web服务器和浏览器用于肯定浏览器缓存中的组件是否与源服务器上的组件匹配的机制。(“实体”是另外一个词“组件”:图像,脚本,样式表等)。添加ETag以提供验证比上次修改日期更灵活的实体的机制。ETag是惟一标识组件的特定版本的字符串。惟一的格式约束是引用字符串。源服务器使用ETag响应头指定组件的ETag 

 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传递回原始服务器。若是ETag匹配,则返回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

  ETag的问题在于它们一般使用属性构建,这些属性使它们对托管站点的特定服务器是惟一的。当浏览器从一个服务器获取原始组件并稍后尝试在不一样服务器上验证该组件时,ETag将不匹配,这种状况在使用服务器集群处理请求的网站上很是常见。默认状况下,Apache和IIS都在ETag中嵌入数据,这大大下降了在具备多个服务器的网站上成功进行有效性测试的概率。

  Apache 1.3和2.x的ETag格式是inode-size-timestamp虽然给定文件能够跨多个服务器驻留在同一目录中,而且具备相同的文件大小,权限,时间戳等,但它的inode在服务器与下一个服务器之间是不一样的。

  IIS 5.0和6.0与ETag有相似的问题。IIS上ETag的格式是Filetimestamp:ChangeNumber。ChangeNumber是用于跟踪IIS配置更改的计数器。后面整个网站的全部IIS服务器ChangeNumber是相同这是不太可能的。

  最终结果是Apache和IIS生成的ETag对于彻底相同的组件从一台服务器到另外一台服务器不匹配。若是ETag不匹配,则用户不会收到ETag设计的小的,快速的304响应; 相反,他们将得到正常的200响应以及组件的全部数据。若是您只在一台服务器上托管您的网站,这不是问题。可是,若是您有多个服务器托管您的网站,而且您正在使用具备默认ETag配置的Apache或IIS,则您的用户正在变慢页面,您的服务器负载更高,您正在消耗更大的带宽,而且代理服务器没有有效地缓存您的内容。即便您的组件具备远期Expires标头,每当用户点击从新加载或刷新时,仍会发出条件GET请求。

  若是您没有利用ETag提供的灵活验证模型,最好只删除ETag。Last-Modified头验证基于对组件的时间戳。删除ETag会减小响应和后续请求中HTTP标头的大小。Microsoft支持文章介绍了如何删除ETag。在Apache中,只需将如下行添加到Apache配置文件便可:

FileETag none

       14. 使Ajax能够缓存

  Ajax的一个优势是它为用户提供即时反馈,由于它从后端Web服务器异步请求信息。可是,使用Ajax并不能保证用户不会在等待那些异步JavaScript和XML响应返回时大拇指。在许多应用程序中,用户是否保持等待取决于Ajax的使用方式。例如,在基于Web的电子邮件客户端中,用户将一直等待Ajax请求的结果,以查找符合其搜索条件的全部电子邮件。重要的是要记住“异步”并不意味着“瞬时”。

为了提升性能,优化这些Ajax响应很是重要。提升Ajax性能的最重要方法是使响应可缓存,如添加Expires或Cache-controll标头中所述其余一些规则也适用于Ajax:

  咱们来看一个例子。Web 2.0电子邮件客户端可能使用Ajax下载用户的通信簿以进行自动完成。若是用户自上次使用电子邮件Web应用程序以来未修改过她的地址簿,则能够从缓存中读取先前的地址簿响应,若是该Ajax响应可使用未来的Expires或Cache-Control标头进行缓存。必须通知浏览器什么时候使用先前缓存的地址簿响应而不是请求新的地址簿响应。这能够经过向地址簿Ajax URL添加时间戳来完成,该时间戳指示用户上次修改其地址簿的时间,例如,&t=1190241612若是自上次下载后地址簿还没有被修改,则时间戳将相同,而且将从浏览器的缓存中读取地址簿,从而消除额外的HTTP往返。若是用户修改了地址簿,则时间戳确保新URL与缓存的响应不匹配,浏览器将请求更新的地址簿条目。

  即便您的Ajax响应是动态建立的,而且可能仅适用于单个用户,它们仍然能够缓存。这样作可使您的Web 2.0应用程序更快。

       15. 尽早清除缓冲区

  当用户请求页面时,后端服务器可能须要200到500毫秒才能将HTML页面拼接在一块儿。在此期间,浏览器在等待数据到达时处于空闲状态。在PHP中,您有函数flush()。它容许您将部分准备好的HTML响应发送到浏览器,以便浏览器能够在后端忙于HTML页面的其他部分时开始获取组件。这种好处主要出如今繁忙的后端或轻量级前端。

  考虑刷新的好地方就在HEAD以后,由于头部的HTML一般更容易生成,而且它容许您包含任何CSS和JavaScript文件,以便浏览器在后端处理时并行地开始获取。

例:

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

  雅虎 搜索开创性研究和真实用户测试,以证实使用此技术的好处。

       16. 使用GET进行Ajax请求

  在雅虎 邮件团队发现,在使用时XMLHttpRequest,POST在浏览器中实现为两步过程:首先发送标头,而后发送数据。所以最好使用GET,它只须要一个TCP数据包发送(除非你有不少cookie)。IE中的最大URL长度为2K,所以若是发送的数据超过2K,则可能没法使用GET。

  一个有趣的反作用是没有实际发布任何数据的POST就像GET同样。根据HTTP规范,GET用于检索信息,所以当您仅请求数据时,使用GET是有意义的(语义上),而不是将数据发送到服务器端存储。

       17. 延迟加载组件

  您能够仔细查看您的页面并问本身:“页面最初渲染必要的是什么?”。其他的内容和组件能够等待。

  JavaScript是在onload事件以前和以后拆分的理想候选者。例如,若是您有执行拖放和动画的JavaScript代码和库,则能够等待,由于在初始渲染以后拖动页面上的元素。其余寻找后期加载候选者的地方包括隐藏内容(用户操做后显示的内容)和首屏下方的图像。

  帮助您完成工做的工具:YUI Image Loader容许您将图像延迟到折叠下方,YUI Get实用程序是一种简单的方法,能够动态地包含JS和CSS。在野外的例子看看雅虎!打开Firebug网络面板的主页

  当性能目标与其余Web开发最佳实践一致时,这是很好的。在这种状况下,渐进加强的想法告诉咱们,JavaScript在受支持时能够改善用户体验,但您必须确保即便没有JavaScript也能正常工做。所以,在确保页面正常工做以后,您可使用一些后期加载的脚原本加强它,这些脚本能够为您提供更多的花俏功能,例如拖放和动画。

       18. 预加载组件

  预加载可能看起来与延迟加载相反,但它实际上有不一样的目标。经过预加载组件,您能够利用浏览器空闲的时间并请求未来须要的组件(如图像,样式和脚本)。这样,当用户访问下一页时,您能够将大部分组件放在缓存中,而且您的页面将为用户加载更快。

  实际上有几种类型的预加载:

  • 无条件预加载 - 一旦onload触发,你就能够继续获取一些额外的组件。请访问google.com,了解如何请求加载精灵图片。google.com主页上不须要此精灵图片,但在连续搜索结果页面上须要此精灵图片。
  • 条件预加载 - 基于用户操做,您能够进行有根据的猜想,即用户前进的位置并相应地预加载。search.yahoo.com上,您能够看到在开始输入输入框后如何请求一些额外的组件。
  • 预期的预加载 - 在启动从新设计以前提早预加载。常常在从新设计以后听到:“新网站很酷,但比之前慢”。部分问题多是用户使用完整缓存访问旧网站,但新网站始终是空缓存体验。您能够经过在启动从新设计以前预加载某些组件来缓解此反作用。您的旧站点可使用浏览器空闲的时间并请求新站点将使用的图像和脚本

       19. 减小DOM元素的数量

  复杂页面意味着要下载更多字节,这也意味着JavaScript中的DOM访问速度更慢。例如,当您想要添加事件处理程序时,若是在页面上循环遍历500或5000个DOM元素,则会有所不一样。

  大量的DOM元素多是一种通症,即应该经过页面标记来改进,而没必要删除内容。您是否使用嵌套表进行布局?您是否只是为了解决布局问题而投入更多<div>也许有一种更好,语义更正确的标记方式。

  YUI CSS实用程序 提供了很好的布局帮助:grids.css能够帮助您完成总体布局,fonts.css和reset.css能够帮助您去除浏览器的默认格式。这是一个从新开始并考虑标记的机会,例如,<div>只有在语义上有意义时才使用s,而不是由于它呈现新行。

  DOM元素的数量很容易测试,只需键入Firebug的控制台:

document.getElementsByTagName('*').length

  那到底有多少DOM元素才算少?检查具备良好标记的其余相似页面。例如雅虎!主页是一个很是繁忙的页面,仍然不到700个元素(HTML标记)。

       20. 跨域拆分组件

  拆分组件容许您最大化并行下载。因为DNS查询惩罚,请确保您使用的域名不超过2-4个。例如,您能够托管HTML和动态内容,www.example.org 并在static1.example.org之间拆分静态组件static2.example.org

  有关更多信息,请查看Tenni Theurer和Patty Chi的“ 在Carpool Lane中最大化并行下载 ”。

       21. 最小化iframe数量

  iframe容许将HTML文档插入父文档中。了解iframe如何运做以便有效使用很是重要。

  <iframe> 优势:

  • 帮助缓慢的第三方内容,如徽章和广告
  • 安全沙箱
  • 并行下载脚本

  <iframe> 缺点:

  • 即便空白也要花钱
  • 阻止页面onload
  • 非语义

       22. 不用404s

  HTTP请求很昂贵,所以发出HTTP请求并得到无用的响应(即404 Not Found)是彻底不必的,而且会在没有任何好处的状况下减慢用户体验。

  有些网站有帮助404“你的意思是X?”,这对用户体验颇有好处,但也浪费了服务器资源(好比数据库等)。特别糟糕的是当外部JavaScript的连接错误而且结果是404时。首先,此下载将阻止并行下载。接下来,浏览器可能会尝试解析404响应主体,就像它是JavaScript代码同样,试图找到可用的东西。

       23. 减少Cookie大小

  HTTP cookie的使用有多种缘由,例如身份验证和个性化。有关cookie的信息在Web服务器和浏览器之间的HTTP标头中进行交换。保持cookie的大小尽量低是很是重要的,以尽可能减小对用户响应时间的影响。

  欲了解更多信息,请查看 Tenni Theurer和Patty Chi撰写的“当Cookie崩溃时”这项研究的主要内容:

  •   消除没必要要的cookie
  • 保持cookie大小尽量低,以尽可能减小对用户响应时间的影响
  • 请注意在适当的域级别设置cookie,以避免其余子域受到影响
  • 适当地设置过时日期。较早的Expires日期或者没有更早删除cookie,从而改善了用户响应时间

       24. 对组建使用cookie-free的域名

  当浏览器发出静态图像请求并将cookie与请求一块儿发送时,服务器对这些cookie没有任何用处。因此他们只是没有充分理由建立网络流量。您应该确保使用无cookie请求请求静态组件。建立一个子域并在那里托管全部静态组件。

  若是您的域名是www.example.org,您能够托管您的静态组件static.example.org可是,若是您已经在顶级域上设置了cookie example.org而不是www.example.org,则全部请求都 static.example.org将包含这些cookie。在这种状况下,您能够购买一个全新的域,在那里托管您的静态组件,并保持此域无cookie。雅虎 用途yimg.com,YouTube使用ytimg.com,亚马逊使用images-amazon.com等。

  在无cookie域上托管静态组件的另外一个好处是,某些代理可能拒绝缓存使用cookie请求的组件。在相关说明中,若是您想知道是否应该使用example.org或www.example.org做为主页,请考虑cookie的影响。省略www会让您别无选择,只能写入cookie *.example.org,所以出于性能缘由,最好使用www子域并将cookie写入该子域。

       25. 最小化DOM的访问次数

  使用JavaScript访问DOM元素的速度很慢,所以为了得到响应更快的页面,您应该:

  • 缓存对访问元素的引用
  • 更新节点“离线”,而后将它们添加到树中
  • 避免使用JavaScript修复布局

  有关更多信息,请查看 Julien Lecomte 的YUI影院的 “高性能Ajax应用程序”

       26. 开发巧妙的事件处理程序

  有时页面感受响应性较差,由于过多的事件处理程序附加到DOM树的不一样元素,而后执行得太频繁。这就是为何使用事件委托是一个很好的方法。若是a中有10个按钮div,则只将一个事件处理程序附加到div包装器,而不是每一个按钮一个处理程序。事件冒出来,这样你就能够捕捉事件并找出它来自哪一个按钮。

  您也不须要等待onload事件以便开始使用DOM树执行某些操做。一般,您只须要在树中访问要访问的元素。您没必要等待下载全部图像。DOMContentLoaded是您可能考虑使用的事件而不是onload,但在全部浏览器中均可用以前,您可使用具备方法YUI事件实用程序onAvailable

  有关更多信息,请查看 Julien Lecomte 的YUI影院的 “高性能Ajax应用程序”

       27. 优先选择使用<link>而非@import

  以前的最佳实践之一声明CSS应位于顶部以容许渐进式渲染。

  在IE中,@import行为与<link>在页面底部使用相同,所以最好不要使用它。

       28. 避免使用filters

  IE专有的AlphaImageLoader过滤器旨在解决IE版本<7中的半透明真彩色PNG的问题。该过滤器的问题在于它在下载图像时阻止渲染并冻结浏览器。它还会增长内存消耗,而且每一个元素应用,而不是每一个图像,所以问题成倍增长。

  最好的方法是AlphaImageLoader彻底避免使用优雅降级的PNG8,这在IE中很好。若是你绝对须要AlphaImageLoader,使用下划线黑客_filter不会惩罚你的IE7 +用户。

       29. 优化图片

  设计师完成为您的网页建立图像后,在将这些图像FTP到Web服务器以前,仍然能够尝试一些操做。

  • 您能够检查GIF并查看它们是否使用与图像中颜色数对应的调色板大小。使用imagemagick很容易检查 
  • identify -verbose image.gif 
  • 当你在调色板中看到使用4种颜色和256色“槽”的图像时,还有改进的余地。
  • 尝试将GIF转换为PNG并查看是否存在保存。一般,有。因为浏览器的支持有限,开发人员常常对使用PNG犹豫不决,但如今已成为过去。惟一真正的问题是真彩色PNG中的alpha透明度,可是GIF也不是真彩色,也不支持变量透明度。因此GIF能够作任何事情,调色板PNG(PNG8)也能够作(动画除外)。这个简单的imagemagick命令致使彻底安全的PNG:
  • convert image.gif image.png
  • “咱们所说的只是:给PiNG一个机会!”
  • 在全部PNG上 运行pngcrush(或任何其余PNG优化工具)。例: 
  • pngcrush image.png -rem alla -reduce -brute result.png
  • 在全部JPEG上运行jpegtran。此工具执行无损JPEG操做(如旋转),还可用于优化和删除图像中的注释和其余无用信息(如EXIF信息)。
  • jpegtran -copy none -optimize -perfect src.jpg dest.jpg

       30.优化CSS Sprites 

  • 将图像水平排列在精灵中而不是垂直排列一般会致使文件较小。
  • 在精灵中组合类似的颜色能够帮助您保持较低的颜色数,理想状况下在256色如下,以适应PNG8。
  • “适合移动设备”而且不要在精灵中留下大的间隙。这不会影响文件大小,但须要较少的内存,以便用户代理将图像解压缩为像素图。100x100图像是1万像素,其中1000x1000是100万像素

       31. 不要在HTML中缩放图像

  不要使用比您须要的更大的图像,由于您能够在HTML中设置宽度和高度。若是您须要,

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

  那么您的图像(mycat.jpg)应该是100x100px而不是缩小的500x500px图像。

       32. 减少favicon.ico的体积并缓存

  favicon.ico是一个保留在服务器根目录中的映像。这是一个必要的邪恶,由于即便你不关心它,浏览器仍然会请求它,因此最好不要回复404 Not Found此外,因为它位于同一台服务器上,所以每次请求时都会发送cookie。此图像也会干扰下载顺序,例如在IE中,当您在onload中请求额外组件时,将在这些额外组件以前下载favicon。

  所以,为了减轻拥有favicon.ico的缺点,请确保:

  • 它很小,最好不到1K。
  • 使用您感受温馨的设置Expires标头(由于若是您决定更改它,则没法重命名)。您能够在未来几个月安全地设置Expires标头。您能够查看当前favicon.ico的上次修改日期,以作出明智的决定。

Imagemagick能够帮助您建立小的favicons

       33. 保持组件小于25K

  此限制与iPhone不会缓存大于25K的组件这一事实有关。请注意,这是未压缩的大小。这是缩小很重要的地方,由于单独使用gzip可能还不够。

欲了解更多信息,请查看Wayne Shea和Tenni Theurer的“ 性能研究,第5部分:iPhone可缓存性 - 让它坚持下去 ”。

       34. 将组件拆分到多个文档中

  将组件打包到多部分文档就像带有附件的电子邮件,它能够帮助您经过一个HTTP请求获取多个组件(请记住:HTTP请求很昂贵)。使用此技术时,首先检查用户代理是否支持它(iPhone不支持)。

       35. 避免设置空图像的src

  带有空字符串src属性的图像会出现多个预期。它以两种形式出现:

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

  两种形式都会产生相同的效果:浏览器向您的服务器发出另外一个请求

  • Internet Explorer向页面所在的目录发出请求。
  • Safari和Chrome会向实际页面提出请求。
  • Firefox 3及更早版本的行为与Safari和Chrome相同,但3.5版解决了此问题[错误444931],再也不发送请求。
  • 遇到空图像时,Opera不执行任何操做。

  为何这种行为很差?

  1. 经过发送大量意外流量来削弱您的服务器,特别是对于天天得到数百万页面浏览量的页面。
  2. 废弃服务器计算周期生成永远不会被查看的页面。
  3. 可能会损坏用户数据。若是您经过cookie或其余方式跟踪请求中的状态,则可能会破坏数据。即便图像请求未返回图像,浏览器也会读取并接受全部标头,包括全部cookie。虽然其他的响应被丢弃,但可能已经形成了损害。

  此行为的根本缘由是在浏览器中执行URI解析的方式。此行为在RFC 3986 - 统一资源标识符中定义。当遇到空字符串做为URI时,它被视为相对URI,并根据5.2节中定义的算法进行解析。这个具体的例子是一个空字符串,在5.4节中列出。Firefox,Safari和Chrome都按照规范正确解析空字符串,而Internet Explorer正在解析它,显然符合规范的早期版本RFC 2396 - 统一资源标识符(这已被RFC 3986废弃) 。从技术上讲,浏览器正在作他们应该作的事情来解析相对URI。问题是在这种状况下,

HTML5添加了标记的src属性的描述,以指示浏览器不要在4.8.2节中提出额外的请求:

src属性必须存在,而且必须包含引用非交互式(可选动画)图像资源的有效URL,该资源既不是分页也不是脚本。若是元素的基URI与文档的地址相同,则src属性的值不能是空字符串。

  但愿浏览器未来不会出现这个问题。不幸的是,<script src =“”>和<link href =“”>没有这样的子句。也许还有时间进行调整以确保浏览器不会意外地实现此行为。

  这条规则的灵感来自雅虎的JavaScript大师Nicolas C. Zakas。有关更多信息,请查看他的文章“ Empty image src can destroy your site ”。

 

英文连接:

相关文章
相关标签/搜索