今天看到一篇不错的web优化文章,但是全英文的博主翻译后放到这里,博主英语
不是很好,有问题请大家及时指出。

最小化 HTTP 请求

标签:内容

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

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

组合文件 是一种通过将所有脚本组合到一个脚本中来减少 HTTP 请求数量的方法,类似地,将所有 CSS 组合到一个样式表中。当脚本和样式表因页面而异时,合并文件更具挑战性,但将这部分作为发布过程的一部分可以缩短响应时间。

CSS Sprites 是减少图像请求数量的首选方法。将您的背景图像组合成单个图像,并使用 CSSbackground-image和background-position属性来显示所需的图像片段。

图像映射 将多个图像组合成一个图像。整体大小大致相同,但减少 HTTP 请求的数量会加快页面速度。图像映射仅在页面中图像连续时才有效,例如导航栏。定义图像地图的坐标可能既乏味又容易出错。使用图像地图进行导航也是不可访问的,因此不推荐使用。

内嵌图像 使用data:URL 方案将图像数据嵌入到实际页面中。这会增加 HTML 文档的大小。将内嵌图像合并到(缓存的)样式表中是一种减少 HTTP 请求并避免增加页面大小的方法。所有主要浏览器尚不支持内嵌图像。

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

使用内容交付网络

标签:服务器

用户靠近您的 Web 服务器会影响响应时间。从用户的角度来看,跨多个地理位置分散的服务器部署您的内容将使您的页面加载速度更快。但是你应该从哪里开始呢?

作为实现地理上分散的内容的第一步,不要试图重新设计您的 Web 应用程序以在分布式架构中工作。根据应用程序,更改架构可能包括艰巨的任务,例如同步会话状态和跨服务器位置复制数据库事务。尝试缩短用户与您的内容之间的距离可能会被此应用程序架构步骤延迟或永远无法通过。

请记住,最终用户响应时间的 80-90% 用于下载页面中的所有组件:图像、样式表、脚本、Flash 等。这是性能黄金法则。与其从重新设计应用程序架构的艰巨任务开始,不如先分散静态内容。这不仅大大缩短了响应时间,而且由于内容交付网络的存在而变得更加容易。

内容分发网络 (CDN) 是一组分布在多个位置的 Web 服务器,可更有效地向用户提供内容。选择用于向特定用户传送内容的服务器通常基于网络接近度的度量。例如,选择网络跳数最少的服务器或响应时间最快的服务器。

一些大型互联网公司拥有自己的 CDN,但使用 CDN 服务提供商是划算的,例如Akamai Technologies、EdgeCast或level3。对于初创公司和私人网站,CDN 服务的成本可能高得令人望而却步,但随着您的目标受众越来越大并变得更加全球化,CDN 是实现快速响应时间所必需的。在 Yahoo!,将静态内容从其应用程序 Web 服务器移至 CDN(上述第 3 方以及 Yahoo 自己的CDN)的属性将最终用户响应时间缩短了 20% 或更多。切换到 CDN 是一个相对容易的代码更改,它将显着提高您网站的速度。

添加 Expires 或 Cache-Control 标头

标签:服务器

这个规则有两个方面:

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

网页设计越来越丰富,这意味着页面中的脚本、样式表、图像和 Flash 越来越多。页面的首次访问者可能需要发出多个 HTTP 请求,但通过使用 Expires 标头,您可以使这些组件可缓存。这避免了对后续页面视图的不必要的 HTTP 请求。Expires 标头最常用于图像,但它们应该用于所有组件,包括脚本、样式表和 Flash 组件。

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

  到期时间:2010 年 4 月 15 日星期四 20:00:00 GMT

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

  ExpiresDefault“访问加10年”

请记住,如果您使用未来的 Expires 标头,您必须在组件更改时更改组件的文件名。在雅虎!我们经常将这一步作为构建过程的一部分:在组件的文件名中嵌入一个版本号,例如,yahoo_2.0.6.js。

只有在用户访问过您的网站后,使用远期的 Expires 标头才会影响页面浏览量。当用户第一次访问您的站点并且浏览器的缓存为空时,它对 HTTP 请求的数量没有影响。因此,这种性能改进的影响取决于用户使用准备好的缓存访问您的页面的频率。(“准备好的缓存”已经包含页面中的所有组件。)我们在 Yahoo! 中对此进行了测量!并发现使用 Primed 缓存的页面浏览量是 75-85%。通过使用远期的 Expires 标头,您可以增加浏览器缓存并在后续页面视图中重新使用的组件数量,而无需通过用户的 Internet 连接发送一个字节。**

Gzip 组件

标签:服务器

通过前端工程师做出的决定,可以显着减少通过网络传输 HTTP 请求和响应所需的时间。确实,最终用户的带宽速度、Internet 服务提供商、与对等交换点的接近程度等超出了开发团队的控制范围。但是还有其他变量会影响响应时间。压缩通过减少 HTTP 响应的大小来减少响应时间。

从 HTTP/1.1 开始,Web 客户端通过 HTTP 请求中的 Accept-Encoding 标头指示支持压缩。

  接受编码:gzip、deflate

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

  内容编码:gzip

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

Gzipping 通常会将响应大小减少约 70%。当今大约 90% 的 Internet 流量通过声称支持 gzip 的浏览器传输。如果您使用 Apache,配置 gzip 的模块取决于您的版本:Apache 1.3 使用mod_gzip而 Apache 2.x 使用mod_deflate。

浏览器和代理存在一些已知问题,这些问题可能会导致浏览器期望的内容与其接收的压缩内容不匹配。幸运的是,随着旧浏览器的使用减少,这些边缘情况正在减少。Apache 模块通过自动添加适当的 Vary 响应头来提供帮助。

服务器根据文件类型选择要 gzip 的内容,但通常他们决定压缩的内容太有限。大多数网站 gzip 其 HTML 文档。对脚本和样式表进行 gzip 压缩也是值得的,但许多网站都错过了这个机会。事实上,压缩包括 XML 和 JSON 在内的任何文本响应都是值得的。图像和 PDF 文件不应被压缩,因为它们已经被压缩。尝试对它们进行 gzip 不仅会浪费 CPU,而且可能会增加文件大小。

Gzip 压缩尽可能多的文件类型是一种减轻页面重量和加速用户体验的简单方法。

将样式表放在顶部

标签: css

虽然研究在雅虎的表现!我们发现,移动样式表文件HEAD使页面看起来是加载速度更快。这是因为将样式表放在 HEAD 中可以让页面逐步呈现。

关心性能的前端工程师希望页面逐步加载;也就是说,我们希望浏览器尽快显示它所拥有的任何内容。这对于包含大量内容的页面和 Internet 连接速度较慢的用户尤其重要。向用户提供视觉反馈(例如进度指示器)的重要性已得到充分研究和记录。在我们的例子中,HTML 页面是进度指示器!当浏览器逐步加载页面时,标题、导航栏、顶部的标志等都作为等待页面的用户的视觉反馈。这改善了整体用户体验。

将样式表放在文档底部附近的问题在于它禁止在许多浏览器(包括 Internet Explorer)中进行渐进式呈现。这些浏览器会阻止渲染,以避免在样式更改时重新绘制页面元素。用户被困在查看空白页面。

的HTML规范明确指出,样式表是被包括在网页的HEAD:“与A,[LINK]可以仅出现在一个文档的HEAD部分,尽管它可能出现任意次数”。无论是空白的白屏还是无样式内容的闪烁,这两种选择都不值得冒险。最佳解决方案是遵循 HTML 规范并在文档 HEAD 中加载您的样式表。

将脚本放在底部

标签:javascript

脚本引起的问题是它们会阻止并行下载。的HTTP / 1.1规范建议的浏览器下载不超过每主机名并行两种组分。如果您从多个主机名提供图像,则可以同时进行两次以上的下载。然而,在下载脚本时,浏览器不会启动任何其他下载,即使是在不同的主机名上。

在某些情况下,将脚本移到底部并不容易。例如,如果脚本用于document.write插入页面的部分内容,则它不能在页面中向下移动。也可能存在范围界定问题。在许多情况下,有一些方法可以解决这些情况。

一个经常出现的替代建议是使用延迟脚本。该DEFER属性指示脚本不包含 document.write,并且是浏览器可以继续呈现的线索。不幸的是,Firefox 不支持该DEFER属性。在 Internet Explorer 中,脚本可能会延迟,但不会像您期望的那样延迟。如果一个脚本可以被推迟,它也可以移动到页面底部。这将使您的网页加载速度更快。

避免使用 CSS 表达式

标签: css

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

  背景颜色:表达式((新日期())。getHours()%2?“#B8D4FF”:“#F08A00”);

如此处所示,该expression方法接受一个 JavaScript 表达式。CSS 属性设置为评估 JavaScript 表达式的结果。该expression方法会被其他浏览器忽略,因此对于在 Internet Explorer 中设置属性以创建跨浏览器的一致体验非常有用。

表达式的问题在于它们的计算频率比大多数人预期的要高。它们不仅在页面呈现和调整大小时进行评估,而且在页面滚动时甚至当用户将鼠标移到页面上时也会进行评估。向 CSS 表达式添加计数器允许我们跟踪评估 CSS 表达式的时间和频率。在页面上移动鼠标可以轻松生成 10,000 多个评价。

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

使 JavaScript 和 CSS 成为外部
标签: 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,但在页面加载完成后动态下载外部文件。后续页面将引用应该已经在浏览器缓存中的外部文件。

减少 DNS 查找

标签:内容

域名系统 (DNS) 将主机名映射到 IP 地址,就像电话簿将人们的姓名映射到他们的电话号码一样。当您在浏览器中键入 www.yahoo.com 时,浏览器联系的 DNS 解析器会返回该服务器的 IP 地址。DNS 是有成本的。DNS 查找给定主机名的 IP 地址通常需要 20-120 毫秒。在 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 查找和允许高度并行下载之间实现了很好的折衷。

缩小 JavaScript 和 CSS

标签: javascript, css

缩小是从代码中删除不必要的字符以减小其大小从而缩短加载时间的做法。当代码被缩小时,所有注释以及不需要的空白字符(空格、换行符和制表符)都将被删除。在 JavaScript 的情况下,这会提高响应时间性能,因为下载文件的大小减少了。用于压缩JavaScript 代码的两个流行工具是JSMin和YUI Compressor。YUI 压缩器还可以缩小 CSS。

混淆是一种可应用于源代码的替代优化。它比缩小更复杂,因此更可能由于混淆步骤本身而产生错误。在对十个美国顶级网站的调查中,缩小实现了 21% 的大小减少,而混淆则减少了 25%。尽管混淆可以减少更大的大小,但缩小 JavaScript 的风险较小。

除了缩小外部脚本和样式之外,内联<script>和<style>块也可以而且应该缩小。即使您对脚本和样式进行 gzip,缩小它们仍然会减少 5% 或更多的大小。随着 JavaScript 和 CSS 的使用和大小的增加,通过缩小代码获得的节省也会增加。

避免重定向

标签:内容

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

  HTTP/1.1 301 永久移动
  位置:http://example.com/newuri
  内容类型:文本/html

浏览器会自动将用户带到Location字段中指定的 URL 。重定向所需的所有信息都在标头中。响应的主体通常是空的。尽管它们的名称不同,但实际上 301 和 302 响应都不会被缓存,除非额外的标头(例如Expires或Cache-Control)表明它应该缓存。元刷新标记和 JavaScript 是将用户定向到不同 URL 的其他方式,但如果您必须进行重定向,首选技术是使用标准 3xx HTTP 状态代码,主要是为了确保后退按钮正常工作。

要记住的主要事情是重定向会降低用户体验。在用户和 HTML 文档之间插入重定向会延迟页面中的所有内容,因为页面中的任何内容都无法呈现,并且在 HTML 文档到达之前,无法开始下载任何组件。

最浪费的重定向之一经常发生,而 Web 开发人员通常没有意识到这一点。当 URL 中缺少尾部斜杠 (/) 时会发生这种情况,否则该 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。

删除重复脚本

标签:javascript

在一个页面中包含两次相同的 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 标头。

顶部| 讨论这个规则

配置 ETag
标签:服务器

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

  HTTP/1.1 200 正常
  最后修改时间:2006 年 12 月 12 日,星期二 03:03:59 GMT
  ETag:“10c24bc-4ab-457e1c1f”
  内容长度:12195

稍后,如果浏览器必须验证组件,它会使用If-None-Match标头将 ETag 传递回源服务器。如果 ETag 匹配,则返回 304 状态代码,将本示例的响应减少 12195 个字节。

  获取 /i/yahoo.gif HTTP/1.1
  主持人:us.yimg.com
  If-Modified-Since: 2006 年 12 月 12 日星期二 03:03:59 GMT
  如果无匹配:“10c24bc-4ab-457e1c1f”
  HTTP/1.1 304 未修改

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. AChangeNumber是一个计数器,用于跟踪对 IIS 的配置更改。ChangeNumber在一个网站后面的所有 IIS 服务器上不太可能是相同的。

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

如果您没有利用 ETags 提供的灵活验证模型,最好完全删除 ETag。在Last-Modified基于组件的时间戳头进行验证。删除 ETag 会减少响应和后续请求中 HTTP 标头的大小。这篇Microsoft 支持文章介绍了如何删除 ETag。在 Apache 中,只需在 Apache 配置文件中添加以下行即可完成此操作:

  FileETag 无

使 Ajax 可缓存

标签:内容

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

为了提高性能,优化这些 Ajax 响应很重要。提高 Ajax 性能的最重要方法是使响应可缓存,如添加过期或缓存控制标头中所述。其他一些规则也适用于 Ajax:
Gzip 组件
减少 DNS 查找
缩小 JavaScript
避免重定向
配置 ETag

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

即使您的 Ajax 响应是动态创建的,并且可能仅适用于单个用户,它们仍然可以被缓存。这样做将使您的 Web 2.0 应用程序更快。

尽早刷新缓冲区

标签:服务器

当用户请求一个页面时,后端服务器可能需要 200 到 500 毫秒的时间来拼接 HTML 页面。在此期间,浏览器在等待数据到达时处于空闲状态。在 PHP 中你有函数flush()。它允许您将部分准备好的 HTML 响应发送到浏览器,以便浏览器可以在您的后端忙于处理 HTML 页面的其余部分时开始获取组件。好处主要体现在繁忙的后端或轻量级前端。

考虑刷新的好地方是在 HEAD 之后,因为头部的 HTML 通常更容易生成,并且它允许您包含任何 CSS 和 JavaScript 文件,以便浏览器在后端仍在处理时开始并行获取。

例子:

      ... <!-- css, js -->
    </头>
    <?phpflush(); ?>
    <身体>
      ... <!-- 内容 -->

雅虎!搜索开创性的研究和真实用户测试证明了使用这种技术的好处。

对 AJAX 请求使用 GET

标签:服务器

在雅虎 邮件团队发现,在使用 时XMLHttpRequest,POST 在浏览器中实现为两步过程:首先发送标头,然后发送数据。所以最好使用GET,它只需要发送一个TCP数据包(除非你有很多cookie)。IE 中的最大 URL 长度为 2K,因此如果您发送超过 2K 的数据,您可能无法使用 GET。

一个有趣的副作用是 POST 没有实际发布任何数据,其行为类似于 GET。基于HTTP 规范,GET 用于检索信息,因此当您仅请求数据时使用 GET 是有意义的(语义上),而不是发送数据以存储在服务器端。

后加载组件

标签:内容

您可以仔细查看您的页面并问自己:“为了最初呈现页面,绝对需要什么?”。其余的内容和组件可以等待。

JavaScript 是在 onload 事件之前和之后进行拆分的理想选择。例如,如果您有执行拖放和动画的 JavaScript 代码和库,它们可以等待,因为页面上的拖动元素是在初始渲染之后进行的。其他寻找后加载候选的地方包括隐藏内容(在用户操作后出现的内容)和折叠下方的图像。

帮助您完成工作的工具:YUI Image Loader允许您将图像延迟到折叠以下,而YUI Get 实用程序是一种动态包含 JS 和 CSS 的简单方法。举个例子,看看Yahoo! 打开 Firebug 的网络面板的主页。

当性能目标与其他 Web 开发最佳实践一致时,这是很好的。在这种情况下,渐进增强的想法告诉我们,如果支持 JavaScript,可以改善用户体验,但您必须确保即使没有 JavaScript 页面也能正常工作。因此,在您确定页面工作正常后,您可以使用一些后加载脚本对其进行增强,这些脚本可为您提供更多功能,例如拖放和动画。

预加载组件

标签:内容

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

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

无条件预加载 - 一旦 onload 触发,您就可以继续获取一些额外的组件。查看 google.com 以获取有关如何在加载时请求精灵图像的示例。这个精灵图片在google.com主页上不需要,但在连续的搜索结果页面上需要。
有条件的预加载 - 根据用户操作,您有根据地猜测用户下一步要去哪里,并相应地预加载。在search.yahoo.com 上,您可以看到在输入框中开始输入后如何请求一些额外的组件。
预期预加载 - 在启动重新设计之前提前预加载。在重新设计之后,您经常会听到这样的话:“新网站很酷,但比以前慢了”。部分问题可能是用户使用完整缓存访问您的旧站点,但新站点始终是空缓存体验。您可以通过在启动重新设计之前预加载一些组件来减轻这种副作用。您的旧站点可以利用浏览器空闲的时间来请求新站点将使用的图像和脚本

减少 DOM 元素的数量

标签:内容

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

大量的 DOM 元素可能是一种症状,即应该通过页面标记改进某些内容,而不必删除内容。您是否使用嵌套表格进行布局?您是否投入更多<div>s 只是为了解决布局问题?也许有更好的、语义上更正确的方法来做你的标记。

YUI CSS 实用程序 对布局有很大帮助:grids.css 可以帮助您进行整体布局,fonts.css 和 reset.css 可以帮助您去除浏览器的默认格式。这是一个重新开始并考虑您的标记的机会,例如,<div>仅在语义上有意义时才使用s,而不是因为它呈现一个新行。

DOM 元素的数量很容易测试,只需在 Firebug 的控制台中输入:
document.getElementsByTagName('*').length

有多少 DOM 元素太多了?检查其他具有良好标记的类似页面。例如雅虎!主页是一个非常繁忙的页面,并且仍然少于 700 个元素(HTML 标签)。

跨域拆分组件

标签:内容

拆分组件允许您最大化并行下载。由于 DNS 查找惩罚,请确保您使用的域不超过 2-4 个。例如,您可以承载你的HTML和动态内容上www.example.org 与分裂之间的静电元件static1.example.org和static2.example.org

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

最小化 iframe 的数量

标签:内容

iframe 允许在父文档中插入 HTML 文档。了解 iframe 的工作原理很重要,这样才能有效地使用它们。

<iframe> 优点:

帮助处理缓慢的第三方内容,如徽章和广告
安全沙箱
并行下载脚本
<iframe> 缺点:

即使空白也很昂贵
阻止页面加载
非语义
最佳

没有 404
标签:内容

HTTP 请求很昂贵,因此发出 HTTP 请求并获得无用的响应(即 404 Not Found)是完全没有必要的,并且会降低用户体验而没有任何好处。

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

减少饼干大小

标签: 饼干

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

有关更多信息,请查看 Tenni Theurer 和 Patty Chi 的“当饼干碎了”。这项研究的收获:

消除不必要的 cookie
保持 cookie 的大小尽可能小,以尽量减少对用户响应时间的影响
请注意在适当的域级别设置 cookie,以免影响其他子域
适当地设置一个到期日期。较早的到期日期或无会更快地删除 cookie,从而缩短用户响应时间

标签: 饼干

当浏览器请求静态图像并将 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 写入该子域。

最小化 DOM 访问

标签:javascript

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

缓存对访问元素的引用
“离线”更新节点,然后将它们添加到树中
避免使用 JavaScript 修复布局
有关更多信息,请查看 YUI 剧院 由 Julien Lecomte 撰写的 “高性能 Ajax 应用程序”。

开发智能事件处理程序

标签:javascript

有时页面感觉响应速度较慢,因为有太多的事件处理程序附加到 DOM 树的不同元素,然后太频繁地执行。这就是为什么使用事件委托是一个很好的方法。如果 a 中有 10 个按钮div,则只将一个事件处理程序附加到 div 包装器,而不是每个按钮一个处理程序。事件冒泡,因此您将能够捕获该事件并找出它源自哪个按钮。

您也无需等待 onload 事件即可开始对 DOM 树执行某些操作。通常,您只需要要访问的元素即可在树中使用。您不必等待下载所有图像。 DOMContentLoaded是您可以考虑使用而不是 onload 的事件,但是在它在所有浏览器中可用之前,您可以使用YUI 事件实用程序,它有一个onAvailable方法。

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

标签: css

之前的最佳实践之一指出,CSS 应该位于顶部,以便进行渐进式渲染。

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

避免过滤器

标签: css

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

最好的方法是AlphaImageLoader完全避免并使用优雅降级的 PNG8,这在 IE 中很好。如果您绝对需要AlphaImageLoader,请使用下划线 hack_filter以免惩罚您的 IE7+ 用户。

优化图像

标签:图像

在设计师完成为您的网页创建图像后,在将这些图像通过 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
“我们要说的是:给 PIN 一个机会!”
在所有 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

优化 CSS 精灵

标签:图像

在精灵中水平排列图像而不是垂直排列通常会导致较小的文件大小。
在精灵中组合相似的颜色可以帮助您保持较低的颜色数,最好在 256 色以下,以便适合 PNG8。
“对移动设备友好”并且不要在精灵中的图像之间留下很大的间隙。这不会对文件大小产生太大影响,但需要较少的内存供用户代理将图像解压缩为像素图。100x100 图像为 10000 像素,其中 1000x1000 为 100 万像素

不要在 HTML 中缩放图像

标签:图像

不要仅仅因为您可以在 HTML 中设置宽度和高度而使用比您需要的更大的图像。如果您需要,

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

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

使 favicon.ico 小且可缓存

标签:图像

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

因此,要减轻拥有 favicon.ico 的缺点,请确保:

它很小,最好在 1K 以下。
使用您觉得舒服的内容设置 Expires 标头(因为如果您决定更改它,则无法重命名它)。您可能可以在未来几个月内安全地设置 Expires 标头。您可以查看当前 favicon.ico 的最后修改日期以做出明智的决定。
Imagemagick可以帮助您创建小图标

保持组件低于 25K

标签: 移动

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

有关更多信息,请参阅 Wayne Shea 和 Tenni Theurer 的“性能研究,第 5 部分:iPhone 可缓存性 - 使其保持不变”。

将组件打包成一个多部分文档

标签: 移动

将组件打包成一个多部分文档就像一封带有附件的电子邮件,它可以帮助您通过一个 HTTP 请求获取多个组件(请记住:HTTP 请求是昂贵的)。当你使用这种技术时,首先检查用户代理是否支持它(iPhone 不支持)。

避免空图像 src

标签:服务器

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

直接的 HTML

<img src="">
JavaScript
var img = new Image();
img.src = "";

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

Internet Explorer向页面所在的目录发出请求。
Safari 和 Chrome向实际页面本身发出请求。
Firefox 3 及更早版本的行为与 Safari 和 Chrome 相同,但 3.5 版解决了这个问题[bug 444931]并且不再发送请求。
当遇到空图像 src 时,Opera不会做任何事情。

为什么这种行为不好?

通过发送大量意外流量来削弱您的服务器,尤其是对于每天获得数百万页面浏览量的页面。
浪费服务器计算周期生成永远不会被查看的页面。
可能损坏了用户数据。如果您正在通过 cookie 或其他方式跟踪请求中的状态,则有可能破坏数据。即使图像请求不返回图像,浏览器也会读取并接受所有标头,包括所有 cookie。当其余的响应被丢弃时,损害可能已经造成。

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

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

src 属性必须存在,并且必须包含引用非交互式、可选动画、图像资源的有效 URL,该图像资源既非分页也非脚本化。如果元素的基本 URI 与文档的地址相同,则 src 属性的值不能是空字符串。
希望以后浏览器不会有这个问题。不幸的是,<script src=""> 和 <link href=""> 没有这样的子句。也许还有时间进行调整以确保浏览器不会意外实现此行为。
这条规则的灵感来自 Yahoo! 的 JavaScript 大师 Nicolas C. Zakas。有关更多信息,请查看他的文章“空图像 src 会破坏您的网站”。

附上源地址连接:

打赏
支付宝 微信
上一篇 下一篇