网站提速的最佳实践(译文)

原文地址 http://developer.yahoo.com/performance/rules.html#cookie_size
这是译文,识字不多,请保持警惕性。
==========================================
给网站提速的最佳实践

1) 最小化HTTP请求次数
tag content
80%的终端响应时间用在了前端(第一句就觉得拗口)。大部分的时间被页面上的组件所占用:图片,样式,脚本,flash(flash和flex的区别)等等。!!减少组件的数量继而减少用来渲染页面的HTTP请求的数量。这是加速网页的关键。

减少组件数量的一种方法是简化网页的设计。除此之外有没有一种方式可以获得快速响应的同时构建丰富内容的网页呢?这里有一些减少HTTP请求数量的技术,同时依旧支持富页面设计。

    1 合并文件
    合并文件是减少HTTP请求数量的一种方式,它通过合并多个脚本文件到单个文件以及合并所有的CSS到一个样式表。当脚本和样式切换的时候,合并文件非常有挑战性。

    2 CSS Sprite
    CSS Sprite 是减少图片请求的首选。合并所有的背景图片到单个图片,用background-image 和background-position属性显示想得到的图片部分。

    3 Image maps
    Image maps 合并数张图片成一张图片。图片的总大小是差不多的, 但是减少了HTTP的请求,加速了网页。 Image maps只有当页面的图片是连续的时候才会有用,像导航栏。
    定义image maps 的坐标会让你觉得乏味可陈而且容易出错。给导航栏使用image maps也是不容易理解的, 所以这种方式不推荐。

    4 URL scheme
    http://tools.ietf.org/html/rfc2397

减少页面中的HTTP请求只是刚刚开始。这是为首次访问者改善用户体验的最重要的准则。
正如Tenni Theurer的博客 Browser Cache Usage - Exposed!
yuiblog.com/blog/2007/01/04/performance-research-part-2/
40%-60%的网站的日常访问者没有该网站的缓存文件。让网页更快的响应第一次访问是更好用户体验的关键。

2)使用内容分发网络
tag server

用户和服务器的距离对响应时间有一定影响。从用户的角度来说,通过许多分散的服务器分发内容会使网页加载速度更快。然而你要从哪里下手呢?

作为部署地理分发网络的第一步,不要为了适应分布式体系结构而重构你的网站应用。根据不同的应用,改变体系结构会带来令人生畏的任务,比如同步会话状态,跨服务器复制数据库事务。尝试减少用户和你的网站的计划会被你的应用架构步骤推迟,或者更糟。

记住80%-90%的终端用户的响应时间被用来下载网页中的各种组件:图片,样式表,脚本,flash等等。这是性能黄金法则。相比较重构应用架构带来的麻烦,分散你的静态内容是更加明智的选择。内容分发网络大幅度地减少了响应时间。

CDN是分布式服务器集群,它跨越数个地区,用来更高效的为用户分发内容。被选中用来分发内容给指定用户的服务器是非常典型地基于网络临近性。举个例子,最小网络跳跃(?)或者最快响应时间的服务器会被选中。

一些大型的互联网公司拥有他们自己的CDN,但是使用CDN服务提供商是划算的。对于创业公司和私人网站来说,CDN的花费让人望而却步,但是当你的目标受众增长,变得更加全球化的时候,CDN是获得快速响应的必要步骤。Yahoo依靠CDN使终端用户响应时间缩短了20%或者更多。

3)添加过期时间或者缓存控制头
tag server

这条规则主要有两个方面
    对于静态组件实行“永不过期”政策;
    对于动态组件使用合适的缓存控制头

网站设计正变得越来越复杂,意味着网页中有更多的脚本,样式表,图片以及flash。对网站第一次访问发起很多次HTTP请求,但是通过设置过期时间可以让那些组件被缓存。在随后的访问中避免了不必要的HTTP请求。过期头最常被用在图片,!!然而他们应该被用在所有的组件上,包括脚本,样式表以及flash组件。

浏览器以及代理使用缓存减少HTTP请求的数量以及大小,让网站加载得更快。一个用来响应HTTP请求的网站服务器使用过期头告诉客户端一个组件能被缓存多久。

如果你的服务器是Apache, 使用过期默认指令设置相对于当前日期的过期时间,
ExpiresDefault "access plus 10 years" 距发送请求10年以后,才会过期。

记住,如果你用一个长久的过期头,当组件发生变化的时候,你不得不更改组件的文件名。 在Yahoo,我们经常操作这个步骤作为开发项目的一部分,一个版本号总是嵌在组件的文件名里,像 yahoo——2.0.6.js。

使用长期的过期头只会在用户访问过你的网站后才会影响网页浏览。 如果用户是第一次访问你的网站并且浏览器缓存是空的时候,对于HTTP请求数没有影响。 !!因此性能提升的效果依赖于用户访问你页面的频率。Yahoo发现已经带有缓存的页面访问占了75%-85%。 通过使用长期过期头,使被缓存以及被重用的组件的数量大大增加。得在随后的访问中,不需要通过用户的因特网发送一个字节。

Gzip 组件
tag server

这次说说发HTTP请求,网络响应受前端工程师的决策的影响显著地减少。终端用户的带宽速度,因特网服务提供商,邻近的对等交换点是开发团队无法控制的。然而还有其他变数会影响响应时间。Gzip压缩通过减少HTTP响应的大小减少响应时间。

Gzip是当前最流行的以及最有效的压缩方式。 它由GNU项目发开,由RFC 1952制定成标准。另外一种压缩格式你很可能碰到的是deflate,但是影响很小而且不流行。

!!Gzipping普遍减少70%的响应量。大约90%的通过浏览器的互联网传输都要求支持gzip。

使用浏览器或者代理会有一些已知的问题,浏览器希望得到和它实际接收到的压缩内容会有错配。 幸运的是,这些边界情况随着旧浏览器的淘汰而减少。Apach的模块通过自动添加合适的的响应头帮了大忙。

服务器根据文件类型决定哪些会被gzip压缩,然而在决定哪些应该被压缩非常受限制。 大部分网站压缩挺忙的HTML文档。!!同样值得压缩脚本和样式表,但是许多网站错过这个机会。实际上,压缩任何文本响应包括XML以及JSON也是值得做的。图片,PDF文件不应该被gzip压缩,因为它们已经被压缩了。 尝试压缩它们只会浪费CPU,同时潜在地增加文件大小。

Gzip压缩尽可能多的文件类型是一种减少网页重量和促进用户体验的一种简单的方式。

4)将样式表放在顶部
tag css

当我们在Yahoo研究性能的时候,发现将样式表移到头部似乎让页面加载更快。这是因为将样式表放到HEAD里可以让页面渐进式的渲染。

关心性能的前端工程师想让页面渐进式加载;换句话说,我们想让浏览器尽快地显示任何内容。当页面内容很多的时候或者用户的网络连接非常慢的时候显得尤为重要。!!给予用户视觉上的反馈的重要性,就像进度指示一样,已经被广泛地论证。在我们的例子中,HTML页面就是进度指示!当浏览器渐进式地加载顶部的header,导航栏,图标 等等,给等待页面响应的户视觉反馈。这提高了整体的用户体验。

将样式表放到文档的接近底部产生的问题是它在许多浏览器中阻止渐进式渲染,包括IE,这些浏览器为了避免样式有变动的时候重复渲染页面上的元素而阻止渲染。用户只能卡在空白的页面。

空白的屏幕或者由于没有应用样式而引起的内容的闪现都不值得去尝试。
最理想的将解决方案是遵循 HTML specification,在文档头部载入你的样式。

5)将脚本放到底部
tag javascript

脚本引起的问题是会阻塞并行下载。!! HTTP/1.1 specification (http://www.w3.org/Protocols/rfc2616/rfc2616-sec8.html#sec8.1.4)建议浏览器对每个域名组件的并行请求数不要超多两个。如果你将图片部署到多个服务器,可以进行超过两个的并行下载。然而当脚本下载的时候,服务器不会开启其他任何下载,甚至是不同域名下资源。

在某些情况下,移动脚本到底部并不是那么容易,举个例子,当脚本使用document.write插入页面内容的时候,脚本不能被移到页面的底部。还会有作用域问题。在很多情况下,这些问题会有变通的解决方案。

经常被提到的一个建议是使用延时脚本。 DEFER属性意味着脚本不包含documen.write,并且是一个让浏览器继续渲染的提示。很不幸的,Firefox不支持DEFER属性。 在IE浏览器中,脚本可能被延迟。!!如果一个脚本可以被延迟,那么它就能被移到页面底部。那会使你的网页加载更快。

6)避免CSS 表达式
tag css

CSS表达式是一种动态设置CSS属性的强有力(危险的)方式。它从IE5开始被支持,但是IE8开始弃用它。举个例子,背景色可以用CSS表达式设置成每小时轮流变换:
    background-color: expression((new Date()).getHours()%2 ?"#B8D4FF" : "#F08A00");
如上所示,expression方法!!接收Js表达式。CSS属性被设置成JS表达式的执行结果。 expression方法被其他浏览器忽略,所以对于ie来说,!!创建一个一致的跨浏览器的表达式设置属性非常有用。
( so it is useful for setting properties in Internet Explorer needed to create a consistent experience across browsers.也许是类似IE6中模拟position:fixed)

!!CSS表达式带来的问题是它比人们预期的执行频率高很多。表达式不仅仅在页面渲染和页面缩放的时候执行,而且页面滚动甚至用户在页面上移动鼠标的时候也会执行。添加一个CSS表达式计数器可以让我们跟踪CSS表达式被执行的时间和频率。 在页面上移动鼠标能轻松地行程超过10000次的计算。

一种减少CSS表达式执行次数的方法是使用一次性表达式。!!当表达式第一次执行的时候,表达式给样式style属性设置一个明确的值,替换CSS表达式。如果样式属性在页面生命周期内必须设置成动态的,使用事件替换CSS表达式是一种可选的途径。 如果你必须使用CSS表达式,记住它会被执行数千次,会影响页面的性能。

7)将JS和CSS分离出去
tag javascript css

许多性能准则规定外部组件如何被管理。 可是,在考虑这些之前,你应该问一个更加基础的问题,JS和CSS应该被包含到外部文件里还是内联到页面内部。

在现实中使用外部文件普遍地加快了网页的加载因为JS和CSS文件被缓存到浏览器中。HTML文档被请求的时候嵌在HTML文档内部的JS和CSS每次度会被下载。内联减少了HTTP请求的次数,但是增加了HTML文档的大小。 另一方面,如果外部JS和CSS文件被浏览器缓存,HTML文档的大小减少的同时也不会增加HTTP的请求数。

!!关键因素是外部JS和CSS组件被缓存的频率和HTML文档被请求的次数有关。尽管很难被量化,这种因素可以用各种指标判定。 如果访问你网站的用户每次会话期间有多个页面的浏览,而且你许多页面都重用相同的脚本和样式表,那么会从缓存的外部文件得到很大的性能效益。

!!许多网站选择一种折中的方式。对于这些网站而言,最好的解决方案一般是部署外部JS和CSS文件。 唯一例外的就是在首页内嵌是更可取的。就像Yahoo's front page 和 My Yahoo! 首页每次会话的访问次数较少,内嵌JS和CSS会得到更快的终端响应时间。

8)减少DNS查找
tag content

域名系统映射域名和IP地址,就像电话本映射人名和电话号码一样。
当你输入www.yahoo.com到你的浏览器,浏览器连接DNS解析器,返回服务器的IP地址,DNS查找有一定的开销,一般会花费20-120微秒。直到DNS查找完成浏览器才可以从域名下载。

为了更好的性能DNS查找会被缓存。这个缓存出现在一个特殊的缓存服务器上。被用户的ISP或者本地网络保持,但是缓存也会出现在用户的个人电脑中。DNS信息保留在操作系统的DNS缓存。大部分的浏览器拥有他们自己的缓存,从操作系统的缓存中独立开来。只要浏览器在它自己的缓存中保存了DNS记录,它不会去像操作系统请求记录。

IE默认缓存DNS查找结果30分钟,由 DnsCacheTimeout 注册设置所指定。
FF缓存DNS查找结果1分钟,由 network.dnsCacheExpiration配置项所控制。

当客户的DNS缓存是空的(浏览器和操作系统都空),DNS寻址的次数和页面中独特域名的数量是一样的,包括页面URL,图片,脚本,样式表,flash对象的域名等等。 !!减少独特域名的数量减少了DNS查询的次数。

减少独特域名的数量潜在地减少了页面中发生的并行下载的总数。避免DNS查找缩短了响应时间,但是减少并行下载也许会增加响应时间。!!我的观点是分散组件到至少两个但是小于4个域名下。这使得减少DNS查询和维持较高水平的并行下载两全其美。

9)最小化JS和CSS
tag javascript css

极简化是从代码中去除不必要特性的时间,减小文件大小从而改善加载时间。当代码被最小化,所有的注释都移除了,不需要的空白字符也会移除。在JS的情况下,这能改善响应性能因为下载文件的大小减少了。两个流行的用来压缩JS代码的工具是JSMin和YUI Compressor。YUI Compressor也压缩CSS。

模糊处理(加密)是一种另类的优化,可应用到源代码。它比最小化更加复杂,因此更容易产生bug,这是模糊步骤的结果。在美国网站的调查中,最小化
达到21%的尺寸缩减率,而模糊处理是25%。!!尽管模糊处理有更高的尺寸所缩减率,最小化JS风险较小。

除了最小化外部脚本和样式,内联的脚本和样式模块也能而且也应该被最小化。 即使你 gzip压缩了你的脚本和样式,最小化它们依旧会减小5%甚至更多的文件大小。随着JS和CSS大小和使用频率的增加,通过最小化你的代码获得的性能提升也会增加。

10)避免重定向
tag content

重定向是通过301和302状态码来完成的。跳转需要的所有信息都在头部信息里面。响应的主体是典型的空。实际上,301和302响应都不会被缓存除非有额外的头部信息,如过期时间或者缓存控制指示它应该被缓存。meta刷新标签和JS是指定用户去不同网址的其他方式,但是如果你必须要作跳转,!!首选技术是使用3XXHTTP状态码,从根本上确保后退按钮正常地工作。

主要需要牢记的是跳转降低了用户体验。在用户和HTML文档之间加入一个跳转会延误页面上的所有东西,因为页面中没有东西可以被渲染,没有组件可以被下载直到开始获取HTML文档。

一个最浪费的跳转经常发生,并且网站开发人员普遍没有意识到这个问题。当URL本来应该有尾斜杠,但是没有的时候,它就会发生。 举个例子,!!定位到http://astrology.yahoo.com/astrology 会得到一个3.1响应,它会重定向到http://astrology.yahoo.com/astrology/. 通过使用Alias,mod_rewrite或者DirectorySlash 指令,这个问题在Apach下已经被修复。

通过连接旧站点到新站点是另一个重定向的普遍使用方法。其他的用法包括连接网站的不同部分,基于特定条件(用户的浏览器,账户类型)跳转。 使用重定向联系两个站点很简单并且只需很少的代码。尽管在这些情境下使用重定向为开发者降低复杂性,但它使用户体验降级。如果两个网站的代码路托管在同一台服务器上,使用Alias和mod_rewrite是重定向这种用法的一个备选方案。如果域名因为重定向而发生变化,一个可选方案是创建一个CNAME和Alias或者mod_write结合到一起。

11)移除重复的脚本
tag javascript

在一个页面中将同一个JS文件引入两次会降低性能。这和你想象的一样。对美国前10网站的检查发现其中两个网站包含重复的脚本。!!两个影响因素会增加在单个网页中出现重复的脚本的概率:团队规模和脚本数量。当这种情况确实发生的时候,重复脚本发起不必要的HTTP请求和多余的JS执行降低性能。

多余的HTTP请求发生在IE浏览器,FF则不会。在IE浏览器中,如果外部脚本引入两次并且没有被缓存,它会在页面加载的时候发起两次HTTP请求。即使脚本被缓存,当页面重新加载的手额外的HTTP请求又会发生。

除了生成浪费的HTTP请求,时间被浪费在重复执行脚本上。 这多余的脚本执行正在FF和IE下都会发生,无论脚本是否被缓存。

一种避免脚本被意外载入两次的方法是在模板系统中实现脚本管理模块。典型的引入脚本方式是在你的HTML页面中使用SCRIPT标签。
<script type="text/javascript" src="menu_1.0.17.js"></script>
PHP中的一种替代方案是创建一个叫insertScript的函数
 <?php insertScript("menu.js") ?>
除了防止相同脚本被插入多次以外,这个函数能用脚本处理其他问题,比如依赖性检测,添加版本号到脚本名中支持很久以后的过期头信息。

12)配置 Etags
tag server

!!Etags 是网站服务器和浏览器用来判断浏览器缓存里面的组件是否和源服务器上的组件一致的一种机制。作为验证实体的一种途径,ETags比last-modified date更具有弹性,它用一个独一无二的字符串来标识一个元素的版本。唯一的约束是这字符串必须带引号。源服务器用Etag响应头指定组件的Etag。

如果浏览器不得不验证一个组件,它使用if-None-Match头部将Etag传回到源服务器。如果Etags一致,一个304状态码会返回。

用Etags的问题就在于它会标识那个特定的服务器,如果换了服务器,Etags也就失去了原有的功能,但是这种现在在网络上太常见了,因为我们经常用服务器集群。默认情况下,Apache和IIS会在Etag中内嵌数据,这样会动态减少验证成功的机会。

Apache1.3和2.x的ETag格式是inode-size-timestamp。虽然一个文件可能在不同服务器的同一个目录,同样的大小,安全级,时间戳等等,它的inode会随着服务器的不同而不同。

IIS5.0和6.0有同样类似Etags的东西,叫文件时间戳:ChangeNumber(更改号),更改号是一个用来追踪IIS配置变化的计数器,ChangeNumber在不同IIS服务器之间是不一样的。

它最终的问题就是,IIS和Apache产生的Etags会在不同服务器之间无法匹配,这样我们的浏览器就无法得到我们期待的304响应,而给我们 的是一个普通的200响应,和正常的数据流。如果你的网站只有一个服务器还无所谓,如果是集群,而你用的是默认的ETag配置,你的用户就会获得更慢的页面,你的服务器也会有更高的负载,消耗更大的带宽资源,代理也无法高效缓存你的内容,甚至即使你有一个长时间过期的头部,也不会阻止 它重新载入内容。

如果你不想发挥Etags提供的这个弹性验证模型的优势,你最好关掉它。Apache中关掉它的方法是在Apache的配置文件中写这么一句:
FileETag none

如果是多服务器负载均衡,可以设置为FileETag MTime Size,apache默认设置为FileETag INode MTime Size,去掉INode。

13) !!缓存Ajax
tag content

AJAX的一个好处是它给用户提供即时的反馈,因为它从后端服务器异步地请求信息。 可以使,使用Ajax并不能保证用户在不会玩弄手指等待那些异步的js和xml响应。在很多应用中,用户是否等待取决于如何使用AJAX。举个例子,在一个网页式的邮箱客户端,用户会等待AJAX找到所有符合搜索条件的电子邮件。记住异步并不意味着瞬间很重要。

为了提高性能,最优化这些AJAX请求很重要。最重要的提高AJAX性能的方式是让响应被缓存。一些规则也适用于AJAX: Gzip components,ReduceDNS lookups, MinifyJavascript, Avoid Redirects,Configure Etags.

让我们来看一个例子。一个Web 2.0的邮箱客户端也许会使用AJAX下载用户的通讯簿用来自动填充。如果用户自从上次使用网页版邮箱依赖没有修改过他的通讯簿,如果AJAX响应使用长时间过期头或者缓存控制头进行缓存,先前的通讯薄响应能从缓存中读取。浏览器必须被告知使用先前缓存的通讯簿还是请求一个新的。可以通过给通讯簿AJAX请求URL添加时间戳标示最后一次修改通讯簿的时间来实现,如&t= 1234567890. 如果通讯簿从上次被下载以后没有被修改,时间戳会保持一致,通讯簿会从浏览器的缓存中读取,省去了一个额外的HTTP往返。如果这个用户已经修改了他的通讯簿,时间戳会确保新的URL不和缓存的响应匹配,浏览器会去请求更新过的整个通讯簿。

14) !!尽早的释放缓冲区
tag server

当用户请求一个页面,后端服务器会花费20-500ms用来缝接HTML页面。在等待数据响应期间,浏览器是闲置的。在PHP中,你有函数flush(),它允许你发送部分准备好的HTML响应浏览器以便浏览器提取组件,那时后端正忙于剩下的HTML页面。当后台繁忙而前台轻松的时候好处尤为明显。

!!考虑输出缓冲的一个好地方就在HEAD标签后面,因为HTML的Head部分通常非常容易产生并且它允许你包含样式和脚本文件,让浏览器可在后台仍旧在处理的时候开始并行接受。
<html>
    <head></head>
    <?php flush();?>

15)使用get方式发送AJAX请求
tag server

Yahoo 邮箱团队发现当使用XHR的时候,POST方式在浏览器内部是以两部处理实现的:先发送头部,然后发送数据。 所以最好使用GET方式,它只发送一个TCP包。在IE中最大URL长度是2K,所以说如果你要发送超过2K 的数据,你也许不能使用GET方式。

一个有趣的副作用,POST不像GET方式那样真正的传递任何数据行为。根据HTTP specs(http://www.w3.org/Protocols/rfc2616/rfc2616-sec9.html)
GET意味着检索数据,所以当你只是请求数据的时候使用GET方式是情理之中的,正好和发送数据在服务器端存储相反。

16)POST-load 组件
tag content

你仔细看看你的页面然后问问你自己。“哪些是绝对必须用来最初渲染你的页面的?” 剩下的内容和组件可以推迟。

JS是一个拆分onload事件前后的理想选择。举个例子,如果你有JS代码和库文件用来实现拖放和动画效果,那些可以推迟,因为在!!页面上拖动元素在最初的渲染之后。其他post-loading的地方包括隐藏内容和不明显位置的图片、

17)预加载组件
tag content

预加载也许看起来像是post-load的反面,但是它实际上有一个不同的目标。通过预加载组件,你可以利用浏览器闲置的时间请求你要用到的组件。通过这种方式,当用户访问下一个页面的时候,大部分组件已经在缓存里面,而且对于用户来说,加载会快很多。

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

    1.无条件的预加载 - 一旦onload事件触发,继续获取一些额外的组件。 以google.com为例,载入页面时sprite图片是如何被请求的。 !!这个sprite图片不需要出现在在google.com首页,但是在接下来的搜索结果界面是必须的。

    2 有条件的预加载 - 基于用户的行为作有根据的推测用户接下来要去哪里并且进行相应的预加载。在search.yahoo.com你可以看到在你开始在输入框输入的时候会有一些额外的组件请求。

    3 预期的预加载 - 在你开始进入新网站的时候提前预加载。 网站重构以后经常会听到“这新网站很出色,但是比以前慢很多”。部分问题是用户带着全部缓存访问你的旧网站,但是新网站总是没有缓存经历。你可以在你进入新网站之前通过预加载减轻这种副作用。 你的浏览器可以使用浏览器闲置的时间请求新站点中用到的脚本和图片。

18)减少DOM元素的数量
tag content

一个复杂的页面意味着更多的字节要被下载,它通常也意味着JS中更慢的DOM存取。如果你遍历页面中的500和5000 DOM元素添加事件处理器会有所不同。

大量的DOM元素是使用页面中标记改善一些东西的征兆。!!你有使用嵌套的表格达到布局的目的么?你有使用div标签仅仅是为了修复布局问题么?也许有一种更好的更符合语义的正确方式处理你的标记。

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

19) 拆分组件到不同的域名下
tag content

拆分组件可让你最大化并行下载。!!出于DNS查询性能处罚的考虑,确保你使用不超过2-4个域名。举个例子,你可以托管你的HTML和动态内容到www.example.com并且拆分静态的组件到static1.example.org和static2.example.org

"Maximizing Parallel Downloads in the Carpool Lane"
(http://yuiblog.com/blog/2007/04/11/performance-research-part-4/)

20)最小化iframes的数量
tag content

iframes允许HTML文档插入到父级文档。理解ifram如何工作对于有效使用他们很重要。

<iframe> pros:
    Helps with slow third-party content like badges and ads
    Security sandbox
    Download scripts in parallel

<iframe> cons:

    Costly even if blank
    Blocks page onload
    Non-semantic


21) No 404s
tag content

HTTP请求开销很大,所以发起HTTP请求却得到一个无用的响应是完全没必要的,而且会毫无益处地降低用户体验。

!!一些网站有有用的的404页面“你是指。。。”,这对于用户体验很有益处,但是也浪费了很多资源。 特别不好的情况是外部JS的连接错误并且结果是404。 首先这个下载会锁定并行下载。其次浏览器会尝试把404响应主体当做JS代码解析,尝试从里面找些有用的。

22) 减少Cookie大小
tag cookie

HTTP cookies因各种理由被使用,比如验证和个性化。!!cookies的信息在网络服务器和浏览器之间通过HTTP头部进行交换。保持cookies尽可能的最小化对于用户的响应时间的影响很重要。
 "When the Cookie Crumbles"
http://yuiblog.com/blog/2007/03/01/performance-research-part-3/

    1 消除不必要的cookies
    2 尽可能少地保留cookie
    3 留心在合适的域名级别下设置cookie,那么其他子域名就不会受到影响
    4 设置一个合适的过期时间。较早的过期时间或者更快的移除cookie会加快用户的响应时间。

23)为组件使用cookie-free域名
tag cookie

当浏览器为静态图片发起请求并且将cookie一起发送过去, 那些cookies对于服务器没有一点用。所以他们只会无理由地制造网络拥堵。 你应该确保静态组件被cookie-free请求所请求。 创建一个子域名并且将你所有的静态组件放到里面。

如果你的域名是www.example.org,你可以将你所有的静态组件托管到static.example.org。可以如果你已经在顶级域名比如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写到那个子域名下。

24)最小化DOM存取
tag javascript

用JS存取DOM元素非常缓慢。所以为了拥有一个更快响应的网页,有应该
    1 缓存访问过的元素的指针
    2 “离线更新nodes”,然后添加到DOM树
    3 避免用JS修改布局
"High Performance Ajax Applications"
http://yuiblog.com/blog/2007/12/20/video-lecomte/

25)开发灵活的事件处理程序
tag javascipt

有些时候页面响应性会降低,因为太多的事件处理程序绑定到DOM树不同的元素中,执行太过频繁。这就是为什么使用事件代理是一种好方法。 如果在一个div中有10个按钮,绑定一个事件处理程序到div外层元素上,而不是每个按钮一个事件处理程序。事件会冒泡,你会捕获这个事件,然后断定源自哪个按钮。

26)多使用link,而不是@import
tag css

为了渐进式地渲染,CSS应该在文档顶部,在IE9中@import和在文档底部使用link一样。所以虽好不要使用他。

27)避免使用滤镜

28)优化图片
tag images

当设计师制作完成网页的图片后,在你上传那些图片到服务器之前仍然有一些事情你可以尝试。

    1 你可以检查GIF图片,看看他们是否使用与图片颜色数一直的调色板尺寸。使用imagemagick(http://www.imagemagick.org/)可以轻松地检查。

    2 尝试将GIF转化成PNG,看看是否有节省空间。多半情况是有改善的。开发者经常犹豫到底要不要使用PNG,主要是受制于浏览器的支持程度,但是这已经是过去的事情了。唯一的问题是真彩色ONG格式的alpha透明,但是GIF并不是真彩色并且也不支持可变的透明。所以任何GIF可以做的事情,PNG8都可以做(除了动画)。
。。。

29) 优化CSS Sprites
tag images

     1 垂直的拼接得到的图片通常小于水平排列的图片。

     2 组合相似的颜色到一张图片上有助于将颜色数保持在低位,理想是256颜色数,适合PNG8格式。

     3 不要在sprite图片上留太多的空隙。这对文件大小的影响不大,但是对于客户端来说只需要更少的内存去将图片解压成像素图,100X100图片是10K像素,1000X1000就是1百万像素。

 30) 不要在HTML中缩放图片
 tag images

 不要仅仅因为你可以在HTML中给图片设置高宽而使用大于你需要的尺寸的图片。
<img width="100" height="100" src="mycat.jpg" alt="My Cat" />
你的图片应该做成100X100像素,而不是一张500X500按比例缩小后的图片。

31)favicon.icon越小越好,而且要可缓存
tag images

favicon.com是一张待在服务器根目录下的图片。它是不可避免的问题,因为即使你不在意它,浏览器仍然会去请求它,所以最好别以404响应。 另外由于他在同一个服务器下,它每次被请求的时候cookies都会发送。这张图片也会干扰下载队列, 举个例子,当你在IE中请求额外的组件的,favicon.icon会在这些额外组件被夹在之前下载。

所以为了减少favicon带来的弊端,要做到:
    1它要很小,最好小于1K。
    2设置你觉得合适的过期头部。

32) 确保组件小于25K
tag mobile

这个约束和iPhone不会缓存大于25K的组件的事实有关。注意这是未解压的尺寸。这是体现极简化重要的地方,因为淡村gzip可能还不够。

需要更多的信息,检查Performance Research, Part 5: iPhone Cacheability - Making it Stick(http://yuiblog.com/blog/2008/02/06/iphone-cacheability/)

33)将组件打包到复合文本。。。
tag mobile

34) 避免空的图片路径
tag server

带有空字符src属性的图片不止一次地出现,它以两种方式出现:

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

两种方式得到同一个结果,浏览器发送另一个请求到你的服务器上。
    1 IE会发送请求到当前页面所在的目录下面。
    2 Safari和Chrome会发送请求到页面自己的路径。
    3 FF3和早期的版本和Safari,Chrome表现一直,但是3.5版本解决了这个问题,不会发送请求。
    4 碰到空地址图片的时候Opera不会做任何事情。

这个行为为何是不好的?
    1 发送一堆不必要的请求到服务器削弱了服务器性能,特别是百万级日流量的站点。
    2 产生一个从未浏览过的页面将浪费服务器的计算周期。
    3 还有可能损坏用户数据。假如你正在通过cookie或者其他方式追踪请求状态,你有可能损坏数据。即使图片请求没有返回图片,所有的头部信息被浏览器接收并读取,包括所有的cookie。当剩下的响应被抛弃的时候,损害可能已经发生了、

这种行为的根源是浏览器执行URI解析的方式引起的。这种行为被定义在RFC 3986。当碰带一个空字符串作为URI,他被视为一个相对URI。

HTML5添加了标签的src属性说明,指示浏览器不要发送额外的请求。
    src属性必须存在,并且必须包含一个有效的URL定位到一个非交互的图片资源,不能是图片也不能是脚本。如果元素的基地址和文档的地址一样,那么src属性的值不能是空字符串。

我希望在未来浏览器不会有这个问题。不幸的是,script标签和link标签没有类似的条款。也许依旧需要时间去作出这个调整,确保浏览器不会意外地执行这个动作。

这条规则是受Yahoo 的JS领袖(Nicolas C Zakas)的启发。更多的信息请查看他的文章"Empty image src can destroy your site"(http://www.nczonline.net/blog/2009/11/30/empty-image-src-can-destroy-your-site/).  


**********************************
               ******
                 __
               /`__`\
           .=.| ('') |.=.
          /.-.\ _)(_ /.-.\
         |:    / ~~ \    :|
         \ :  | (__) |  : /
          | :  \_/\_/  : |
          |:  /|    |\  :|
          \_/` |    | `\_/
               |    |
               |    |
               |~~~~|
               '----'
**********************************
 更多内容 http://www.cnblogs.com/cy056
1 减少请求(合并文件(CSS+JS+图片),外链JS-CSS,缓存控制,Etag)
2 CDN,Gzip,JS+CSS(简化+混淆),减少DNS查询,减少重定向
3 CSS放前面,JS放后面, 预加载,延迟加载,flush(), DOM操作,事件代理,CSS表达式
4 缓存AJAX ,GET方式
5 减少cookie大小,合适的cookie级别

posted @ 2013-05-07 00:30  积跬步  阅读(371)  评论(0编辑  收藏  举报