浏览器的进程、线程、Web Worker及Event Loop

2019-12-17  本文已影响0人  李霖弢

进程和线程

系统会为进程分配cpu和内存
每个进程至少包含一个线程
不同进程之间也可以通信,不过代价较大

浏览器是多进程的

通过Chrome的更多工具 -> 任务管理器 可以查看进程信息
通常每个网页的渲染进程(Renderer)和每种第三方插件占用一个进程,所有网页公用一个Browser主进程(前进、后退、下载等)和GPU绘图进程

其中CSS由下载线程进行下载,不会阻塞DOM树解析,但会阻塞render树渲染


网页的渲染进程(Render)
  1. GUI线程
    负责绘制、回流、重绘。注意GUI线程不会和JS线程同时执行,执行JS时GUI会被暂时挂起
  2. JS引擎线程
    一个Tab页(renderer进程)中无论什么时候都只有一个JS线程在运行JS程序
  3. 事件触发线程
    来自浏览器内核的事件及JS引擎中的异步任务会被添加进事件触发线程,当对应的事件符合触发条件被触发时,该线程会把事件添加到待处理队列的队尾,等待JS引擎线程 的处理
  4. 定时触发器线程
  5. 异步http请求线程
    在XMLHttpRequest在连接后是通过浏览器新开一个线程请求
    将检测到状态变更时,如果设置有回调函数,异步线程就产生状态变更事件,将这个回调再放入事件队列中。再由JavaScript引擎执行。
Web Worker 线程 (IE11以上支持)

JS引擎线程向浏览器申请开一个子线程(仅能通过.postMessage()与JS线程交互,而且不能操作DOM)用于处理复杂JS,防止阻塞页面。
逻辑完成后应在主线程中调用.terminate()或Worker中调用close()方法关闭Worker以释放资源,否则会一直占用
postMessage传递对象时仅传值不传址(先将通信内容串行化,然后把串行化后的字符串发给 Worker,再还原。)

var worker = new Worker('test.js');
worker.postMessage('Hello World');
worker.postMessage({ method: 'echo', args: ['Work'] });

worker.onmessage = function (event) {
    console.log('Received message ' + event.data);
    worker.terminate();
}
// 写法零
self.addEventListener('message', function (e) {
  self.postMessage('You said: ' + e.data);
}, false);
// 写法一
this.addEventListener('message', function (e) {
  this.postMessage('You said: ' + e.data);
}, false);
// 写法二
addEventListener('message', function (e) {
  postMessage('You said: ' + e.data);
}, false);
复合图层(硬件加速)

dom改变会触发当前复合层的回流重绘,默认情况下所有dom处于同一复合层。
复合图层会占用额外资源。
通过硬件加速可以创建新的复合层,以提高重绘效率。

Event Loop

同步任务都在JS线程上执行,形成一个执行栈。
JS线程之外,事件触发线程管理着一个任务队列,异步任务完成后会将其回调加入任务队列。
一旦执行栈中的所有同步任务执行完毕(此时JS引擎空闲),系统就会读取任务队列,将可运行的异步任务添加到可执行栈中,开始执行。
定时器线程会在倒计时完成时将任务加入任务队列,但任务的执行依然得等到JS线程空闲,因此JS通过计时器执行任务是不准确的

macrotask与microtask

task->process.nextTick->其他jobs->渲染->task->...

    setTimeout(function(){
        console.log(1)
    },0);
    new Promise(function(resolve){
        console.log(2)
        for( var i=100000 ; i>0 ; i-- ){
            i==1 && resolve()
        }
        console.log(3)
    }).then(function(){
        console.log(4)
    });
    console.log(5);

// 2 3 5 4 1
setTimeout和setInterval
上一篇 下一篇

猜你喜欢

热点阅读