再谈Yahoo关于网站性能优化的N条策略
一、 Yahoo的军规条例:谨记:80%-90%的终端响应时间是花费在下载页面中的图片,样式表,脚本,flash等; 1、尽量减少HTTP请求个数——须权衡 合并图片(如css sprites,内置图片使用数据)、合并CSS、JS,这一点很重要,但是要考虑合并后的文件体积。 2、使用CDN(内容分发网络) 这里可以关注CDN的三类实现:镜像、高速缓存、专线,以及智能路由器和负载均衡; 3、为文件头指定Expires或Cache-Control,使内容具有缓存性。 区分静态内容和动态内容,避免以后页面访问中不必要的HTTP请求。 4、避免空的src和href 留意具有这两个属性的标签如link,script,img,iframe等; 5、使用gzip压缩内容 Gzip压缩所有可能的文件类型以来减少文件体积 6、把CSS放到顶部 实现页面有秩序地加载,这对于拥有较多内容的页面和网速较慢的用户来说更为重要,同时,HTML规范清楚指出样式表要放包含在页面的<head />区域内; 7、把JS放到底部 HTTP/1.1 规范建议,浏览器每个主机名的并行下载内容不超过两个,而问题在于脚本阻止了页面的平行下载,即便是主机名不相同 8、避免使用CSS表达式 页面显示和缩放,滚动、乃至移动鼠标时,CSS表达式的计算频率是我们要关注的。可以考虑一次性的表达式或者使用事件句柄来代替CSS表达式。 9、将CSS和JS放到外部文件中 我们需要权衡内置代码带来的HTTP请求减少与通过使用外部文件进行缓存带来的好处的折中点。 10、减少DNS查找次数 我们需要权衡减少 DNS查找次数和保持较高程度并行下载两者之间的关系。 11、精简CSS和JS 目的就是减少下载的文件体积,可考虑压缩工具JSMin和YUI Compressor。 12、避免跳转 为了确保“后退”按钮可以正确地使用,使用标准的 3XXHTTP状态代码;同域中注意避免反斜杠 “/” 的跳转; 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可缓存 利用时间戳,更精巧的实现响应可缓存与服务器数据同步更新。 16、尽早刷新输出缓冲 尤其对于css,js文件的并行下载更有意义 17、使用GET来完成AJAX请求 当使用XMLHttpRequest时,浏览器中的POST方法是一个“两步走”的过程:首先发送文件头,然后才发送数据。在url小于2K时使用GET获取数据时更加有意义。 18、延迟加载 确定页面运行正常后,再加载脚本来实现如拖放和动画,或者是隐藏部分的内容以及折叠内容等。 19、预加载 关注下无条件加载,有条件加载和有预期的加载。 20、减少DOM元素个数 使用更适合或者在语意是更贴切的标签,要考虑大量DOM元素中循环的性能开销。 21、根据域名划分页面内容 很显然, 是最大限度地实现平行下载 22、尽量减少iframe的个数 考虑即使内容为空,加载也需要时间,会阻止页面加载,没有语意,注意iframe相对于其他DOM元素高出1-2个数量级的开销,它会在典型方式下阻塞onload事件,IE和Firefox中主页面样式表会阻塞它的下载。 23、避免404 HTTP请求时间消耗是很大的,有些站点把404错误响应页面改为“你是不是要找***”,这虽然改进了用户体验但是同样也会浪费服务器资源(如数据库等)。最糟糕的情况是指向外部 JavaScript的链接出现问题并返回404代码。首先,这种加载会破坏并行加载;其次浏览器会把试图在返回的404响应内容中找到可能有用的部分当作JavaScript代码来执行。 24、减少Cookie的大小 去除不必要的coockie 25、使用无cookie的域 确定对于静态内容的请求是无coockie的请求。创建一个子域名并用他来存放所有静态内容。 26、减少DOM访问 缓存已经访问过的有关元素 27、开发智能事件处理程序 有时候我们会感觉到页面反应迟钝,这是因为DOM树元素中附加了过多的事件句柄并且些事件句病被频繁地触发。这就是为什么说使用event delegation(事件代理)是一种好方法了。如果你在一个div中有10个按钮,你只需要在div上附加一次事件句柄就可以了,而不用去为每一个按 钮增加一个句柄。事件冒泡时你可以捕捉到事件并判断出是哪个事件发出的。 28、用<link>代替@import 在IE中,页面底部@import和使用<link>作用是一样的,因此最好不要使用它。 29、避免使用滤镜 完全避免使用AlphaImageLoader的最好方法就是使用PNG8格式来代替,这种格式能在IE中很好地工作。如果你确实需要使用 AlphaImageLoader,请使用下划线_filter又使之对IE7以上版本的用户无效。 30、优化图像 尝试把GIF格式转换成PNG格式,看看是否节省空间。在所有的PNG图片上运行pngcrush(或者其它PNG优化工具) 31、优化CSS Spirite 在Spirite中水平排列你的图片,垂直排列会稍稍增加文件大小; 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带来的弊端,要做到: 34、保持单个内容小于25K 因为iPhone不能缓存大于25K的文件。注意这里指的是解压缩后的大小。由于单纯gizp压缩可能达不要求,因此精简文件就显得十分重 要。 35、打包组件成复合文本 页面内容打包成复合文本就如同带有多附件的Email,它能够使你在一个HTTP请求中取得多个组件(切记:HTTP请求是很奢侈的)。当你使用这条规 则时,首先要确定用户代理是否支持(iPhone就不支持)。 二、Yahoo军规之外的场景?1、 使用json作为数据的交换格式 针对Yslow的不要在HTML中缩放图像——第33条,有人会误解为不要对图片加宽高值,其实这条建议本身的意思是不要为了获取一个特定大小的图片,而去强行通过设置宽高值拉伸或者压缩一个既有的图片。建议是另存一张符合尺寸的图片替代。 3、 拆离内容块 尽量用div取代tables,或者将tables打破成嵌套层次深的结构; 避免用这样的嵌套 <table> <table> <table> ... </table> </table> </table> 采用下面的或者div重构: <table></table> <table></table> <table></table> 4、 高效的CSS书写规则 众所周知,CSS选择符是从右向左进行匹配的。 <div id="box"> <div class="hd"> <h3>我的旅途</h3> </div> <div class="bd"> <h4>旅途1</h4> <ul id="pics"> <li><a href="#pic" title=""><img src="" alt="" /></a><p>这是在<strong>图片1</strong></p></li> </ul> </div> </div> 为了代码上缩进后内层的整洁性,我们html有可能这样写之外,更喜欢看这样的css写法: .box{border:1px solid #ccc } .box .hd{border-bottom:1px solid #ccc } .box .hd h3{color:#515151} .box .bd{color:#404040 } .box .bd ul{margin-left:10px} .box .bd ul li{border-bottom:1px dashed #f1f1f1} .box .bd ul li a{text-decoration:none} .box .bd ul li a:hover{text-decoration:underline} .box .bd ul li a img{border:1px solid #ccc} .box .bd ul li p{text-align:left;} .box .bd ul li p strong{color:#ff6600} 其实写到这里,问题已经显而易见了。深达五层抑或六层的嵌套,同时右边的选择符都是采用标签,在满足我们视觉平整与代码结构系统化的时候,付出的是性能的代价。 不做进一步的代码书写方式的探讨,受个人习惯与应用场景影响。这里对css选择符按照开销从小到大的顺序梳理一下:
参考《高性能网站建设-进阶指南》,有如下建议:
还要注意到,即便是页面加载后,当页面被触发引起回流(reflow)的时候,低效的选择符依然会引发更高的开销,显然这对于用户是不佳的体验。 三、Yahoo军规再度挖掘会怎样?在网站性能优化的路上,是不会有终点的,这也是前端工程师永不会妥协的地方。
? (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |