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


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 相关文章推荐
网页中实现浏览器的最大,最小化和关闭按钮
Mar 12 Javascript
每天一篇javascript学习小结(Function对象)
Nov 16 Javascript
快速解决Canvas.toDataURL 图片跨域的问题
May 10 Javascript
Js遍历键值对形式对象或Map形式的方法
Aug 08 Javascript
用Vue.js实现监听属性的变化
Nov 17 Javascript
Javascript基础回顾之(一) 类型
Jan 31 Javascript
Vue.js上下滚动加载组件的实例代码
Jul 17 Javascript
快速将Vue项目升级到webpack3的方法步骤
Sep 14 Javascript
Vue Element使用icon图标教程详解(第三方)
Feb 07 Javascript
解决vue中监听input只能输入数字及英文或者其他情况的问题
Aug 30 Javascript
基于Express框架使用POST传递Form数据
Aug 10 Javascript
vue-cli3中配置alias和打包加hash值操作
Sep 04 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
PHP+Mysql树型结构(无限分类)数据库设计的2种方式实例
2014/07/15 PHP
php面向对象重点知识分享
2019/09/27 PHP
JavaScript游戏之优化篇
2010/11/08 Javascript
远离JS灾难css灾难之 js私有函数和css选择器作为容器
2011/12/11 Javascript
jquery事件重复绑定的快速解决方法
2014/01/03 Javascript
基于jQuery 实现bootstrapValidator下的全局验证
2015/12/07 Javascript
三分钟带你玩转jQuery.noConflict()
2016/02/15 Javascript
js提示框替代系统alert,自动关闭alert对话框的实现方法
2016/11/07 Javascript
jQuery DateTimePicker 日期和时间插件示例
2017/01/22 Javascript
使用vue-infinite-scroll实现无限滚动效果
2018/06/22 Javascript
详解关于JSON.parse()和JSON.stringify()的性能小测试
2019/03/14 Javascript
vue服务端渲染操作简单入门实例分析
2019/08/28 Javascript
js 闭包深入理解与实例分析
2020/03/19 Javascript
[49:21]2018DOTA2亚洲邀请赛3月30日 小组赛B组 Effect VS iG
2018/03/31 DOTA
Python的语言类型(详解)
2017/06/24 Python
python实现机器人行走效果
2018/01/29 Python
python自动查询12306余票并发送邮箱提醒脚本
2018/05/21 Python
python生成器与迭代器详解
2019/01/01 Python
python 实现Flask中返回图片流给前端展示
2020/01/09 Python
Python通过正则库爬取淘宝商品信息代码实例
2020/03/02 Python
New Balance澳大利亚官网:运动鞋和健身服装
2019/02/23 全球购物
致200米运动员广播稿
2014/02/06 职场文书
企业军训感想
2014/02/07 职场文书
《一个中国孩子的呼声》教学反思
2014/02/12 职场文书
生日礼品店创业计划书范文
2014/03/21 职场文书
烹饪大赛策划方案
2014/05/26 职场文书
社区矫正工作方案
2014/06/04 职场文书
中秋节活动总结
2014/08/29 职场文书
房屋出租协议书范本(标准版)
2014/09/24 职场文书
2014年终个人工作总结
2014/11/07 职场文书
实习协议书
2015/01/27 职场文书
加班费申请报告
2015/05/15 职场文书
大国崛起观后感
2015/06/02 职场文书
教育教学读书笔记
2015/07/02 职场文书
银行文明优质服务培训心得体会
2016/01/09 职场文书
threejs太阳光与阴影效果实例代码
2022/04/05 Javascript