yahoo军规的思考
针对优化性能,提高网站加载速度,雅虎给出了一系列方案,网上也流传很多个版本,但是基本大同小异
1、减少HTTP请求
合并图片(如css sprites,内置图片使用数据)、合并CSS、JS,原理比较简单,用户通过浏览器进行下载,但是浏览器允许的并发请求资源数最多是8个,也就是浏览器最多只能从一个服务器上同时下载8个文件,因此需要下载的文件数量过多时会影响页面加载速度,合并资源能有效的减少需要下载的文件数量,当然如果追求加载速度也可以之后把一些文件放在其他服务器上。
2、使用CDN(内容分发网络)
将源站内容分发至全国所有的节点,缩短用户查看对象的延迟,提高用户访问网站的响应速度与网站的可用性,解决网络带宽小、用户访问量大、网点分布不均等问题。
对于这一条我不太了解,查了一下,大概是说用一层虚拟网对当前网络情况,用户信息等进行分析,把用户重新导向一个最优的服务节点上。
3、为文件头指定Expires或Cache-Control,使内容具有缓存性。
4、避免空的src和href
留意具有这两个属性的标签如link,script,img,iframe等。
5、使用gzip压缩内容
Gzip压缩所有可能的文件类型以来减少文件体积。
这个很厉害,是在服务器端对文件进行压缩,大概能压缩50%左右。
6、把样式表放到顶部
实现页面有秩序地加载,这对于拥有较多内容的页面和网速较慢的用户来说更为重要,同时,HTML规范清楚指出样式表要放包含在页面的<head />区域内。
7、把JS放到底部
对于这个我的看法有点不太一样,觉得并不是所有情况都适用,当然这么做也没什么问题。
8、避免使用CSS表达式
页面显示和缩放,滚动、乃至移动鼠标时,CSS表达式的计算频率是我们要关注的。可以考虑一次性的表达式或者使用事件句柄来代替CSS表达式。CSS表达式是一个功能强大的(和危险)的方式来动态设置CSS属性。 他们支持在Internet Explorer开始用5版本,但被废弃的开始与IE8。
9、将CSS和JS放到外部文件中
在现实世界中使用的外部文件通常产生更快的页面,因为JavaScript和CSS文件由浏览器高速缓存。 JavaScript和CSS的内联在HTML文档获取下载HTML文档请求每次。 这减少了所需的HTTP请求的数量,但会增加HTML文档的大小。 另一方面,如果该JavaScript和CSS是在由浏览器高速缓存的外部文件,HTML文件的尺寸减小,而不增加HTTP请求的数目。我们需要权衡内置代码带来的HTTP请求减少与通过使用外部文件进行缓存带来的好处的折中点。
10、减少DNS查询
我们需要权衡减少 DNS查找次数和保持较高程度并行下载两者之间的关系。域名系统(DNS)映射主机名到IP地址,就像电话簿映射人的名字,以他们的电话号码。 当你键入www.yahoo.com到浏览器,由浏览器所接触的DNS解析返回该服务器的IP地址。 DNS是有成本的。 它通常需要20-120毫秒的DNS查找IP地址,一个给定的主机名。 直到DNS查询完成后,浏览器无法从该主机下载任何东西。
11、精简CSS和JS
这需要在前端开发工作中对一些文件进行处理,从代码中删除不必要的字符,以减小其尺寸,从而提高了加载时间。比如css,js这些文件进行压缩,也就是格式化处理,有些像gulp这样的构建工具在压缩时设置mangle: true或不设置,会对代码进行一些处理,比如改变变量名,这也是一种压缩的手段,但是这种压缩是不可逆的,使用时需要注意。
12、避免重定向
重定向使用的301和302的状态码来完成的。重定向拖慢了用户体验。 插入用户和HTML文档之间的重定向延迟一切在因为没有在可以呈现该页面的页面和没有组件可以就被下载到HTML文档已经到来。为了确保“后退”按钮可以正确地使用,使用标准的 3XXHTTP状态代码;同域中注意避免反斜杠 “/” 的跳转;跨域使用 Alias或者 mod_rewirte建立 CNAME(保存一个域名和另外一个域名之间关系的DNS记录)。
13、剔除重复的JS和CSS
重复调用脚本,除了增加额外的HTTP请求外,多次运算也会浪费时间。在IE和Firefox中不管脚本是否可缓存,它们都存在重复运算JavaScript的问题。
14、配置ETags
Entity tags(ETags)(实体标签)是web服务器和浏览器用于判断浏览器缓存中的内容和服务器中的原始内容是否匹配的一种机制(“实体”就是所说的“内 容”,包括图片、脚本、样式表等),是比last-modified date更更加灵活的机制,单位时间内文件被修过多次,Etag可以综合Inode(文件的索引节点(inode)数),MTime(修改时间)和Size来精准的进行判断,避开UNIX记录MTime只能精确到秒的问题。 服务器集群使用,可取后两个参数。使用ETags减少Web应用带宽和负载。
15、使得AJAX可缓存
利用时间戳,更精巧的实现响应可缓存与服务器数据同步更新。好处是,它提供瞬时反馈给用户,因为它请求信息异步从后端网络服务器。 但是,使用Ajax是不能保证该用户将不被摆弄他的拇指等待这些异步JavaScript和XML响应返回。 在许多应用中,用户是否被保持等待取决于Ajax如何被使用。 例如,在一个基于Web的电子邮件客户端的用户将保持等待一个Ajax请求的结果发现所有符合他们的搜索条件的电子邮件。 重要的是要记住,“异步”并不意味着“瞬间”。
16、尽早刷新输出缓冲
尤其对于css,js文件的并行下载更有意义,当用户请求一个页面,它可以在任何地方,从200到500毫秒的后端服务器缝合在一起的HTML页面。在此期间,该浏览器是空闲,因为它等待数据到达。在PHP中有函数flush()。它可以让你把你的部分准备HTML响应到浏览器,这样浏览器就可以开始获取组件,同时后端忙于在HTML页面的其余部分。这样做的好处主要是看到忙碌的后端或轻前端。
17、使用GET的AJAX请求
当使用XMLHttpRequest时,浏览器中的POST方法是一个“两步走”的过程:首先发送文件头,然后才发送数据。在url小于2K时使用GET获取数据时更加有意义。在雅虎 邮件研究小组发现,当使用XMLHttpRequest的,POST将在浏览器中实现为两个步骤:首先发送标题,然后发送数据。所以最好使用GET,只需要一个TCP数据包发送(除非你有很多的饼干)。最大URL长度在IE浏览器是2K,所以如果你发送超过2K的数据,你可能无法使用GET。一个有趣的影响是,POST没有实际公布任何数据的行为以获得更多信息。基于对HTTP规范,GET意味着用于检索信息,因此它是有道理的(语义)使用GET,当你只请求数据,而不是将数据发送到存储服务器端。
18、延迟加载
确定页面运行正常后,再加载脚本来实现如拖放和动画,或者是隐藏部分的内容以及折叠内容等。
19、预加载
关注下无条件加载,有条件加载和有预期的加载。
20、减少DOM元素的数量
使用更适合或者在语意是更贴切的标签,要考虑大量DOM元素中循环的性能开销。
21、跨域分离组件
拆分组件,您可以最大限度地提高并行下载。请确保您使用的是不超过2-4个域名,因为DNS查找处罚。例如,您可以承载你的HTML和动态内容的www.example.org和拆分静态组件之间static1.example.org和static2.example.org, 是最大限度地实现平行下载
22、尽量减少iframe的个数
考虑即使内容为空,加载也需要时间,会阻止页面加载,没有语意,注意iframe相对于其他DOM元素高出1-2个数量级的开销,它会在典型方式下阻塞onload事件,IE和Firefox中主页面样式表会阻塞它的下载。
<IFRAME>优点:
有助于像徽章和广告慢第三方内容
安全沙箱
并行下载脚本
<IFRAME>的缺点:
即使空白不惜血本
块页面的onload
非语义
23、避免404
HTTP请求是昂贵,因此使得HTTP请求,并得到一个无用的反应(即404未找到)是完全不必要的,并会减慢没有任何好处的用户体验。
HTTP请求时间消耗是很大的,有些站点把404错误响应页面改为“你是不是要找***”,这虽然改进了用户体验但是同样也会浪费服务器资源(如数据库等)。最糟糕的情况是指向外部 JavaScript的链接出现问题并返回404代码。首先,这种加载会破坏并行加载;其次浏览器会把试图在返回的404响应内容中找到可能有用的部分当作JavaScript代码来执行。
24、减少Cookie的大小
去除不必要的coockie
使coockie体积尽量小以减少对用户响应的影响
注意在适应级别的域名上设置coockie以便使子域名不受影响
设置合理的过期时间。较早地Expire时间和不要过早去清除coockie,都会改善用户的响应时间。
25、使用无cookie的域
确定对于静态内容的请求是无coockie的请求。创建一个子域名并用他来存放所有静态内容。
26、最大限度减少DOM访问
缓存已经访问过的有关元素
线下更新完节点之后再将它们添加到文档树中
避免使用JavaScript来修改页面布局
27、开发智能事件处理程序
有时候我们会感觉到页面反应迟钝,这是因为DOM树元素中附加了过多的事件句柄并且些事件句病被频繁地触发。这就是为什么说使用event delegation(事件代理)是一种好方法了。如果你在一个div中有10个按钮,你只需要在div上附加一次事件句柄就可以了,而不用去为每一个按 钮增加一个句柄。事件冒泡时你可以捕捉到事件并判断出是哪个事件发出的。
你同样也不用为了操作DOM树而等待onload事件的发生。你需要做的就是等待树结构中你要访问的元素出现。你也不用等待所有图像都加载完毕。
你可能会希望用DOMContentLoaded事件来代替 事件应用程序中的onAvailable方法。
28、用<link>代替@import
在IE中,页面底部@import和使用<link>作用是一样的,因此最好不要使用它。
29、避免使用滤镜
完全避免使用AlphaImageLoader的最好方法就是使用PNG8格式来代替,这种格式能在IE中很好地工作。如果你确实需要使用 AlphaImageLoader,请使用下划线_filter又使之对IE7以上版本的用户无效。
30、优化图像
尝试把GIF格式转换成PNG格式,看看是否节省空间。在所有的PNG图片上运行pngcrush(或者其它PNG优化工具)
31、优化CSS Spirite
CSS精灵是减少图像的请求的数量的优选的方法。 结合你的背景图像转换成一个单一的形象,并使用CSS background-image和background-position属性来显示所需的图像片段。
在Spirite中水平排列你的图片,垂直排列会稍稍增加文件大小;
Spirite中把颜色较近的组合在一起可以降低颜色数,理想状况是低于256色以便适用PNG8格式;
便于移动,不要在Spirite的图像中间留有较大空隙。这虽然不大会增加文件大小但对于用户代理来说它需要更少的内存来把图片解压为像素地图。 100×100的图片为1万像素,而1000×1000就是100万像素。
32、不要在HTML中缩放图像——须权衡
不要为了在HTML中设置长宽而使用比实际需要大的图片。如果你需要:
<img width=”100″ height=”100″ src=”mycat.jpg” alt=”My Cat” />
那么你的图片(mycat.jpg)就应该是100×100像素而不是把一个500×500像素的图片缩小使用。这里在下文有更有趣的分析。
33、favicon.ico要小和可缓存
favicon.ico是位于服务器根目录下的一个图片文件。它是必定存在的,因为即使你不关心它是否有用,浏览器也会对它发出请求,因此最好不要返回一 个404 Not Found的响应。由于是在同一台服务器上,它每被请求一次coockie就会被发送一次。这个图片文件还会影响下载顺序,例如在IE中当你在 onload中请求额外的文件时,favicon会在这些额外内容被加载前下载。
因此,为了减少favicon.ico带来的弊端,要做到:
文件尽量地小,最好小于1K
在适当的时候(也就是你不要打算再换favicon.ico的时候,因为更换新文件时不能对它进行重命名)为它设置Expires文件头。你可以很安全地 把Expires文件头设置为未来的几个月。你可以通过核对当前favicon.ico的上次编辑时间来作出判断。
Imagemagick可以帮你创建小巧的favicon。
34、保持单个内容小于25K
因为iPhone不能缓存大于25K的文件。注意这里指的是解压缩后的大小。由于单纯gizp压缩可能达不要求,因此精简文件就显得十分重 要。
35、打包组件成复合文本
页面内容打包成复合文本就如同带有多附件的Email,它能够使你在一个HTTP请求中取得多个组件(切记:HTTP请求是很奢侈的)。当你使用这条规 则时,首先要确定用户代理是否支持(iPhone就不支持)。