首先从一次完整的的请求说起:(以此为例get,www,baidu.com)
1,webbrower 发出request,
2,然后解析www.baidu.com为ip,找到ip的服务器,
3,服务器处理请求资源并返回请求的内容,
4,browser接受请求内容过程,(返回内容是按顺序读取的)
4.1遇到外联css,就会并发去读取css内容(),
4.2遇到图片时,回去并发读取图片,目前浏览器的并发数为2,
4.3遇到js时则会阻塞其他请求。
4.4加载完css后,browse开始渲染页面,
4.5直到加载完页面中的文本资源,这时dom的结构已经确定,会出发 document.ready方法
4.6 browse继续加载 图片和js,完成后。页面就全部加载完成,这时会出发 window.onload()方法
来分析一下里面具体的时间开销:
1,从1--4.4 用户才开始看到页面上有内容,在这以前页面就是空白的
2,解析域名也是有一定时间开销的,如果是大机房的可以通过路由配置 dns 缓存,依赖于外部机房环境,可控性比较小。
3,这是服务器处理的时间,优化程序代码可以减少这里的时间
4,
4.1浏览器在接收完css之前,一般是不去渲染dom的,以避免无所谓的刷新和闪烁。所以直到4.4用户才真正在页面上看到内容。
4.2 浏览器的单域名并发访问数 为2,多域名下并发数没限制,可以通过定义域名别名改善
4.3 浏览器加载js时会阻塞其他请求,直到加载完成。改善的话可以把js放到页面下面去加载。
从上面的流程可以分析出以下建议:
1,减少连接数(原因:并发限制,dns开销)
2,将css放到 head中。(1,首先这符合w3c规范,2,应为css加载完后,遇到dom对象时就会直接显示,可以更快的显示页面。)
3,将js放到页面底部,(加载js时会阻塞其他请求,这段时间页面没有反映,如果js中没有write的话应该放到底部,页面渲染完后再加载js)
4,减少下载内容(网络是有速度限制的,内容越少当然加载越快)
针对上面4条建议给出具体做法:
1,使用 css sprite将小图片合并,合并css、js。使用浏览器缓存: cache-control、expires。不使用etag
2、3不用说了,上面已经解释清楚了。
4,采用gzip压缩,可以使用 jsmin 将js精简,使用工具将css,html精简,尽可能缩减图片。
按照 性能黄金法则 说明: 文本内容只占所有时间的10%-20%, 这样做以后 至少能将时间缩小40%-50%。能明显改善用户体验。
这只是一些建议参考,具体的需要你针对自己的网站进行分析,分析工具可以使用firedebug,yslow,(这两个可以集成)
yslow会直接给出你建议。
这个总结来源于一次优化的请求,最初某个页面的加载十分缓慢,load事件迟迟无法触发,因此希望可以通过对静态文件分域名等方式对页面的外部资源进行优化,拿得load事件尽可能早地触发。
于是我查看了页面的源码,并对外部资源进行了整理,基于下面2个理念画出了一个推测的瀑布图:
浏览器对同一个域只能并发2个HTTP请求 – 网上盛传已久。
javascript文件的加载会阻塞浏览器其他资源的加载 – 同样网上盛传已久。
然而,当我看到各浏览器中实际的瀑布图时,我知道自己又犯了一个简单的错误:太过相信所谓的权威和大众的声音,而没有更早地进行实践来检验理论的正确性……
本篇文章就使用几种流行的浏览器,针对同一个页面的外部资源加载过程进行分析,推测各浏览器加载外部资源的策略、特征,并最后给予一定的比较和总结。
测试样例
测试的页面结构如下:
head
1.css + 1.js
body
1.jpg + 2.jpg + 2.js + 2.css + 3.jpg + 4.jpg + 3.css + 3.js + 5.jpg + 6.jpg
共12个外部资源,加上页面本身,一次完整的加载一共有13次HTTP GET请求。
针对每一个外部资源,服务器首先会休眠5秒的时间,随后再返回相应的内容,以方便查看整个外部资源的加载过程。
测试的浏览器如下:
IE6
IE8
Firefox3.6
Firefox4.0 beta12
Chrome 8
Opera 11
IE6
IE6的瀑布图非常传统,其特征有:
各资源按照在HTML中出现的顺序进行加载。
javascript文件会阻塞其后所有资源的加载。
最大并发HTTP连接数为2个。
可见网上盛传的2个“误区”都来自IE6统治浏览器市场的时代,针对IE6的优化太多太多,大家也就习惯性地将这些结论作为公理来使用了。
IE8
和IE6完全不同的瀑布图,其特点有:
最大并发HTTP连接数为6个。
javascript文件已经不会阻塞其他资源的加载,甚至多个javascript文件可以一起加载,并且会保证执行的顺序。
会分析HTML结构,优先下载script和link标签定义的外部资源。
Firefox3.6
和IE8的几乎完全一样:
最大并发HTTP连接数为6个(可在about:config中修改)。
javascript文件不会阻塞其他资源的加载,多个javascript文件可以一起加载。
会分析HTML结构,优先下载script和link标签定义的外部资源。
Firefox4 beta12
不知是因为设计理念上的不同,还是因为beta版未照顾到这一块,Firefox4反而退化了,和Firefox3.6的区别主要体现在对资源类型的处理上,Firefox4不再严格地优先下载script和link标签定义的外部资源,而是按照HTML结构中出现的顺序来进行加载。
Chrome8
Chrome自带的工具不能很清楚地表示各请求的开始时间,所以使用了Fiddler的瀑布图,从图上可以看出,Chrome也是比较特立独行的一位,其特点有:
最大并发HTTP连接数为6。
head部分的资源会单独下载,且阻塞body中的其他资源的加载。
会优先加载script和link标签定义的资源。
Opera11
先报怨一下,Dragonfly不怎么好用来着……Opera的资源加载也比较有特色,而且很难看出规律,只能大致总结一下:
最大并发HTTP连接数为5(网上有说原先版本是4)。经过网友的指正,Opera的最大并发HTTP连接数默认为16,可在opera:config - Performance - Max Connections Server查看和修改。
javascript文件的加载会阻塞其他script和link标签定义的外部资源的加载,如图中的2.js。但不会阻塞图片等其他资源的加载,如图中的3.js。
会一定程度上对资源的优先级进行优化,但由于javascript文件要阻止后续部分资源的加载,又为了充分利用最大HTTP连接数,因此不能严格先加载所有的script和link标签定义的资源,导致瀑布图上各类型资源有相互穿插,难寻规律。
总结
抛开IE6不论的话,除非是在线相册之类外部资源非常多的页面,不然没必要去追求静态资源的分域名优化。
针对IE6进行静态资源分域名优化时,要严格注意javascript文件对后续资源的阻塞,进行精确计算和设计后保证资源最完美地分域名存储,以提供最大并行度。
鉴于Chrome对head部分的资源会独立加载,当head部分用不满6个HTTP并发数时,是否可以将资源移到body中呢?在body中的资源又会引起其他的问题,需要谨慎考虑。
Opera的行为比较怪异,似乎主动设计了一个很麻烦的算法,不过考虑到其占有率,就先放在一边吧……而且号称最快的浏览器的Opera,在加载javascript文件时竟然如此笨拙……
Firefox4 beta12的行为让人无法理解,看来要追踪RC版是否还存在这个问题,如果存在的话可以考虑找Mozilla报个问题了。
本文作者:记者 来源:CIOZJ
CIO之家 www.ciozj.com 微信公众号:imciow