前端优化之雅虎(Yahoo)军规14条规则
相信很多⼈都听过优化⽹站性能的雅虎军规14条规则,下⾯就详细介绍⼀下这14条规则的优化吧
image
第⼀条、尽可能的减少 HTTP 的请求数 (Make Fewer HTTP Requests )
http请求是要开销的,想办法减少请求数⾃然可以提⾼⽹页速度。常⽤的⽅法,合并css,js(将⼀个页
⾯中的css和js⽂件分别合并)以及Image maps和css sprites等。当然或许将css,js⽂件拆分多个是因为css结构,共⽤等⽅⾯的考虑。阿⾥巴巴中⽂站当时的做法是开发时依然分开开发,然后在后台 对js,css进⾏合并,这样对于浏览器来说依然是⼀个请求,但是开发时仍然能还原成多个,⽅便管理和重复引⽤。yahoo 甚⾄建议将⾸页的css和js 直接写在页⾯⽂件⾥⾯,⽽不是外部引⽤。因为⾸页的访问量太⼤了,这么做也可以减少两个请求数。⽽事实上国内的很多门户都是这么做的。
⽽css sprites是指只⽤将页⾯上的背景图合并成⼀张,然后通过css的background-position属性定义不过的值来取他的背景。淘宝和阿⾥巴巴中⽂站⽬前都是这样做的。有兴趣的可以看下淘宝和阿⾥巴巴的背景图。
第⼆条、使⽤CDN(内容分发⽹络): Use a Content Delivery Network
说实话,对于CDN这⼀块⾃⼰并不是很了解,简单地讲,通过在现有的Internet中增加⼀层新的⽹络架构,将⽹站的内容发布到最接近⽤户的cache服务器内,通过DNS负载均衡的技术,判断⽤户来源就近访问cache服务器取得所需的内容,杭州的⽤户访问近杭州服务器上的内容,北京的访问 近北京服务器上的内容。这样可以有效减少数据在⽹络上传输的时间,提⾼速度。更详细地内容⼤家可以参考百度百科上对于CDN的解释。Yahoo!把静态内容分布到CDN减少了⽤户影响时间20%或更多。
CDN技术⽰意图:
image.png
CDN组⽹⽰意图:
image.png
第三条、 添加Expire/Cache-Control 头:Add an Expires Header
现在越来越多的图⽚,脚本,css,flash被嵌⼊到页⾯中,当我们访问他们的时候势必会做许多次的http请求。其实我们可以通过设置Expires header 来缓存这些⽂件。Expire其实就是通过header报⽂来指定特定类型的⽂件在览器中的缓存时间。⼤多数的图⽚,flash在发布后都是不需要经常修改的,做了缓存以后这样浏览器以后就不需要再从服务器下载这些⽂件⽽是⽽直接从缓存中读取,这样再次访问页⾯的速度会⼤⼤加快。⼀个典型的HTTP 1.1协议返回的头信息:
| HTTP/1.1 200 OK
Date: Fri, 30 Oct 1998 13:19:41 GMT
Server: Apache/1.3.3 (Unix)
Cache-Control: max-age=3600, must-revalidate
Expires: Fri, 30 Oct 1998 14:19:41 GMT
Last-Modified: Mon, 29 Jun 1998 02:28:12 GMT
ETag: “3e86-410-3596fbbc”
css中的position属性Content-Length: 1040
Content-Type: text/html |
据我了解,⽬前阿⾥巴巴中⽂站的Expires过期时间是30天。不过期间也有过问题,特别是对于脚本过期时间的设置还是应该仔细考虑下,不然相应的脚本功能更新后客户端可能要过很长⼀段时间才能“感知”到这样的变化。所以,哪些应该缓存,哪些不该缓存还是应该仔细斟酌⼀番。
第四条、启⽤Gzip压缩:Gzip Components
Gzip的思想就是把⽂件先在服务器端进⾏压缩,然后再传输。这样可以显著减少⽂件传输的⼤⼩。传输完毕后浏览器会 重新对压缩过的内容进⾏解压缩,并执⾏。⽬前的浏览器都能“良好”地⽀持 gzip。不仅浏览器可以识别,⽽且各⼤“爬⾍”也同样可以识别,各位seoer可以放下⼼了。⽽且gzip的压缩⽐例⾮常⼤,⼀般压缩率为85%,就是 说服务器端100K的页⾯可以压缩到25K左右再发送到客户端。具体的Gzip压缩原理⼤家可以参考csdn上的《gzip压缩算法》 这篇⽂章。雅虎特别强调, 所有的⽂本内容都应该被gzip压缩: html (php), js, css, xml, txt… 这⼀点我们⽹站做得不错,是⼀个A。以前我们的⾸页也并不是A,因为⾸页上还有很多⼴告代码投放的js,这些⼴告代码拥有者的⽹站的js没有经过gzip压缩,也会拖累我们⽹站。
以上三点⼤多属于服务器端的内容,本⼈也是粗浅地了解⽽已。说得不对的地⽅有待各位指正。
第五条、将css放在页⾯最上⾯ ( Put Stylesheets at the Top)
将css放在页⾯最上⾯,这是为什么?因为 ie,firefox等浏览器在css全部传输完全之前不会去渲染任何的东西。理由诚如⼩马哥说得那样很简单。css,全称Cascading Style Sheets (层叠样式表单)。层叠即意味这后⾯的css可以覆盖前⾯的css,级别⾼的css可以覆盖级别低的css。在[css之!important] 这篇⽂章的最下⾯曾简单地提到过这层级关系,这⾥我们只需要知道css可以被覆盖的。既然前⾯的可以被覆盖,浏览器在他完全加载完毕之后再去渲染⽆疑也是合情合理的很多浏览器下,如IE,把样式表放在页⾯的底部的问题在于它禁⽌了⽹页内容的顺序显⽰。浏览器阻⽌显⽰以免重画页⾯元素,那⽤户只能看到空⽩页了。Firefox不会阻⽌显⽰,但这意味着当样式表下载后,有些页⾯元素可能需要重画,这导致闪烁问题。所以我们应该尽快让css加载完毕
顺着这层意思,如果我们再细究的话,其实还有可以优化的地⽅。⽐如本站上⾯包含的两个css⽂件,
第六条、将script放在页⾯最下⾯ (Put Scripts at the Bottom )
将脚本放在页⾯最下⾯的⽬的有那么两点:
1、 因为防⽌script脚本的执⾏阻塞页⾯的下载。在页⾯loading的过程中,当浏览器读到js执⾏语句的
时候⼀定会把它全部解释完毕后在会接下来读下 ⾯的内容。不信你可以写⼀个js死循环看看页⾯下⾯的东西还会不会出来。(setTimeout 和 setInterval的执⾏有点类似于多线程,在相应的响应时间之前也会继续下⾯的内容渲染。)浏览器这么做的逻辑是因为js随时可能执 ⾏ location.href或是其他可能完全中断此页⾯过程的函数,即如此,当然得等他执⾏完毕之后再加载咯。所以放在页⾯最后,可以有效减少页⾯可 视元素的加载时间。
2、脚本引起的第⼆个问题是它阻塞并⾏下载数量。HTTP/1.1规范建议浏览器每个主机的并⾏下载数不超过2个(IE只能为2个,其他浏览器如ff 等都是默认设置为2个,不过新出的ie8可以达6个)。因此如果您把图像⽂件分布到多台机器的话,您可以达到超过2个的并⾏下载。但是当脚本⽂件下载时,浏览器不会启动其他的并⾏下载。
当然对各个⽹站来说,把脚本都放到页⾯底部加载的可⾏性还是值得商榷的。就⽐如阿⾥巴巴中⽂站的页⾯。很多地⽅有内联的js,页⾯的显⽰严重依赖于此,我承认这和⽆侵⼊脚本的理念相差甚远,但是很多“历史遗留问题”却不是那么容易解决的。
第七条、避免在CSS中使⽤Expressions (Avoid CSS Expressions )
不过这样就多了两层⽆意义的嵌套,肯定不好。还需要⼀个更好的办法。
第⼋条、把javascript和css都放到外部⽂件中 (Make JavaScript and CSS External )
这点我想还是很容易理解的。不仅从性能优化上会这么做,⽤代码易于维护的⾓度看也应该这么做。把css和js写在页⾯内容可以减少2次请求,但也增 ⼤了页⾯的⼤⼩。如果已经对css和js做了缓存,那也就没有2次多余的http请求了。当然,我在前⾯中也说过,有些特殊的页⾯开发⼈员还是会选择内联 的css和js⽂件。
第九条、减少DNS查询 (Reduce DNS Lookups)
在 Internet上域名与IP地址之间是⼀⼀对应的,域名(kuqin)很好记,但计算机不认识,计算机之间的“相认”还要转成ip地址。在⽹络上每台计算机都对应有⼀个独⽴的ip地址。在域名和ip地址之间的转换⼯作称为域名解析,也称DNS查询。⼀次DNS的解析过程会消耗20-120毫秒的 时间,在dns查询结束之前,浏览器不会下载该域名下的任何东西。所以减少dns查询的时间可以加快页⾯的加载速度。yahoo的建议⼀个页⾯所包含的域 名数尽量控制在2-4个。这就需要对页⾯整体有⼀个很好的规划。⽬前我们这点做的不好,很多打点的⼴告投放系统拖累了我们。
第⼗条、压缩 JavaScript 和 CSS (Minify JavaScript )
image.png
当然,压缩带来的⼀个弊端就是代码的可读性没了。相信很多做前端的朋友都遇到过这个问题:看Google的效果很酷,可是去看他的源代码却是⼀⼤堆 挤在⼀起的字符,连函数名都是替换过的,汗死!⾃⼰的代码也这样岂不是对维护⾮常不⽅便。所有阿⾥巴巴中⽂站⽬前采⽤的做法是在js和css发布的时候在 服务器端进⾏压缩。这样在我们很⽅便地维护⾃⼰的代码。
第⼗⼀条、避免重定向 (Avoid Redirects )
第⼗⼆条、移除重复的脚本 (Remove Duplicate Scripts )
这点我想不说也知道,不仅是从性能上考虑,代码规范上看也是这样。但是不得不承认,很多时候我们会因为图⼀时之快⽽加上⼀些或许是重复的代码。或许⼀个统⼀的css框架和js框架可以⽐较好的解决我们的问题。⼩猪的观点很对,不仅是要做到不重复,更是要做到可重⽤。
第⼗三条、配置实体标签(ETags) (Configure ETags )
这点我也不懂,呵呵。在inforQ上到⼀篇解释得⽐较详细的说明《使⽤ETags减少Web应⽤带宽和负载》,有兴趣的同学可以去看看。
第⼗四条、使 AJAX 缓存 (Make Ajax Cacheable )
ajax还要去缓存?做ajax请求的时候往往还要增加⼀个时间戳去避免他缓存。It’s important to remember that “asynchronous” does not imply “instantaneous”.(记住“异步”不是“瞬间”这⼀点很重要)。记住,即使AJAX是动态产⽣的⽽且只对⼀个⽤户起作⽤,他们依然可以被缓存。

版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系QQ:729038198,我们将在24小时内删除。