运作的流程
当你在浏览器地址输入内容的时候,浏览器进程的UI线程会捕捉你的输的内容
如果输入是网址,则UI线程会启动一个网路线程来请求DNS进行域名解析,接着开始连接服务器获取数据。
如果输入的是关键字,浏览器就会知道你要的是搜索,就会使用默认配置的搜索引擎来查询
1 当网路获取到数据到数据后,首先会检查站点是否是恶意站点,如果是则会提示一个警告页面,浏览器会
阻止你的访问(当然你也可以强行的继续访问),检查是否是恶意站点的方法有很多,比如检测IP地址是否在黑名单之内
2 当数据准备完毕,并且通过了安全检验,网路线程就会通知UI线程我准备好了,UI线程就会创建一个渲染进程来渲染页面
3 浏览器进程通过IPC管道将数据传递给渲染器进程进行渲染,渲染进程将接收到的数据也就是HTML(渲染进程的核心任务
就是把html,css,js image等渲染成用户可以交互的WEB页面)会被渲染进程的主线程进行解析,构造DOM数据结构
(DOM就是文档模型,是浏览器对页面在其内部的表现形式,是WEB开发人员可以通过JS与之交互的数据结构和API)
4 HTML首先进行tokeniser标记化,通过词法分析将输入的HTNL内容解析成多个标记,根据识别后的标记进行DOM数据构造
在DOM树构造的过程中,会创建document对象,然后以document为根节点的DOM树不断进行修改向其里面添加各种元素,HTML中
往往会引入额外的资源(图片,CSS,JS脚本)图片和CSS这些资源需要通过网络下载或者从缓存中直接加载,不会阻塞HTML的解析
但是当HTML解析时遇见script标签就会停止对HTML的解析,转而加载并执行JS,为什么?
应为浏览器不知道JS执行是否会改变当前页面的HTML构造,如果修改了HTML那么之前解析的HTML就没有任何意义了,这就为什么要
将script放在合适的位置,或者使用async/defer属性来异步加载JS
5 当HTML解析完成之后生成一个DOM树,但是我们不知道DOM树上的每一个节点应该长什么样子,主线程需要解析CSS并确认每一个
DOM节点的计算样式,哪怕你没有提供自定义的CSS样式,浏览器会有自己的默认样式表
6 在知道DOM结构和每个节点的样式后,接下来需要知道每个节点需要放在页面的那个位置,也就是坐标和要占多大的区域
这个阶段我们称为layout布局,主线程通过DOM和计算好的样式生成layout树,它上面每个节点都记录了X Y 坐标和占位大小,
这里需要注意一点DOM树和layout树并不是一一对应的,DOM树是解析HTML获得的并不关系样式,而layout树 DOM树
和计算好的样式生成的,所有他们并不是一一对应的
layout树是最后展示在屏幕上的节点对应的
7 当layout树生成完毕以后,我们还需要知道以什么样的顺序进行绘制这个节点,比如z-index会影响节点的绘制的层级关系
如果我们按照DOM的层级结构来绘制页面,则会导致渲染错误,为了保证正确层级,主线程会遍历layout树创建一个绘制记录表
(该记录表记录绘制的顺序,这个阶段我们称为paint)
8 以上完成之后就会把这些信息转换位像素点,显示在屏幕上,这种行为我们栅格化
主线程遍历layout树生成layer树(图层树)当layer树生成完毕和绘制顺序确定后主线程将这些信息转递给合成器线程
合成器线程将每一个图层栅格化,由于一层可能页面的整体长度是一样大,由此合成器线程会将他们分成许多个图块发送给
栅格化线程栅格化每个土块,并将他们存储在GPU内存中,当图块栅格化完成后,合成器线程会收集称为“draw quads”的图块信息
这些信息记录了图块在内存中的位置,和在页面的那个位置绘制图块信息,根据这些信息合成器线程会生成一个合成帧,然后通过
IPC传送给浏览器进程,接着浏览器进程将合成帧传送到GPU,然后GPU渲染展示到屏幕上,如果你的页面发生了变化,
则在走一边流程生成新的帧,传输到GPU,在由GPU渲染到页面上
以上就是完成的流程
重排
当我改变一个元素的尺寸位置属性时会重新触发样式计算布局,绘制以及后面的所有流程,这种行为称为重排
重绘
当改变一个元素的颜色属性时,不会重新进行样式机选布局,绘制以及后面的流程,这种就是重绘
重绘和重排所带来的问题
2 者都会占用主线程,包括JS也运行在主线程上,他们会抢占执行的时间,如果你写了一个不断导致重绘和重排的动画
浏览器则需要在每一帧都要运行样式,计算布局,和绘制的操作,如果一帧的时间内布局和绘制结束后还有时间JS就会获取到主线
的执行权,如果到下一帧执行的时候,JS没有归还主线,那么就会造成卡顿的现象
优化方法
1 使用requestAnimationFrame() 它会在每一帧调用,然后我们可以把JS运行任务分成一些更小的任务块分到每一帧
在每一帧时间用完之前归还主线程
2 使用Transfrom 该属性实现的动画不会经过布局和绘制,而是直接运行在合成器线程和栅格化线程,所以不会影响到
主线程中JS的执行,更重要的是Transfrom实现的动画由于不需要布局和绘制节省了很多的运算时间
进程和线程
1 进程:当启动一个程序的时候,就会创建一个进程执行任务代码,同时会为该进程分配一个内存空间,该程序的状态都保存在
这个内存中,当应用程序关闭时,该内存空间也会被回收,进程可以启动更多进程来执行任务,由于每一个进程分配的内存空间是
独立所以,如果2个进程之间需要通信的话通过IPC管道进行通信传递
2 线程: 进程可以将任务分成多个小任务,然后创建多个线程来并行执行不同的任务,
同一个进程下的线程,是可以直接通信共享数据的
www.bilibili.com/video/BV1x5…