阅读学习 [从浏览器多进程到JS单线程,JS运行机制最全面的一次梳理 文章后的整理零碎知识点
包含的知识点的主要组成 :🔥**用于回顾知识点并整理
**
- 浏览器有那些进程 ;
- 进程和线程的关系
- Render 进程下的线程 有哪些?
- Brower 进程和渲染进程之间的关系 /通信 -- HTML 最初下载解析的部分
- HTML 解析中的部分 —— GUI 进程 ,async , defer 关键字 , js 引擎-执行 异步执行 js 文件(批量操作 DOM 元素 ) ,CSS 树是另一线程执行构建-但 render 树构建受其阻塞 , 两个 事件了解 on Load , onDOMContentLoaded ;
- js 引擎线程和 GUI 线程之间的关系 -- 互斥- 引出 DOM 更新可能由于批量计算缓慢卡顿 -- webWorker 使用 -- sharedWorker
- HTML 页面渲染过程 : 关键 复合图层的了解
- 事件循环机制 :计时器处理线程 , 事件处理线程 ,Http 请求线程
两个关键优先级 -- nextTick , setImmediate
浏览器内核可以广义的称为渲染进程 因为 - 浏览器的主要工作还是渲染展示内容
浏览器内核是多线程:
-
GUI 渲染线程 : HTML 解析,构建 DOM,渲染树同时处理布局和绘制;
关键 :**GUI 渲染和 js 引擎执行是互斥的** **2. JS 引擎线程 : js 代码处理 ,任务队列中任务执行** -
事件触发线程(维护事件队列) : 针对定时器事件,鼠标点击 , AJAX 请求这些 处理为任务添加到该线程维护的事件队列 , 待 JS 引擎任务处理完毕 。
-
定时触发器线程(管理定时器执行)
setTimeout中低于4ms的时间间隔算为4ms - 原因 : 异步的底层是需要等待线程执行的 ,无法做到 0ms 同步执行 ;
- 异步 Http 请求线程: ( 负责网络请求的处理 )
深入 Html 加载 GUI 渲染线程的执行 :
render 树 构建 (元素尺寸位置的计算 )layout , 绘制 patint,光栅化, GPU 合成图层 , 显示
- 构建出渲染树后 , 经历哪些流程最终绘制并显示出页面 :
分层 ,光栅化 ,绘制 , 布局, 显示 ;
Layout Paint (只是记录画什么-) 分层 (分成多个合成词-普通图层和复合图层-满足分层条件的部分-trasnslate,opacity-GPU 执行合成操作 ) 光栅化 (矢量绘制指令转为屏幕像素位图 ) 合成 -GPU 渲染( 图层按照层级叠加- 合并 ) -输出屏幕显示
- 何时需要借助 GPU 进程帮助渲染页面 ;
图层合成阶段 必须交给 GPU 进程 , 屏幕上屏
主动硬件加速、强制走 GPU ( 创建复合图层 )
-
- 使用 transform / opacity 做动画
- 3D 变换:
translate3d、rotate3d、perspective - 设置
will-change主动提示浏览器预分配 GPU 图层 - 媒体类:
<video>、WebGL、Canvas、3D 图形 - 滚动独立图层、固定定位悬浮元素
Html 文件中 前设置可以保证 DOM 加载完整 ,不需要异步顺序执行 defer ) , 不做处理时同步下载解析阻塞 GUI 界面渲染
两个 关键词属性解决问题 :
defer、async :
两者的执行时机和执行顺序区别
defer: HTML 完整解析完毕后 保持标签书写先后顺序**
async : 脚本下载完成立刻插队执行 谁先下载完,谁先执行(无序)
使用的不同场景 :
脚本之间有关联关系 ,且脚本需要操作 DOM 则需要 设置 defer 。
相关 两个事件 :
load事件与DOMContentLoaded :
DOMContentLoaded:
HTML + 样式表 + 阻塞 JS 执行完
关键区别在于大的图片,媒体数据的加载 和 async 大的加载 js 文件 ;
Load :
面全部静态资源(图片、媒体、字体)加载完成后触发
🔥常用场景 :
在页面所有资源加载完毕时 获取一些数据: 获取媒体资源尺寸、瀑布流、关闭全局 loading , 全站加载统计
事件循环整体逻辑 :
- 执行一个宏任务(栈中没有就从事件队列中获取)
- 执行过程中如果遇到微任务,就将它添加到微任务的任务队列中
- 宏任务执行完毕后,立即执行当前微任务队列中的所有微任务(依次执行)
- 当前宏任务执行完毕,开始检查渲染,然后GUI线程接管渲染
- 渲染完毕后,JS线程继续接管,开始下一个宏任务(从事件队列中获取)
两个优先执行 :
微任务中 nextTick , 宏任务中的 setImmediate
process.nextTick(function(){
console.log(7);
});
new Promise(function(resolve){
console.log(3);
resolve();
console.log(4);
}).then(function(){
console.log(5);
});
process.nextTick(function(){
console.log(8);
});