yahoo前端性能团队总结过35条黄金定律。高性能的网站优化包括很多的点,大致分为几个方面,在此分门别类的总结一下:

一、浏览器方面(页面优化)
①减少HTTP请求次数
网页的打开,70%的响应时间花在下载网页内容(img/css/js…)。减少请求次数是缩短响应时间的关键!具体方法有:压缩聚合css、js等文件;CSS Sprites;Image Maps;Inline p_w_picpath;
②减少DNS请求次数
DNS查询也消耗响应时间,如果我们的网页内容来自各个不同的domain (如嵌入开放广告或引用了外部img/css/js),那么客户端首次解析这些domain也需要消耗一定的时间。
③避免页面跳转

当客户端收到服务器的跳转回复时,客户端再次根据服务器回复中的location指定的地址再次发送请求,例如以下跳转回复。

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

当客户端遇到这种回复的时候,用户只能等待客户端再次发送请求,有的网站甚至会一直跳N次,跳到他想带你去的地方…当然在这个时候用户看不到任何页面内容,只有浏览器的进度条一直在刷新。
④缓存Ajax
Ajax可以帮助我们异步的下载网页内容,返回查询结果。
⑤延迟加载
将页面中最重要的内容首次加载出来,次要的可以延迟加载显示。Javascript是典型的可以延迟加载内容。一个比较激进的做法是开发网页时先确保网页在没有Javascript的时候也可以基本工作,然后通过延迟加载脚本来完成一些高级的功能。
⑥提前加载

与延迟加载目的相反,提前加载的是为了提前加载接下来网页中访问的资源,下面是提前加载的类型:

-- 无条件提前加载:当前网页加载完成后,马上去下载一些其他的内容。

-- 有条件加载:根据用户的输入推断需要加载的内容。

-- 有预期的的加载:这种情况一般发生在网页重新设计时,由于用户经常访问旧网页,本地对旧的网页内容缓存充分从而显得旧网页速度很快,而新的网页内容却没有缓存,设计者可以在旧网页的内容中预先加载一些新网页中可能用到的内容,这样新的网页就会生下来一些需要下载的资源。 

⑦减少DOM元素数量

网页中元素过多对网页的加载和脚本的执行都是沉重的负担,500个元素和5000个元素在加载速度上会有很大差别。想知道你的网页中有多少元素,通过在浏览器中的一条简单命令就可以算出:

document.getElementsByTagName('*').length

多少算是多了呢?雅虎曾经号称主页只有700多元素,但现在接近多了一倍。知乎个人内页比雅虎多吧。

⑧根据域名划分内容

浏览器一般对同一个域的下载连接数有所限制,按照域名划分下载内容可以浏览器增大并行下载连接,但是注意控制域名使用在2-4个之间,不然dns查询也是个问题。

一般网站规划会将静态资源放在类似于http://static.example.com,动态内容放在www.example.com上。这样做还有一个好处是可以在静态的域名上避免使用cookie。这一点,在腾讯、淘宝、天猫上都能发现它们都有很多的二级域名地址分类。

⑨减少iframe数量

即使iframe内容为空也消耗加载时间;会阻止页面加载;没有语义。


二、服务器方面
①使用CDN,提高网站的下载速度可以通过CDN来提升。CDN通过部署在不同地区的服务器来提高客户的下载速度。
②添加Expires或Cache-Control报头文
-- 对于静态内容添加Expires,将静态内容设为永不过期,或者很长时间。
-- 对于动态内容应用合适的Cache-Control,让浏览器根据条件来发送请求。
③Gzip压缩
Gzip通常可以减少70%网页内容的大小,包括脚本、样式表、图片等文件。Gzip比deflate更高效,主流服务器都有相应的压缩支持模块。 
④配制ETags

虽然标题叫配制ETags,但是这里你要根据具体情况进行一些判断。首先Etag简单来说是通过一个文件版本标识使得服务器可以轻松判断该请求的内容是否有所更新,如果没有就回复304 (not modified),从而避免下载整个文件。

但是Etags的版本信息即使主流服务器未能很好地支持跨服务器的判断,比如你从一个服务器集群中一台得到Etags,然后发送到了另一台那么校验很有可能会失败。

⑤尽早flush输出

网页后台程序中我们知道有个方法叫Response.FLush(),一般我们调用它都是在程序末尾,但注意这个方法可以被调用多次。目的是可以将现有的缓存中的回复内容先发给客户端,让客户端“有活干”。那在什么时候调用这个方法比较好呢?一般情况下我们可以在对于需要加载比较多外部脚本或者样式表时可以提前调用一次,客户端收到了关于脚本或其他外部资源的链接可以并行的先发请求去下载,服务器接下来把后续的处理结果发给客户端。

⑥使用GET Ajax请求

浏览器在实现XMLHttpRequest POST的时候分成两步,先发header,然后发送数据。而GET却可以用一个TCP报文完成请求。另外GET从语义上来讲是去服务器取数据,而POST则是向服务器发送数据,所以我们使用Ajax请求数据的时候尽量通过GET来完成。 

⑦避免空的图片src

空的图片src仍然会使浏览器发送请求到服务器,这样完全是浪费时间,而且浪费服务器的资源。尤其是你的网站每天被很多人访问的时候,这种空请求造成的伤害不容忽略。浏览器如此实现也是根据RFC 3986 - Uniform Resource Identifiers标准,空的src被定义为当前页面。


三、COOkie

①减小Cookie

Cookie被用来做认证或个性化设置,其信息被包含在http报文头中,对于cookie我们要注意以下几点,来提高请求的响应速度:

-- 去除没有必要的cookie,如果网页不需要cookie就完全禁掉;

-- 注意cookie设置的domain级别,没有必要情况下不要影响到sub-domain;

-- 设置合适的过期时间,比较长的过期时间可以提高响应速度;

②页面内容使用无Cookie域名

大多数网站的静态资源都没必要cookie,我们可以采用不同的domain来单独存放这些静态文件,这样做不仅可以减少cookie大小从而提高响应速度,还有一个好处是有些proxy拒绝缓存带有cookie的内容,如果能将这些静态资源cookie去除,那就可以得到这些proxy的缓存支持。


四、CSS

①将css置顶

经样式表(css)放在网页的HEAD中会让网页显得加载速度更快,因为这样做可以使浏览器逐步加载已将下载的网页内容。这对内容比较多的网页尤其重要,用户不用一直等待在一个白屏上,而是可以先看已经下载的内容。 

②避免css表达式

CSS表达式的问题在于它被重新计算的次数远比我们想象的要多,不仅在网页绘制或大小改变时计算,即使我们滚动屏幕或者移动鼠标的时候也在计算,因此我们还是尽量避免使用它来防止使用不当而造成的性能损耗。 如果想达到某种效果我们可以通过简单的脚本做到。

③用<link>代替@import

避免使用@import的原因很简单,因为它相当于将css放在网页内容底部。

④避免使用Filters

AlphaImageLoad是IE5.5 - IE8中支持,这种滤镜的使用会导致图片在下载的时候阻塞网页绘制,另外使用这种滤镜会导致内存使用量的问题。IE9中已经不再支持。


五、JavaScript

①将脚本置底

HTTP/1.1 specification 建议浏览器对同一个hostname不要超过两个并行下载连接, 所以当你从多个domain下载图片的时候可以提高并行下载连接数量。但是当脚本在下载的时候,即使是来自不同的hostname浏览器也不会下载其他资源,因为浏览器要在脚本下载之后依次解析和执行。

②使用外部JS和CSS文件

-- 使用外部Javascript和CSS文件可以使这些文件被浏览器缓存,从而在不同的请求内容之间重用。

-- 同时将Javascript和CSS从inline变为external也减小了网页内容的大小。

-- 使用外部Javascript和CSS文件的决定因素在于这些外部文件的重用率,如果用户在浏览我们的页面时会访问多次相同页面或者可以重用脚本的不同页面,那么外部文件形式可以为你带来很大的好处。

③使用智能事件处理

这里说智能的事件处理需要开发者对事件处理有更深入的了解,通过不同的方式尽量少去触发事件,如果必要就尽早的去处理事件。

比如一个div中10个按钮都需要事件句柄,那么我们可以将事件放在div上,在事件冒泡过程中捕获该事件然后判断事件来源。


六、图片

①优化图片

当美工完成了网站的图片设计后,我们可以在上传图片之前对其做以下优化:

-- 检查GIF图片中图像颜色的数量是否和调色板规格一致。如果你发现图片中只用到了4种颜色,而在调色板的中显示的256色的颜色槽,那么这张图片就还有压缩的空间。

-- 尝试把GIF格式转换成PNG格式,看看是否节省空间。大多数情况下是可以压缩的。

-- 在所有的PNG图片上运行pngcrush (或者其它PNG优化工具)。

-- 在所有JPEG图片上运行jpegtran。这个工具可以对图片中的出现的锯齿等做无损操作,同时它还可以用于优化和清除图片中的注释以及其它无用信息。

②不要在HTML中缩放图片

不要通过图片缩放来适应页面,如果你需要小图片,就直接使用小图片吧。

③使用小且可缓存的favicon.ico

网站图标文件favicon.ico,不管你服务器有还是没有,浏览器都会去尝试请求这个图标。所以我们要确保这个图标存在,并使文件尽量小,且设置一个较长的过期时间。


七、移动客户端

①保持单个文件小于25KB

这限制是因为iphone,他只能缓存小于25K,注意这是解压后的大小。所以单纯gzip不一定够用,精简文件工具要用上了。

②打包组建成符合文档

把页面内容打包成复合文本就如同带有多附件的Email,它能够使你在一个HTTP请求中取得多个组建。当你使用这条规则时,首先要确定用户代理是否支持(iPhone不支持)。



原文:http://www.zhihu.com/question/21057713