雅虎军规——前端优化的35条建议

无论是在工作中,还是在面试中,web前端性能的优化都是很重要的,那么我们进行优化需要从哪些方面入手呢?yohoo关于性能优化的35条的军规,web2.0的设计与视觉,用户越来越注重用户体验,但用户体验的前提就是网站的访问速度,对于一个大型网站的yahoo来说,处理性能优化是不可缺少的,他是怎么制定性能优化呢,相比很多朋友都想了解下,YaHoo把性能优化作为他们不可触犯的军规,具体怎样优化呢,且看他们的优化方案。

80%-90%的终端响应时间是花费在下载页面中的图片,样式表,脚本,flash等;雅虎军规可以分类7大类35条,包括内容、服务器、CSS、JS、Cookie、图片、移动应用。现在说一些常用的规则。

1、尽可能减少HTTP请求数

那么什么是HTTP请求呢?——从客户端到服务器端的请求消息,包括消息首行中,对资源的请求方法资源的标识符及使用的协议。通俗一点说就是:当你打开网页的时候,你所看到的文字、图片、多媒体等等,这一切内容,都是从服务器获取的。每一个内容的获取,就是一个HTTP请求。

合并文件:把所有的脚本放到一个文件中来减少HTTP请求。比如合并项目中的JS、CSS。

CSS Sprites是减少图片请求数量的首选方式。把背景图片都整合到一张图片中,然后用CSS的background-image和background-position属性来定位要显示的部分。

减少页面的HTTP请求数是个起点,这是提升站点首次访问速度的重要指导原则。

了解这个只是对于我们网站设计和优化有何启示呢?

  1. 由于DNS查找是需要时间的,而且它们通常都是只缓存一定的时间,所以应该尽可能地减少DNS查找的次数。

  2. 减少DNS查找次数,最理想的方法就是将所有的内容资源都放在同一个域(Domain)下面,这样访问整个网站就只需要进行一次DNS查找,这样可以提高性能。

  3. 但理想总归是理想,上面的理想做法会带来另外一个问题,就是由于这些资源都在同一个域,而HTTP /1.1 中推荐客户端针对每个域只有一定数量的并行度(它的建议是2),那么就会出现下载资源时的排队现象,这样就会降低性能。

  4. 所以,折衷的做法是:建议在一个网站里面使用至少2个域,但不多于4个域来提供资源。我认为这条建议是很合理的,也值得我们在项目实践中去应用。

2、减少DNS查询

域名系统建立了主机名和IP地址间的映射,就像电话簿上人名和号码的映射一样。当你在浏览器输入www.yahoo.com的时候,浏览器就会联系DNS解析器返回服务器的IP地址。DNS是有成本的,它需要20到120毫秒去查找给定主机名的IP地址。在DNS查找完成之前,浏览器无法从主机名下载任何东西。

大多数浏览器有独立于操作系统的自己的cache。只要浏览器在自己的cache里还保留着这条记录,它就不会向操作系统查询DNS。

IE默认缓存DNS查找30分钟,写在DnsCacheTimeout注册表设置中。Firefox缓存1分钟,可以用network.dnsCacheExpiration配置项设置。Chrome同样缓存一分钟。

那么时间长短有什么不同呢?

缓存时间长:减少DNS的重复查找,节省时间

缓存时间短:及时的检测网站服务器的变化,保证正确性。

3、避免重定向

重定向用301(永久性重定向)和302(临时重定向)状态码,下面是一个有301状态码的HTTP头:

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

牢记重定向会拖慢用户体验,在用户和HTML文档之间插入重定向会延迟页面上的所有东西,页面无法渲染,组件也无法开始下载,直到HTML文档被送达浏览器。

有一种常见的极其浪费资源的重定向,而且web开发人员一般都意识不到这一点,就是URL尾部缺少一个斜线的时候。例如,跳转到http://astrology.yahoo.com/astrology会返回一个重定向到http://astrology.yahoo.com/astrology/的301响应(注意添在尾部的斜线)。在Apache中可以用Alias,mod_rewrite或者DirectorySlash指令来取消不必要的重定向。

如果你的网站使用了301重定向,搜索引擎在爬网的时候,会进行分析。当发现是301重定向的时候,它会记录下新的地址,删除原来的旧地址。也就是说301使得搜索引擎变得智能。

如果你使用的是302,搜索引擎会先找到旧地址,再去跳新的地址。

4、使AJAX缓存

利用时间戳,更精巧的实现响应可缓存与服务器数据同步更新。

5、为文件头指定Expires或Cache-Control,使内容具有缓存性

区分静态内容和动态内容,避免以后页面访问中不必要的HTTP请求。

6、使用CDN(内容分发网络)

这里可以关注CDN的三类实现:镜像、高速缓存、专线,以及智能路由器和负载均衡;

7、启用Gzip压缩

GZIP,即网页压缩,是由WEB服务器和浏览器之间共同遵守的协议,也就是说WEB服务器和浏览器都必须支持该技术,而现在主流的浏览器都是支 持的,包括IE、FireFox、谷歌浏览器、Opera 等。常见的WEB服务器有Apache 和IIS 等。双方的协商过程如下:

(1)首先浏览器请求某个URL 地址,并在请求的头 (head) 中设置属性accept-encoding值为gzip、deflate,表明浏览器支持gzip和deflate这两种压缩方式。

(2)WEB服务器接收到请求后判断浏览器是否支持压缩,如果支持就传送压缩后的响应内容,否则传送不经过压缩的内容;

(3)浏览器获取响应内容后,判断内容是否被压缩,如果是则解压缩,然后显示响应页面的内容。

GZIP压缩的比率往往在3到10倍,也就是本来90k大小的页面,采用压缩后实际传输的内容大小只有28至30K大小,这可以大大节省服务器的 网络带宽,同时如果应用程序的响应足够快时,网站的速度瓶颈就转到了网络的传输速度上,因此内容压缩后就可以大大的提升页面的浏览速度。

在实际应用中,并不需要对网站所有文件都进行压缩,只需要对静态文件进行压缩就可以了,包括js、css及html文件。对其他文件进行压缩并不 会对WEB性能有太多的改观,并且对网站开启GZIP功能是需要牺牲部分服务器性能的。

8、将css放在页面最上面

关注性能的前端工程师想让页面逐步渲染。也就是说,我们想让浏览器尽快显示已有内容,这在页面上有一大堆内容或者用户网速很慢时显得尤为重要。

9、将script放下页面最下面

脚本会阻塞并行下载,HTTP/1.1官方文档建议浏览器每个主机名下并行下载的组件数不要超过两个,如果图片来自多个主机名,并行下载的数量就可以超过两个。如果脚本正在下载,浏览器就不开始任何其它下载任务,即使是在不同主机名下的。

再比如,如果引入的js文件有个死循环或者执行时间很长的脚本,如果将这个脚本放到头部,那么浏览器会一直加载这个脚本而停止对网页的渲染,会造成页面一直空白,用户一直等待渲染的问题。这将造成很差的用户体验。如果将此脚本放到页面最下面,页面的HTML、CSS将先呈现给用户,用户会因为页面提前加载而觉得速度更快。

有时候,并不容易把脚本移动到底部。举个例子,如果脚本是用document.write插入到页面内容中的,就没办法再往下移了。还可能存在作用域问题,在多数情况下,这些问题都是可以解决的。

一个常见的建议是用推迟(deferred)脚本,有DEFER属性的脚本意味着不能含有document.write,并且提示浏览器告诉他们可以继续渲染。不幸的是,Firefox不支持DEFER属性。在IE中,脚本可能被推迟,但不尽如人意。如果脚本可以推迟,我们就可以把它放到页面底部,页面就可以更快地载入。

10、把JavaScript和CSS放到外面

很多性能原则都是关于如何管理外部组件的,然而,在这些顾虑出现之前你应该问一个更基础的问题:应该把JavaScript和CSS放到外部文件中还是直接写在页面里?

实际上,用外部文件可以让页面更快,因为JavaScript和CSS文件会被缓存在浏览器。HTML文档中的行内JavaScript和CSS在每次请求该HTML文档的时候都会重新下载。这样做减少了所需的HTTP请求数,但增加了HTML文档的大小。另一方面,如果JavaScript和CSS在外部文件中,并且已经被浏览器缓存起来了,那么我们就成功地把HTML文档变小了,而且还没有增加HTTP请求数。

所以是否将这两种文件放到外面不是绝对的,应该视情况而定。如果这是一个不常访问的页面,或者这个页面的css、js非常少,只有几行,那么完全没有必要放到外面。

11、移除重复的脚本

页面含有重复的脚本文件会影响性能,这可能和你想象的不一样。在对美国前10大web站点的评审中,发现只有2个站点含有重复脚本。两个主要原因增加了在单一页面中出现重复脚本的几率:团队大小和脚本数量。在这种情况下,重复脚本会创建不必要的HTTP请求,执行无用的JavaScript代码,而影响页面性能。

  IE会产生不必要的HTTP请求,而Firefox不会。在IE中,如果一个不可缓存的外部脚本被页面引入了两次,它会在页面加载时产生两个HTTP请求。即使脚本是可缓存的,在用户重新加载页面时也会产生额外的HTTP请求。

  除了产生没有意义的HTTP请求之外,多次对脚本求值也会浪费时间。因为无论脚本是否可缓存,在Firefox和IE中都会执行冗余的JavaScript代码。

  避免不小心把相同脚本引入两次的一种方法就是在模版系统中实现脚本管理模块。典型的脚本引入方法就是在HTML页面中用SCRIPT标签:

<script type="text/javascript" src="menu_1.0.17.js"></script>

12、不要用HTML缩放图片

不要因为在HTML中可以设置宽高而使用本不需要的大图。如果需要

<img width="100" height="100" src="mycat.jpg" alt="My Cat" />

那么图片本身(mycat.jpg)应该是100x100px的,而不是去缩小500x500px的图片。

13、减少cookie的大小

使用cookie的原因有很多,比如授权和个性化。HTTP头中cookie信息在web服务器和浏览器之间交换。重要的是保证cookie尽可能的小,以最小化对用户响应时间的影响。

  • 列表内容

去除不必要的coockie
使coockie体积尽量小以减少对用户响应的影响
注意在适应级别的域名上设置coockie以便使子域名不受影响
设置合理的过期时间。较早地Expire时间和不要过早去清除coockie,都会改善用户的响应时间。

14、避免图片src属性为空

Image with empty string src属性是空字符串的图片很常见,主要以两种形式出现:

straight HTML:

<img src=””>

JavaScript:

var img = new Image();
img.src = “”;

雅虎的团队指出,如果你将img的src留空,可能你的本意是暂时不要显示任何图片,但在不同的浏览器其实还是会有一些额外的请求发生。据我的观察,现在的这些浏览器都不再发送额外的请求了。这也算是浏览器自身的改进吧,为什么要对一个空白的img去发起额外的请求呢?

但既然以前早期的版本有可能发生这样的事情,如果你无法确保你的用户都使用最新的现代浏览器,那么请简单地遵守这条原则:总是给img的src设置值,而且是一个合法的值。

作为开发者,我理解有的时候,你想将src留空的原因在于,页面加载的时候,你想快速完全加载,这些图片你可能想后期再根据实际情况再加载。如果真的是这样,你应该参考一下另外一个讨论:优化网站设计(十七):延迟或按需加载内容。

或者很简单地,你可以将初始图片设置为一个很小的默认图片(这个图片设置永不过期),而不是留空。

  • 1
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值