前端开发性能优化规范
成都全搜索前端开发性能优化规范网站性能优化是一个很综合的话题,涉及到服务器的配置和网站前后端程序等各个方面,前端开发组以yahoo 的yslow 提高网页效率的14条准则和google 的page s
成都全搜索前端开发性能优化规范
网站性能优化是一个很综合的话题,涉及到服务器的配置和网站前后端程序等各个方面,前端开发组以yahoo 的yslow 提高网页效率的14条准则和google 的page speed 为理论基础,结合自身的实际情况初步制定出成都全搜索前端开发性能优化规范,望大家在开发中遵循以下规范优化性能。
传输优化
第一条:Make Fewer HTTP Requests 尽可能的减少HTTP 的Request 请求数。 终端用户响应的时间中,有80用于下载各项内容。这部分时间包括下载页面中的图像、样式表、脚本、Flash 等。通过减少页面中的元素可以减少HTTP 请求的次数。这是提高网页速度的关键步骤。
减少HTTP 请求的方法包括:合并Javascript/CSS文件、使用CSS Sprites(合并背景图片) 。
其中绿色的为传输文件花费的Reveive 时间,而前面白色的为检索缓存和确认链接是否有效的Blocked 时间。老版本的IE 和Firefox 都使用较低的单个主机并发连接数(2),而新版本的IE 和Firefox 都使用较高的单个主机并发连接数(6),所以除了正在下载的文件外其他的HTTP 请求都要排队,请求越多Blocked 的时间就越长。
IE7 2
,IE8 6
Firefox2
Firefox3 2 6 network.http.max-persistent-connections-per-server:6 尽量减少HTTP 的Request 请求。
1. CSS Sprites(合并背景图片), 最有效的方法
CSS Sprites :简单的说就是利用CSS 的background-position 属性,控制一张背景图片的显示区域。把能合并在一起的背景图片都合并到一张图上。如下图:
将20个单独的背景图片合并成一张背景图,相当于把20个HTTP 请求减小为1个HTTP 请求。
2. 合并css 文件
为了方便组织和规划样式表,将用于不同用途的样式表文件分离开来,形成不同的css 文件。采用两套版本,编辑版和发布版。编辑版仍然使用多个css 文件以便于规划和组织。而等到发布的时候,再将多个css 文件合并到一个文件中去,从而达到减少HTTPRequest 请求数的目的。
3. 合并js 文件
原因和处理方法同上。
,第二条:Reduce DNS Lookups 减少DNS 查询
域名系统(DNS )提供了域名和IP 的对应关系,就像电话本中人名和他们的电话号码的关系一样。当你在浏览器地址栏中输入www.cdqss.com 时,DNS 解析服务器就会返回这个域名对应的IP 地址。DNS 解析的过程同样也是需要时间的。一般情况下返回给定域名对应的IP 地址会花费20到120毫 秒的时间。而且在这个过程中浏览器什么都不会做直到DNS 查找完毕。
真正意义上的指导其实有两条:
1:如果不是必须,请不要把网站放到两台服务器上。
2:网页中的图片、css 文件、js 文件、flash 文件等等,不要太多的分散在不同的网络空间中(经过测试现阶段适合我们的是使用4个图片服务器)。
第三条:Gzip Components 启用Gzip 压缩
Gzip 的思想就是把文件先在服务器端进行压缩,然后再传输。这对于体积较大的纯文字型的文件有效果明显。
从HTTP/1.1开始,web 客户端都默认支持HTTP 请求中有Accept-Encoding 文件头的压缩格式:
Accept-Encoding: gzip, deflate
如果web 服务器在请求的文件头中检测到上面的代码,就会以客户端列出的方式压缩响应内容。Web 服务器把压缩方式通过响应文件头中的Content-Encoding 来返回给浏览器。 Content-Encoding: gzip
Gzip 大概可以减少70的响应规模。
图像和PDF 文件由于已经压缩过了所以不能再进行gzip 压缩。如果试图gizp 压缩这些文件的话不但会浪费CPU 资源还会增加文件的大小。
,第四条:使用GBK 编码
GBK 的文字编码是双字节来表示的,即不论中、英文字符均使用双字节来表示,只不过为区分中文,将其最高位都定成1。UTF -8编码则是用以解决国际上字符的一种多字节编码,它对英文使用8位(即一个字节),中文使用24位(三个字节)来编码。对中文字符GBK 能节省空间。
第五条:Use a Content Delivery Network 使用CDN
YSlow 的官方解释是:用户与你网站服务器的接近程度会影响响应时间的长短。把你的网站内容分散到多个、处于不同地域位置的服务器上可以加快下载速度。
结合中国的网络特色,这个便不难理解了。“北方服务器”、“南方服务器”、“电信服务器”、“网通服务器”……这些词听起来是那么熟悉。如果,一个北京的电信用户试图从广东的网通服务器上打开一个类似《壁纸合集》帖子的网页时,你就能很深刻的理解。
鉴于这个不是我们开发人员力所能及的准则,所以这里也就不多言了。
第六条:Avoid Redirects 避免跳转
跳转会降低用户体验。在用户和HTML 文档中间增加一个跳转,会拖延页面中所有元素的显示,因为在HTML 文件被加载前任何文件(图像、Flash 等)都不会被下载。
链接地址写明确。例如:将http://www.cdqss.com/写成http://www.cdqss.com (注意最后面一个“/”符号)。这两个网址都能访问到,但是,它们是有区别的。http://www.cdqss.com会被重新指向http://www.cdqss.com/ 。显然,中间多一次加载
,时间。
第七条:Minify JavaScript and CSS 减少JavaScript 和CSS 文件的体积
最终发布版本中把没有必要的空行、空格和注释全部去掉。
第八条:减少HTTP 404 (文件未找到)
HTTP 请求时间消耗是很大的,因此使用HTTP 请求来获得一个没有用处的响应(例如404没有找到页面)是完全没有必要的,它只会降低用户体验而不会有一点好处。
第九条:使用GET 方式发送AJAX 请求
Yahoo!Mail 团队发现,当使用 XMLHttpRequest 时,浏览器中的POST 方法是一个“两步走”的过程:首先发送文件头,然后才发送数据。因此使用GET 最为恰当,因为它只需 发送一个TCP 包(除非你有很多cookie) 。IE 中URL 的最大长度为2K ,因此如果你要发送一个超过2K 的数据时就不能使用GET 了。
一个有趣的不同就是POST 并不像GET 那样实际发送数据。根据HTTP 规范,GET 意味着“获取”数据,因此当你仅仅获取数据时使用GET 更加有意义(从语意上讲也是如此) ,相反,发送并在服务端保存数据时使用POST 。
避免阻塞
第一条:Put CSS at the Top 把CSS 样式放在页面的上方
把样式表放到文档的内部似乎会加快页面的下载速度。这是因为把样式表放到内会使页面有步骤的加载显示。注重性能的前端服务器往往希望页面有秩序地加载。同时,我们也希望浏览器把已经接收到内容尽可能显示出来。向用户返回可视化的反馈,比如进程指针,HTML 页面就是进程指针。当浏览器有序地加载文件头、导航栏、顶部的logo 等对于等待页面加载的用户来说都可以作为可视化的反馈。这从整体上改善了用户体验。
,把样式表放在文档底部的问题是在包括Internet Explorer在内的很多浏览器中这会中止内容的有序呈现。浏览器中止呈现是为了避免样式改变引起的页面元素重绘。用户不得不面对一个空白页面。无论是引起白屏还是出现没有样式化的内容都不值得去尝试。最好的方案就是按照HTML 规范在文档内加载样式表。
第二条:Move Scripts to the Bottom 将脚本放在底部
脚本带来的问题就是它阻止了页面的平行下载。HTTP/1.1 规范建议,浏览器每个主机名的并行下载内容不超过两个。如果你的图片放在多个主机名上,你可以在每个并行下载中同时下载2个以上的文件。但是当下载脚本 时,浏览器就不会同时下载其它文件了,即便是主机名不相同。
在某些情况下把脚本移到页面底部可能不太容易。比如说,如果脚本中使用了document.write 来插入页面内容,它就不能被往下移动了。这里可能还会有作用域的问题。
一个经常用到的替代方法就是使用延迟脚本。defer 属性表明推迟加载,它告诉浏览器继续显示。
注: Firefox 3.5 开始支持 defer
优化缓存
第一条:Add an Expires Header 添加周期头
浏览器(和代理)使用缓存来减少HTTP 请求的大小和次数以加快页面访问速度。Web 服务器在HTTP 响应中使用Expires 文件头来告诉客户端内容需 要缓存多长时间。下面这个例子是一个较长时间的Expires 文件头,它告诉浏览器这个响应直到2010年4月15日才过期。
Expires: Thu, 15 Apr 2010 20:00:00 GMT
,如果你使用的是Apache 服务器,可以使用ExpiresDefault 来设定相对当前日期的过期时间。下面这个例子是使用ExpiresDefault 来设定请求时间后10年过期的文件头: ExpiresDefault "access plus 10 years"。
第二条:Make JavaScript and CSS External 将javascript 和css 独立成外部文件 很多性能规则都是关于如何处理外部文件的。
使用外部文件的优点:可以提高页面速度,因为JavaScript 和CSS 文件都能在浏览器中产生缓存。内置在HTML 文档中的JavaScript 和CSS 则会在每次请求中随HTML 文档重新下载。这虽然减少了HTTP 请求的次数,却增加了HTML 文档的大小。从另一方面来说,如果外部文件中的 JavaScript 和CSS 被浏览器缓存,在没有增加HTTP 请求次数的同时可以减少HTML 文档的大小。外部JavaScript 和CSS 文件缓存的频率和请求HTML 文档的次数有关。如果一个会话中用户会浏览你网站中的多个页面,并且这些页面中会重复使用相同的脚本和样式表,缓存外部文件就会带来更大的益处。
对于拥有较大浏览量的首页来说,有一种技术可以平衡内置代码带来的HTTP 请求减少与通过使用外部文件进行缓存带来的好处。其中一个就是在首页中内置 JavaScript 和CSS ,但是在页面下载完成后动态下载外部文件,在子页面中使用到这些文件时,它们已经缓存到浏览器了。
第三条:Configure ETags 配置你的实体标签
Etag (Entity tags )实体标签。Etag 是识别内容版本号的唯一字符串。Etag 不是给用户用的,而是给浏览器缓存用的。Etag 是服务器告诉浏览器,缓存中的内容是否已经发生变化的一种机制。通过Etag ,浏览器就可以知道现在的缓存中的内容是不是最新的,需不需要重新从服务器上重新下载。这和 “Last-Modified ”的概念有点类似。
如果你没有使用ETag 提供的灵活的验证模式,那么干脆把所有的ETag 都去掉会更好。
,第四条:缓存AJAX 请求
Ajax 经常被提及的一个好处就是由于其从后台服务器传输信息的异步性而为用户带来的反馈的即时性。但是,使用Ajax 并不能保证用户不会在等待异步的 JavaScript 和XML 响应上花费时间。在很多应用中,用户是否需要等待响应取决于Ajax 如何来使用。例如,在一个基于Web 的Email 客户端 中,用户必须等待Ajax 返回符合他们条件的邮件查询结果。记住一点,“异步”并不异味着“即时”,为了提高性能,优化Ajax 响应是很重要的。
第五条:在没有Cookie 的域里处理静态内容
当浏览器在请求中同时请求一张静态的图片和发送coockie 时,服务器对于这些coockie 不会做任何地使用。因此他们只是因为某些负面因素而创建的网络传输。所有你应该确定对于静态内容的请求是无coockie 的请求。创建一个子域名并用他来存放所有静态内容。
如果你的域名是www.cdqss.com ,你可以在img.cdqss.com 上存在静态内容。但是,如果你不是在 www.cdqss.com 上而是在顶级域名cdqss.com 设置了coockie ,那么所有对于img.cdqss.com 的请求 都包含coockie 。在这种情况下,你可以再重新购买一个新的域名来存在静态内容,并且要保持这个域名是无coockie 的。Yahoo! 使用的是 ymig.com ,YouTube 使用的是ytimg.com ,Amazon 使用的是images-anazon.com 等等。
使用无 coockie 域名存静态内容的另外一个好处就是一些代理(服务器)可能会拒绝对coockie 的内容请求进行缓存。一个相关的建议就是,如果你想确定应该使用cdqss.com 还是www.cdqss.com 作为你的一主页,你要考虑到coockie 带来的影响。忽略掉www 会使你除了把 coockie 设置到*.cdqss.com(*是泛域名解析,代表了所有子域名)外没有其它选择,因此出于性能方面的考虑最好是使用 带有www 的子域名并且在它上面设置coockie 。
,客户端优化
第一条:Avoid CSS Expressions 避免使用CSS 中的Expressions
首先有必要先说明一下CSS Expressions 是什么一个东西。其实它就像其它语言中的if ……else ……语句。这样在CSS 中就可以进行简单的逻辑判断了。举个简单的例子
input{background-color:expression((this.readOnly&&
this.readOnly==true)?"#0000ff":"#ff0000")}
这样css 就可以根结一些情况分别使用不同的样式了。
只有IE 浏览器支持expression 表达式。表达式的问题就在于它的计算频率要比我们想象的多。不仅仅是在页面显示和缩放时,就是在页面滚动、乃至移动鼠标时都会要重新计算一次。给CSS 表达式增加一个计数器可以跟踪表达式的计算频率。在页面中随便移动鼠标都可以轻松达到10000次以上的计算量。如果样式属性必须在页面周期内动态地改变,使用事件句柄来代替CSS 表达式是一个可行办法。如果必须使用CSS 表达式,一定要记住它们要计算成千上万次并且可能会对你页面的性能产生影响。
第二条 使用有效率的CSS 选择器
*{ margin:0; padding:0;}避免浏览器样式差异
*号通配符把所有标签都初始化一遍,浏览器的渲染消耗一定的资源。建议有选择性地使用div span button b table{ margin:0; padding:0;}填充样式。
第三条 Remove Duplicate Scripts 移除重复的脚本
,重复脚本会引起不必要的HTTP 请求和无用的JavaScript 运算,这降低了网站性能。
第四条:不在HTML 内扭曲图片
不要为了在HTML 中设置长宽而使用比实际需要大的图片。如果你需要:那么你的图片(/upload/12/pfj1bdp2050.jpg )就应该是100x100像素而不是把一个500x500像素的图片缩小使用。
在页面加载的时候会按照指定的大小预留出图片的空间,不会因为在加载的时间导致页面内容发生变化。
第五条:减少页面DOM 元素的数量
一个复杂的页面意味着需要下载更多数据,同时也意味着JavaScript 遍历DOM 的效率越慢。不要仅仅为了布局而引入更多的
该规范还有很多不完善和需要改进的地方,希望大家提出自己的意见和建议,把发现的问题反馈回来,以便我们及时作出修改。
前端开发组 2010年1月25日星期一