深入了解现代浏览器
以Chrome 为例
应用程序时,将创建一个进程 Process
可能会再创建一个或多个线程帮助工作,这是可选的
进程被分配了一份内存,所有的程序状态都保存其中
一个Process 可以要求OS 启动另一个进程来运行不同的任务
进程间交流用IPC Inter Process Communication(互相进程通信)
Browser Process
控制地址栏、书签、前进后退按钮、隐身模式、网络请求、文件访问
与渲染Process 沟通
决定标签上的加载小圈圈的状态
页面需要关闭、要加载另一个页面时执行beforeunload 事件的回调方法
此进程包含Network thread,需要以来网络时,由此线程处理
Renderer Process
用以网站里的内容
每个标签页都有一个进程,某个挂了不影响其他的
每个进程都要包含V8 引擎等内容,开销很大。Chrome 根据电脑硬件的情况做标签页的进程上限
线程虽然可以共享进程的资源,但是标签页用了线程,一旦其中一个出问题整个进程就挂了
每个跨站的iframe 也会单独一个进程,主要为了安全,隔离他们,就无法未经同意访问对方的数据了
Main thread
解析文本字符串(HTML) 为DOM
加载HTML 提到的外部资源
遇到<script> 标签后停止解析HTML,先加载<script>
因为要假设js 里有document.write() 等颠覆DOM 结构的操作
解析CSS,即使开发者不提供样式,每个DOM 节点也有浏览器默认样式
Layout Tree 布局树
display:none 布局树中没有;DOM 树中存在
visibility:hidden 布局树中存在;DOM 树中存在
p::before{content:'x'} 布局树中存在;DOM 树中没有
布局树后还要考虑z-index 然后创建绘制记录(对绘画过程的注释)
绘画过程如 先背景,再文本、矩形
JS 操作<canvas> 就要考虑绘制过程
DOM、样式 修改,布局树跟着变动,然后重新绘制
Worker threads
动画元素、定时器等,和JS 一起在主线程执行,JS 动作大了就会阻塞
把JS 分成很多小块,运行一块JS 渲染一下动画帧
或把JS 放在Web Workers 中运行,不用阻塞主线程
Web Workers 就是执行JS 的另一个线程,可以多线程执行JS 啦
Worker 用不了document、window,不能操作本地文件,可以使用ajax
Worker 加载的js 必须同源、必须从网上下载
Compositor thread 合成线程
主线程把层树、绘制顺序信息交给合成线程
合成线程把图层划分为图块,交给像素化线程,像素化图块后存储到GPU 内存中
优先处理可视窗口中的内容
只用到这个线程的动画效果,如丝般顺滑。不会占用主线程
<https://www.html5rocks.com/en/tutorials/speed/high-performance-animations/>
滚动到页面上带有事件处理的区域Non-fast Scrollable region
会向主线程传输输入事件
没有事件处理区域则直接合成新帧,不用等待主线程
事件冒泡,只在顶层附加事件处理程序的话,会频繁等待主线程,无法平滑滚动
移动端touchstart 事件默认行为会滚动页面
监听后,浏览器会等200毫秒以确定回调函数中有没有preventDefault() 阻止默认行为
然而80% 的情况是没有preventDefault() 的,却每次都要等200毫秒
<https://www.cnblogs.com/ziyunfei/p/5545439.html>
用passive:true 来告知浏览器不用等了,我这个回调函数不会阻止默认行为
ele.addEventListener('touchstart',event=>{...},{passive:true})
触摸设备每秒发送60~120次触摸事件;鼠标每秒发送100次。高于屏幕刷新率。
chrome 会延迟调度,只在requestAnimationFrame 事件触发时调度
requestAnimationFrame 触发频率基本和屏幕刷新率同步
Raster thread 像素化线程
光栅化、栅格化或者像素化。就是把矢量图形转化成像素点儿的过程
把页面元素规划到N 个图层中,像素化每个图层
或者直接像素化页面的局部,没有图层的概念。这要根据性能做取舍
Utility Process
GPU Process
请求显卡把整个浏览器的样子绘制到显示设备上
Plugin Process
控制插件如Flash
<https://developers.google.com/web/updates/2018/09/inside-browser-part1>
<https://developers.google.com/web/updates/2018/09/inside-browser-part3>
https://app.yinxiang.com/shard/s5/nl/11952/8e17e181-2efc-45be-9cb8-53b3596a0bf0