浏览器中JavaScript执行原理
本章我们讨论javascript在浏览器中是如果工作的,包括:下载、解析、执行的全过程。javascript的这些讨人嫌的地方我们是知道的:
i.需要串行下载
ii.需要解析
iii.需要串行执行
而在chrchromium中,js是这样解析的:(其实第一章末尾已经有了)

至于一些步骤的解释,这里就不再复述了,不懂的请戳:浏览器渲染过程 拉至末尾。
简直就是大魔王有木有?心中可有一万只草泥马奔腾而过?为什么在所有的下载线程中:
i.css加载不会阻塞页面
ii.images加载不会阻塞页面
iii.flash加载不会阻塞页面
iiii.activeX加载不会阻塞页面
iiiii.ajax还有同步异步之分
特么javascript文件就会阻塞页面!!
既然如此,我们能回避UI阻塞吗
i.在页面底部(</body>之前)引入js脚本,原因:由于js加载阻塞页面,而HTML是下载多少渲染多少,因此我们把它至于页面底部,让UI线程先执行完再加载js脚本
ii.根据具体情况,通过combo和compress减少请求数(通常在正式生产环境,我们将多个js脚本压缩为一个)
BUT ,这并没有真正回避UI阻塞,在</body>之前存在一个较大的脚本需要加载执行时,UI在ready后,需要较长的时间等待脚本加载和执行,在脚本ready前,UI是处于无事件响应状态的。
iii.defer属性
HTML4标准中为<script>标签定义的属性,用于告诉浏览器:内容中包含document.write之类破坏DOM的脚本
浏览器会无阻塞式(延迟)加载脚本,并且按页面中<script>标签顺序串行执行js脚本
在HTML渲染完毕之后,onload触发之前执行
支持:IE4.0+ ,FF3.5+
iiii.async属性
HTML5标准中为<script>标签定义的属性
对比defer,以下相同:
无阻塞式加载
以下不同:
加载完立即执行
不保证按照页面中<script>标签顺序执行
支持:FF3.6+ ,Chrome ,Opera10.5+ ,Safari ,IE9+
iiiii.不依赖浏览器版本的方式
Dynamic Script DOM ,比如google分析:

XHR Inject
XHR Eval
Script in Iframe
还有问题吗?当然还有:
i.并行、异步加载脚本也需要保证顺序、同源策略、CDN、缓存等因素的影响
ii.没有通用的解决方案,不过我们可以:
使用LABjs || requireJS || seaJS 等管理我们的脚本加载
服务端combo脚本
iii.以上可以相对完美的解决脚本下载问题,但这并不能解决脚本执行阻塞的问题
异步大法好
关于异步
i.你是否认为: 异步 == (方法 + 回调) ? 呵呵 ... 你懂得! 冒泡排序的异步例子:
var innerLoop = function (array, x, y, callback) {
if (y < array.length - x) {
compare(array[y], array[y + 1], function (r) {
if (r > 0) {
swap(array, y, y + 1, function () {
innerLoop(array, x, y + 1, callback);
});
} else {
innerLoop(array, x, y + 1, callback);
}
});
} else {
callback();
}
}
outerLoop(array, 0, function () {
console.log("done!");
}
);
var compare = function (x, y, callback) {
setTimeout(10, function () {
callback(x - y);
});
}
var swap = function (a, i, j, callback) {
var t = a[i]; a[i] = a[j]; a[j] = t;
repaint(a);
setTimeout(20, callback);
}
var outerLoop = function (array, x, callback) {
if (x < array) {
innerLoop(array, x, 0, function () {
outerLoop(array, x + 1, callback);
});
} else {
callback();
}
}
ii.你是否认为: 浏览器是单线程执行的 ?
iii.你是否使用 setTimeout || setInterval 模拟过多线程 ?
iiii.异步编程是有难度的:
破坏了代码的局部性
难以应用于需要保持顺序的场景
难以处理异常及取消
难以操作异步之间的协作及组合
问题根源:
i.javascript是单线程语言
不能创建线程
不能开展并行任务
不能对线程操作
ii.阻塞UI渲染
如何解决:
i.浏览器并不是单线程的货,我们可以利用如下异步线程:
资源下载线程(javacript、images、css、object)
ajax线程
web worker线程
setTimeout模拟多线程
总结
我们可以使用各种组合方式、现代浏览器的新特性去处理这些问题,总而言之,没有一种方案是通用的。我们需要在对应的场景中找出最合适的方案,而这些方案无非是围绕这些原理做出的变体。
浏览器中JavaScript执行原理的更多相关文章
- 浏览器中Javascript单线程分析
线程这个特性对于一门语言环境来说是尤其重要的,在Java/C++环境下都提供了多线程API操作. 但在Javascript中据说代码执行时单线程的,大量计算的逻辑会阻塞浏览器HTML渲染,但setTi ...
- 浏览器中js执行机制学习笔记
浏览器中js执行机制学习笔记 RiverSouthMan关注 0.0772019.05.15 20:56:37字数 872阅读 291 同步任务 当一个脚本第一次执行的时候,js引擎会解析这段代码,并 ...
- 浏览器中Javascript的加载和执行
在刚学习Javascript时曾对该问题在小组内做个一次StudyReport,发现其中的基础还是值得分析的. 从标题分析,可以加个Javascript的加载和执行分为两个阶段:加载.执行.而加载即浏 ...
- 浏览器中“JavaScript解析器”工作原理
浏览器在读取HTML文件的时候,只有当遇到<script>标签的时候,才会唤醒所谓的“JavaScript解析器”开始工作. JavaScript解析器工作步骤: 1.“找一些东西”: v ...
- web浏览器中javascript
1.异步载入一个js代码function loadasync(url) { var head = document.getElementsByTagName("head")[0]; ...
- javascript执行原理
执行环境 当执行流执行到函数时会创建一个执行环境,这个执行环境包含了函数内部 语句可以访问的所有变量和函数,当代码执行完时,销毁执行环境.所以一般情 况下,局部变量在函数执行完时会被销毁. 作用域.调 ...
- 浏览器解析JavaScript的原理
JavaScript的特点一般都知道的就是解释执行,逐行执行,就是从上到下依次执行. JavaScript的执行之前,其实还是有一些操作的,只是没有表现出来 JavaScript的执行过程: 1.语法 ...
- elasticsearch中filter执行原理深度剖析(bitset机制与caching机制)
(1)在倒排索引中查找搜索串,获取document list date来举例 word doc1 doc2 doc3 2017-01-01 * *2017-02-02 * *2017-03-03 ...
- JavaScript执行顺序分析
之前从JavaScript引擎的解析机制来探索JavaScript的工作原理,下面我们以更形象的示例来说明JavaScript代码在页面中的执行顺序.如果说,JavaScript引擎的工作机制比较深奥 ...
随机推荐
- uboot环境变量初始化
一.环境变量概述 1.环境变量的概念 可以理解为用户对软件的全局配置信息,这部分信息应该可以从永久性存储器上读取,能被查询,能被修改. 启动过程中,应该首先把环境变量读取到合适的内存区域,然后利用环境 ...
- PAT (Basic Level) 1001害死人不偿命的(3n+1)猜想 (15)
卡拉兹(Callatz)猜想: 对任何一个自然数n,如果它是偶数,那么把它砍掉一半:如果它是奇数,那么把(3n+1)砍掉一半.这样一直反复砍下去,最后一定在某一步得到n=1.卡拉兹在1950年的世界数 ...
- ruby定时脚本
ruby定时脚本的实现涉及到三个方面: 要定时执行的代码 定时控制(设置定时的时间) 将脚本后台化 实例: # in func.rb def func # the function body goes ...
- bzoj 3041: 水叮当的舞步 迭代加深搜索 && NOIP RP++
3041: 水叮当的舞步 Time Limit: 10 Sec Memory Limit: 128 MBSubmit: 72 Solved: 44[Submit][Status] Descript ...
- wireshark设置抓服务器的包
wireshark设置抓服务器的包:
- web版本控制
说说你在web开发中是怎么进行版本管理的 在web开发中,我首先将系统框架搭建完成后,我会发布到服务器上,然后给小组成员进行分工,为他们划分各自的模块,他们每天早上上班时就从服务器上先将自己机器上面的 ...
- 从 mian 函数开始一步一步分析 nginx 执行流程(四)
如不做特殊说明,本博客所使用的 nginx 源码版本是 1.0.14,[] 中是代码所在的文件! 这一节我们分析ngx_worker_process_cycle(),该函数代码比较少,因为它通过调用函 ...
- 在多台服务器上简单实现Redis的数据主从复制
Redis的主从复制功能非常强大,一个master可以拥有多个slave,而一个slave又可以拥有多个slave,如此下去,形成了强大的多级服务器集群架构.下面我演示下怎样在多台服务器上 ...
- KK的新书《必然》对未来科技趋势的预言
是他第一次在<失控>中提示我们-- 要用生物学而不是机械学的角度看待这个世界. 是他第一次在<科技想要什么>提示我们-- 科技本身就是一个生命体. 而在新书<必然 ...
- NOI题库05 派
05:派 Description 我的生日要到了!根据习俗,我需要将一些派分给大家.我有N个不同口味.不同大小的派.有F个朋友会来参加我的派对,每个人会拿到一块派(必须一个派的一块,不能由几个派的小块 ...