浏览器加载、渲染和解析过程黑箱简析


Posted in Javascript onNovember 29, 2012

用 Fiddler 监控,在 IE6 下,资源下载顺序为:
浏览器加载、渲染和解析过程黑箱简析

很明显,下载顺序从上到下,文档流中先出现的资源先下载。在 IE8, Safari, Chrome 等浏览器下也类似。

Firefox 对下载顺序做了优化
浏览器加载、渲染和解析过程黑箱简析
Firefox 会将 js, css 提前下载,而将图片等资源延迟到后面下载。

对于渲染,利用 Fiddler 将网速调慢,可以看到 css 下载后会马上渲染到页面,渲染和下载同步进行。js 的解析和运行,也类似。

对于 js 运行,以及页面加载相关事件的触发,特别做了测试。在 Firefox 下,打开测试页面:

[22:13:32.947] HTML Start[22:13:32.947] normal inline script run time[22:13:34.904] normal external script run time[22:13:35.775] [body] normal external script run time[22:13:35.789] [body end] normal external script run time[22:13:35.789] HTML End[22:13:35.791] deferred inline script run time[22:13:35.791] deferred external script run time[22:13:35.793] DOMContentLoaded[22:13:38.144] images[0] onload[22:13:38.328] images[1] onload[22:13:39.105] images[2] onload[22:13:39.105] images[3] onload[22:13:39.106] window.onload

很明显,JS 的运行严格按照文档流中的顺序进行。其中 deferred 的脚本会在最后运行(注:Firefox 3.5 开始支持 defer,而且支持得很完美)。

再来看下 IE8,结果如下:

[22:33:56.806] HTML Start[22:33:56.826] normal inline script run time[22:33:57.786] normal external script run time[22:33:57.812] deferred inline script run time[22:33:57.816] document.readyState = interactive[22:33:57.934] [body] normal external script run time[22:33:58.310] [body end] normal external script run time[22:33:58.310] HTML End[22:33:58.346] deferred external script run time[22:33:58.346] images[0].readyState = loading[22:33:58.346] images[0].readyState = complete[22:33:58.346] images[0] onload[22:33:58.361] doScroll[22:33:58.451] images[1].readyState = loading[22:33:58.479] images[1].readyState = complete[22:33:58.479] images[1] onload[22:33:58.794] images[2].readyState = loading[22:33:58.854] images[2].readyState = complete[22:33:58.854] images[2] onload[22:33:58.876] images[3].readyState = loading[22:33:58.876] images[3].readyState = complete[22:33:58.876] images[3] onload[22:33:58.887] document.readyState = complete[22:33:58.888] window.onload

可以看出,IE8 下,defer 只对 external 脚本有效,对 inline 脚本无效。另,与 DOMContentLoaded 最接近的是 doScroll. 这是 doScroll 被广泛用来模拟 DOMContentLoaded 的原因。小心:仅仅是模拟,细节上并不等价。

还可以得到一个有点意外的结果:放在 body 结束前的脚本,执行时,依旧最好放在 domready 事件中。无论在 Firefox 还是 IE 下,解析到 HTML End 时,并不代表 DOM 可以安全操作,特别是页面比较复杂时。

从上面数据中,也可以看出 YSlow 性能优化法则里,建议将样式置顶和脚本置底的根据。

有兴趣的可以进一步测试动态添加样式和脚本的情形,会稍有不同,但没有特别 surprise.

最后总结下

页面资源的下载顺序是从上到下的,文档流中先出现的资源先下载(注:存在并发,具体请参考 UA Profiler)。当某一样式下载完成时,会立刻渲染到页面(体现了层叠样式表中层叠在渲染时的含义)。当某一脚本下载完成时,也会立刻解析和运行。脚本的运行严格按照文档流中的顺序进行,deferred 的脚本会在正常脚本运行之后运行(Firefox 和 IE 下)。

特别需要留意:脚本运行时,会暂停该脚本之下所有资源的下载(因为脚本可能改变文档流,甚至跳转页面,浏览器的暂停策略是合理的)。要小心内联脚本,经常会阻塞后续下载。

好了,废话不多说。以上结果,建议各位亲自测试,反复测试,疯狂测试,一直到眼花缭乱稀里糊涂恍然大悟继续糊涂为止……

Javascript 相关文章推荐
Web层改进II-用xmlhttp 无声息提交复杂表单
Jan 22 Javascript
Extjs4 关于Store的一些操作(加载/回调/添加)
Apr 18 Javascript
JsRender实用入门教程
Oct 31 Javascript
js随机生成网页背景颜色的方法
Feb 26 Javascript
JavaScript生成随机数的4种自定义函数分享
Feb 28 Javascript
jquery实现倒计时功能
Dec 28 Javascript
javascript实现数组去重的多种方法
Mar 14 Javascript
详解JavaScript中this的指向问题
Jan 20 Javascript
jQuery实现上传图片前预览效果功能
Aug 03 jQuery
解决vue.js 数据渲染成功仍报错的问题
Aug 25 Javascript
教你搭建按需加载的Vue组件库(小结)
Jul 29 Javascript
Javascript Worker子线程代码实例
Feb 20 Javascript
javascript控制swfObject应用介绍
Nov 29 #Javascript
javascript 保存文件到本地实现方法
Nov 29 #Javascript
jquery连缀语法如何实现
Nov 29 #Javascript
javascript 使td内容不换行不撑开
Nov 29 #Javascript
json原理分析及实例介绍
Nov 29 #Javascript
javascript全局变量封装模块实现代码
Nov 28 #Javascript
Javascript Request获取请求参数如何实现
Nov 28 #Javascript
You might like
destoon实现调用图文新闻的方法
2014/08/21 PHP
PHP在linux上执行外部命令的方法
2017/02/06 PHP
php用户名的密码加密更安全的方法
2019/06/21 PHP
js传值 判断
2006/10/26 Javascript
JavaScript与Div对层定位和移动获得坐标的实现代码
2010/09/08 Javascript
jquery使用jquery.zclip插件复制对象的实例教程
2013/12/04 Javascript
鼠标滑过出现预览的大图提示效果
2014/02/26 Javascript
jQuery修改CSS伪元素属性的方法
2014/07/30 Javascript
Jquery全屏相册插件zoomvisualizer具有调节放大与缩小功能
2015/11/02 Javascript
jQuery实现图片走马灯效果的原理分析
2016/01/16 Javascript
详解Vue打包优化之code spliting
2018/04/09 Javascript
vue源码解析之事件机制原理
2018/04/21 Javascript
JavaScript实现JSON合并操作示例【递归深度合并】
2018/09/07 Javascript
vue+element-ui表格封装tag标签使用插槽
2020/06/18 Javascript
使用IPython来操作Docker容器的入门指引
2015/04/08 Python
各个系统下的Python解释器相关安装方法
2015/10/12 Python
python anaconda 安装 环境变量 升级 以及特殊库安装的方法
2017/06/21 Python
python 打印直角三角形,等边三角形,菱形,正方形的代码
2017/11/21 Python
Python 处理图片像素点的实例
2019/01/08 Python
Python OpenCV对本地视频文件进行分帧保存的实例
2019/01/08 Python
Django中自定义admin Xadmin的实现代码
2019/08/09 Python
深入浅析Python 中的sklearn模型选择
2019/10/12 Python
python超时重新请求解决方案
2019/10/21 Python
python3常用的数据清洗方法(小结)
2019/10/31 Python
python3实现弹弹球小游戏
2019/11/25 Python
时尚的CSS3进度条效果
2012/02/22 HTML / CSS
HTML中使用SVG与SVG预定义形状元素介绍
2013/06/28 HTML / CSS
英国第一蛋白粉品牌:Myprotein
2016/09/14 全球购物
给同学的道歉信
2014/01/16 职场文书
员工晚婚的请假条
2014/02/08 职场文书
给学校的建议书
2014/03/12 职场文书
城管个人总结
2015/02/28 职场文书
医院岗前培训心得体会
2016/01/08 职场文书
七年级之开学家长寄语35句
2019/09/05 职场文书
如何正确理解python装饰器
2021/06/15 Python
《战锤40K:暗潮》跳票至9月 公布新宣传片
2022/04/03 其他游戏