1、浏览器进程模型
1.1、何为进程
注:浏览器主要有上面三个进程,但不止这三个!
注:浏览器进程是主进程,网络进程和渲染进程都是主进程开启的。
所谓每秒把页面画60次,就是指帧率为60ms(FPS), 不停的在画,不停的在画,所以我们才会感觉流畅
注意:这里所看到的其它线程有比如用户点击按钮时用到的交互线程,或者开启定时器时用到的计时线程
计时器的线程非常复杂,比渲染线程还复杂,我们这里知道我们平常用的计时器就是交给计时线程处理的就行了。
解释:任务都是一样的,但是队列可以有多个,浏览器会根据任务的特点分到不同的队列里去,不同的队列,他们的执行顺序是有优先级的!!!!!!!!!
这里简单说下promise.then()内部的回调属于微队列,await console.log(1);console.log(1)是同步代码,但是后续就属于微队列了。其他的基本上都属于其它队列了。还有微队列 > 交互队列 > 延时队列,也就是说promise.then()的执行顺序要高于setTimeout
注意:学会画图,把几个队列都画出来,按顺序执行就行了!!
问:交互队列、延时队列、微队列、网络请求队列,谁的执行优先级高,排个顺序??
在浏览器中,执行优先级的顺序通常为:
- 微队列(Microtasks Queue):包括 Promise.then、MutationObserver 回调等。
- 交互队列(Interaction Queue):通常与用户事件有关,比如点击、输入等。
- 网络请求队列(Network Requests Queue):包括 fetch、XHR 请求等。
- 延时队列(Timers Queue):包括 setTimeout、setInterval 等。
执行顺序具体如下:
- 当一个事件循环开始时,微任务队列(或微队列)中的所有微任务将被依次执行,直到微任务队列为空。微任务的优先级最高。
- 接下来,用户交互事件优先处理。
- 然后处理网络请求完成后的回调(如 AJAX 完成后处理)。
- 最后处理延时任务,比如 setTimeout 和 setInterval 的回调。
总结的顺序是:
- 微队列
- 交互队列
- 网络请求队列
- 延时队列
这样确保了关键的小任务(微任务)能够最快地得到响应,同时用户交互的事件也能迅速响应,网络请求的回调次之,最后才是延时任务。
JS引擎线程和渲染线程(GUI线程)是浏览器中两个非常重要的线程,它们在浏览器的多线程架构中协同工作,共同负责网页的加载、渲染和交互。理解它们之间的关系对于深入理解浏览器的工作原理至关重要。
2、js引擎线程和渲染线程
2.1、JS引擎线程
- 功能:主要负责解析和执行JavaScript代码。
- 特点:
- 单线程执行:同一时间只能执行一个JavaScript任务。
- 处理异步操作:通过事件循环机制处理异步任务(如定时器、网络请求等)。
2.2、渲染线程(GUI线程)
- 功能:负责页面的渲染工作,包括解析HTML和CSS、构建DOM树、计算布局、绘制页面等。
- 特点:
- 与JS引擎线程互斥:当JS引擎线程执行JavaScript代码时,渲染线程会被阻塞,无法进行页面渲染。
- 高效渲染:通过分阶段渲染(如重排、重绘)优化性能。
2.3、它们之间的关系
- 互斥关系:
- 阻塞现象:当JS引擎线程在执行JavaScript代码时,渲染线程会被阻塞,无法进行页面的渲染。这是因为JavaScript代码可能会修改DOM或样式,导致页面需要重新渲染。
- 执行顺序:通常情况下,JS引擎线程先执行JavaScript代码,完成后渲染线程才会进行页面渲染。
- 协同工作:
- 事件循环:JS引擎线程通过事件循环机制处理异步任务,当执行栈中的同步代码执行完毕后,会从任务队列中取出异步任务的回调函数继续执行,期间渲染线程会在适当的时候进行页面渲染。
- 异步更新:通过异步操作(如setTimeout、Promise等),JS引擎线程可以在不阻塞渲染线程的情况下,安排后续的DOM更新和页面渲染。
- 优化策略:
- 批量更新:现代浏览器通过批量更新DOM和样式,减少重排和重绘的次数,提高渲染效率。
- Web Workers:使用Web Workers可以在后台线程中执行JavaScript代码,避免阻塞主线程(JS引擎线程和渲染线程)。
2.4、示例说明
// 同步JavaScript代码
console.log('开始执行JS代码');
document.body.innerHTML = '<p>新的内容</p>'; // 修改DOM
// 异步JavaScript代码
setTimeout(() => {
console.log('异步任务执行');
document.body.style.color = 'red'; // 修改样式
}, 1000);
console.log('继续执行JS代码');
javascript复制代码
- 执行过程:
- JS引擎线程开始执行同步代码,修改DOM。
- 同步代码执行完毕后,渲染线程进行页面渲染,显示新的内容。
- setTimeout将异步任务交给定时器线程处理,JS引擎线程继续执行后续代码。
- 异步任务完成后,其回调函数被放入任务队列。
- JS引擎线程在事件循环中取出并执行回调函数,再次修改样式。
- 渲染线程根据新的样式重新渲染页面。
2.5、总结
JavaScript是单线程的,意味着它一次只能执行一个任务。当JS引擎线程在执行JS代码时,它会占用主线程的全部资源,无法同时进行其他操作。
由于JS引擎线程和GUI渲染线程共享同一个主线程资源,当JS引擎线程在执行时,GUI渲染线程必须等待,无法同时进行页面渲染。
JS引擎线程和渲染线程在浏览器中紧密协作,但又互斥运行。JS引擎线程负责执行JavaScript代码,可能会触发渲染线程进行页面更新;而渲染线程在JS引擎线程执行代码时会暂时被阻塞,以避免渲染不一致的问题。通过事件循环和异步处理机制,浏览器能够在保证页面正确渲染的同时,高效地执行JavaScript代码。