Open homobulla opened 6 years ago
URL(笔记来源): https://juejin.im/post/5a6547d0f265da3e283a1df7
浏览器是多进程的,js是单线程的 进程是一个工厂,工厂有它的独立资源 ——> 系统分配的内存(独立的一块内存) 工厂之间的相互独立 -> 进程之间相互独立 多个工人协作完成任务 -> 多个线程在进程中协作完成任务 工厂内有一个或多个工人 -> 一个进程由一个或多个线程组成 工人之间共享空间 -> 同一进程下的各个线程之间共享程序的内存空间(包括代码段、数据集、堆等)
Browser进程:浏览器的主进程(负责协调、主控),只有一个。 第三方插件进程:每种类型的插件对应一个进程,仅当使用该插件时才创建 GPU进程:最多一个,用于3D绘制等 浏览器渲染进程(浏览器内核)
1. GUI渲染线程 2. JS引擎线程 3. 事件触发线程 4. 定时触发器线程 5. 异步http请求线程 GUI渲染线程与JS引擎线程是互斥的. 当JS引擎执行时GUI线程会被挂起(相当于被冻结了),GUI更新会被保存在一个队列中等到JS引擎空闲时立即被执行。 GUI渲染操作DOM,js操作也会操作DOM,为了防止二者冲突。JS引擎执行时间过长会阻塞页面。
web worker 可以使得后台线程执行任务而不干扰页面。
创建worker时,JS引擎开启一个子线程,且不能操作DOM. JS引擎线程与worker线程通过 postMessage API 方式通信。
JS分为同步任务和异步任务 同步任务都在主线程上执行,形成一个 执行栈 主线程之外,事件触发线程管理着一个 任务队列 ,只要异步任务有了运行结果,就在任务队列之中放置一个事件。 一旦执行栈中的所有同步任务执行完毕(此时JS引擎空闲),系统就会读取任务队列,将可运行的异步任务添加到可执行栈中,开始执行。
macrotask与microtask console.log('script start'); setTimeout(function() { console.log('setTimeout'); }, 0); Promise.resolve().then(function() { console.log('promise1'); }).then(function() { console.log('promise2'); }); console.log('script end');
macrotask
setTimeout
setInterval
microtask
Promise
process.nextTick
一 `macrotask`(又称之为宏任务),可以理解是每次执行栈执行的代码就是一个宏任务(包括每次从事件队列中获取一个事件回调并放到执行栈中执行) 1. 每一个task会从头到尾将这个任务执行完毕,不会执行其它. 2. 浏览器为了能够使得JS内部task与DOM任务能够有序的执行,会在一个task执行结束后,在下一个 task 执行开始前,对页面进行重新渲染 (task->渲染->task->...) 二 `microtask`(又称为微任务),可以理解是在当前 task 执行结束后立即执行的任务 1. 也就是说,在当前task任务后,下一个task之前,在渲染之前 2. 所以它的响应速度相比`setTimeout`(`setTimeout`是task)会更快,因为无需等渲染 3. 也就是说,在某一个`macrotask`执行完后,就会将在它执行期间产生的所有`microtask`都执行完毕(在渲染前)
执行一个宏任务(栈中没有就从事件队列中获取) 执行过程中如果遇到微任务,就将它添加到微任务的任务队列中 宏任务执行完毕后,立即执行当前微任务队列中的所有微任务(依次执行) 当前宏任务执行完毕,开始检查渲染,然后GUI线程接管渲染 渲染完毕后,JS线程继续接管,开始下一个宏任务(从事件队列中获取)
从浏览器多进程到js单线程
URL(笔记来源): https://juejin.im/post/5a6547d0f265da3e283a1df7
进程与线程 进程是cpu资源分配的最小单位(系统会给它分配内存) 线程是cpu调度的最小单位
浏览器包含的进程
浏览器的渲染进程 ---> 多线程
浏览器渲染进程包含的线程
web Worker
创建worker时,JS引擎开启一个子线程,且不能操作DOM. JS引擎线程与worker线程通过 postMessage API 方式通信。
从Event Loop谈JS的运行机制
JS中分为两种任务类型:macrotask和microtask
macrotask
:主代码块,setTimeout
,setInterval
等(可以看到,事件队列中的每一个事件都是一个macrotask)microtask
:Promise
,process.nextTick
等macrotask
中的事件都是放在一个事件队列中的,而这个队列由事件触发线程维护microtask
中的所有微任务都是添加到微任务队列(Job Queues)中,等待当前macrotask
执行完毕后执行,而这个队列由JS引擎线程维护(这点由自己理解+推测得出,因为它是在主线程下无缝执行的)运行机制