各浏览器是如何下载资源来打开页面的

这个总结来源于一次优化的请求,最初某个页面的加载十分缓慢,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的资源加载也比较有特色,而且很难看出规律,只能大致总结一下:

  • Opera的最大并发HTTP连接数默认为1纽约娱乐城6,可在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报个问题了。

对各浏览器加载外部资源的策略的掌握,是WPO的基本元素,虽然一直想当一个WPO的专家,却在这方面迟迟不愿实践,实在有愧于自己的理想……

时间: 2024-10-29 19:11:22

各浏览器是如何下载资源来打开页面的的相关文章

python下用selenium的webdriver包如何在执行完点击下一页后没有获得下一页新打开页面的html源代码

问题描述: 新打开的页面url不变,只是网页内容变了,然后使用drive.page_source得到的都是第一页的html代码,并不是当前页面的html代码. 1.  原因:webdriver仍默认在原页面下获取标签等信息: 解决方法:采用切换页面句柄的方式解决: 2.  原因:缺少time.sleep(1),如果短了就无法正常获取数据,所以检查适当位置是否有停留 def get_info(num): driver.get(url) driver.implicitly_wait(10) # 隐式

CSS3-基于浮动的布局,响应式WEB设计,定位网页上的元素,设计打印页面的css技术

基于浮动的布局: 1.除非图片设置了宽度,否则始终应该要对浮动的图片设置一个宽度,这样可以让浏览器给其他内容腾出环绕的空间 2.当侧边栏的高度与主内容区的高度不一致的时候,可以用个margin进行调整 3.在一个非浮动元素<div>中存在一个浮动元素,当浮动元素高于元素本身的时候,内容就会溢出<div>中,解决方案如下: A:在</div>介绍之前添加一个换行,并且添加一个类<br class=”clear”/>,之后创建一个样式br.class{clear

03.获取页面的flash文件

1.打开页面的web控制台 2.选择网路查看当前请求的swf文件所在的地址 3.打开swf的文件地址 4.另存为swf的网页为swf格式 搞定就可以了.

宏观视角下的浏览器:05 | 渲染流程(上):HTML、CSS和JavaScript,是如何变成页面的?

前言:该篇说明:请见 说明 —— 浏览器工作原理与实践 目录 在上一篇文章中我们介绍了导航相关的流程,那导航被提交后又会怎么样呢?就进入了渲染阶段.这个阶段很重要,了解其相关流程能让你 “看透” 页面是如何工作的,有了这些知识,你可以解决一系列相关的问题,比如能熟练使用开发者工具,因为能够理解开发者工具里面大部分项目的含义,能优化页面卡顿问题,使用 JavaScript 优化动画流程,通过优化样式表来防止强制同步布局,等等. 既然它的功能这么强大,那么今天,我们就来好好聊聊 渲染流程. 通常,我

服务端通知浏览器以下载的方式打开图片

import java.io.File; import java.io.FileInputStream; import java.io.IOException; import java.io.InputStream; import java.io.OutputStream; import javax.servlet.ServletException; import javax.servlet.http.HttpServlet; import javax.servlet.http.HttpServ

点击按钮(或超链接)如何跳转到另外一个页面并执行目标页面的js函数

页面跳转同时执行js代码$(function(){});url参数传递 标题的前半部分其实不必赘述,按钮也可以换成超链接.. 假设是需要在A页面上的一个按钮,点击后跳转到B页面,传一些参数后且并B页面的某个js函数可以执行~~ 关键在于如何跳转到目标页面之后并「接着」执行「目标页面的js函数」.原因是目标页面的某个js函数原来是需要点击该页面的按钮或超链接才能触发的,但现在需要在跳转到B页面后立即执行! 先不想是从A页面跳转到B页面,假设你想在B页面一打开就执行的话,是需要把代码逻辑写在$(fu

通过Web Api 和 Angular.js 构建单页面的web 程序

在传统的web 应用程序中,浏览器端通过向服务器端发送请求,然后服务器端根据这个请求发送HTML到浏览器,这个响应将会影响整个的页面,比如说:用户通过一个连接导航到一个页面,会发送一个请求到服务器端,接下来服务器将会发送一个新的页面给浏览器. 但是在单页面应用程序中,整个页面只是在浏览器一开始请求的时候才会加载,接下来的请求,下来的交互请求都是通过ajax 来完成的,这就意味着只有部分的页面会更新,并不需要去加载整个的页面,这就减少了对用户操作的响应时间,从而使用户有一个更流畅的体验.但是在传统

定义页面的Dispose方法:[before]unload事件启示录

前言 最近实施的同事报障,说用户审批流程后直接关闭浏览器,操作十余次后系统就报用户会话数超过上限,咨询4A同事后得知登陆后需要显式调用登出API才能清理4A端,否则必然会超出会话上限. 即使在页面上增添一个登出按钮也无法保证用户不会直接关掉浏览器,更何况用户已经习惯这样做,增加功能好弄,改变习惯却难啊.这时想起N年用过的window.onbeforeunload和window.onunload事件. 本文记录重拾这两个家伙的经过,以便日后用时少坑. 为网页写个Dispose方法 C#中我们会将释

PHP $_SERVER[&#39;HTTP_REFERER&#39;] 获取前一页面的 URL 地址

转载:http://www.5idev.com/p-php_server_http_referer.shtml 使用 $_SERVER['HTTP_REFERER'] 将很容易得到链接到当前页面的前一页面的地址.一个例子如下: index.php(实际地址为:http://www.5idev.com/php/index.php): <a href="test.php">链接</a> test.php(实际地址为:http://www.5idev.com/php/