这些浏览器工作原理你都吃透了吗?
点击上方“逆锋起笔”,公众号回复 PDF
领取大佬们推荐的学习资料
浏览器内有哪些进程,这些进程都有些什么作用
浏览器地址输入URL后,内部的进程、线程都做了哪些事
我们与浏览器交互时,内部进程是怎么处理这些交互事件的
进程
和线程
。进程
,进程启动后,CPU会给该进程分配相应的内存空间,当我们的进程得到了内存之后,就可以使用线程
进行资源调度,进而完成我们应用程序的功能。互不影响
,也就是说,当其中一个进程挂掉了之后,不会影响到其他进程的执行,只需要重启挂掉的进程就可以恢复运行。浏览器的多进程架构
浏览器进程 (Browser Process):负责浏览器的TAB的前进、后退、地址栏、书签栏的工作和处理浏览器的一些不可见的底层操作,比如网络请求和文件访问。
渲染进程 (Renderer Process):负责一个Tab内的显示相关的工作,也称渲染引擎。
插件进程 (Plugin Process):负责控制网页使用到的插件
GPU进程 (GPU Process):负责处理整个应用程序的GPU任务
Browser Process
会向这个URL发送请求,获取这个URL的HTML内容,然后将HTML交给Renderer Process
,Renderer Process
解析HTML内容,解析遇到需要请求网络的资源又返回来交给Browser Process
进行加载,同时通知Browser Process
,需要Plugin Process
加载插件资源,执行插件代码。解析完成后,Renderer Process
计算得到图像帧,并将这些图像帧交给GPU Process
,GPU Process
将其转化为图像显示屏幕。多进程架构的好处
多进程架构优化
Renderer Process
的作用是负责一个Tab内的显示相关的工作,这就意味着,一个Tab,就会有一个Renderer Process,这些进程之间的内存无法进行共享,而不同进程的内存常常需要包含相同的内容。浏览器的进程模式
Process-per-site-instance (default) - 同一个 site-instance 使用一个进程
Process-per-site - 同一个 site 使用一个进程
Process-per-tab - 每个 tab 使用一个进程
Single process - 所有 tab 共用一个进程
site 指的是相同的 registered domain name(如:google.com ,bbc.co.uk)和scheme (如:https://)。比如a.baidu.com和b.baidu.com就可以理解为同一个 site(注意这里要和 Same-origin policy 区分开来,同源策略还涉及到子域名和端口)。
site-instance 指的是一组 connected pages from the same site,这里 connected 的定义是 can obtain references to each other in script code 怎么理解这段话呢。满足下面两中情况并且打开的新页面和旧页面属于上面定义的同一个 site,就属于同一个 site-instance
Single process
,顾名思义,单进程模式,所有tab都会使用同一个进程。接下来是Process-per-tab
,也是顾名思义,每打开一个tab,会新建一个进程。而对于Process-per-site
,当你打开 a.baidu.com 页面,在打开 b.baidu.com 的页面,这两个页面的tab使用的是共一个进程,因为这两个页面的site相同,而如此一来,如果其中一个tab崩溃了,而另一个tab也会崩溃。Process-per-site-instance
是最重要的,因为这个是 Chrome 默认使用的模式,也就是几乎所有的用户都在用的模式。当你打开一个 tab 访问 a.baidu.com ,然后再打开一个 tab 访问 b.baidu.com,这两个 tab 会使用两个进程。而如果你在 a.baidu.com 中,通过JS代码打开了 b.baidu.com 页面,这两个 tab 会使用同一个进程。默认模式选择
Process-per-site-instance
作为默认的进程模式呢?Process-per-site-instance
兼容了性能与易用性,是一个比较中庸通用的模式。相较于 Process-per-tab,能够少开很多进程,就意味着更少的内存占用
相较于 Process-per-site,能够更好的隔离相同域名下毫无关联的 tab,更加安全
网页加载过程
Browser Process
负责,针对工作的不同,Browser Process 划分出不同的工作线程:UI thread:控制浏览器上的按钮及输入框;
network thread:处理网络请求,从网上获取数据;
storage thread:控制文件等的访问;
第一步:处理输入
UI thread
会判断输入的内容是搜索关键词(search query)还是URL,如果是搜索关键词,跳转至默认搜索引擎对应都搜索URL,如果输入的内容是URL,则开始请求URL。第二步:开始导航
UI thread
将关键词搜索对应的URL或输入的URL交给网络线程Network thread
,此时UI线程使Tab前的图标展示为加载中状态,然后网络进程进行一系列诸如DNS寻址,建立TLS连接等操作进行资源请求,如果收到服务器的301重定向响应,它就会告知UI线程进行重定向然后它会再次发起一个新的网络请求。第三步:读取响应
network thread
接收到服务器的响应后,开始解析HTTP响应报文,然后根据响应头中的Content-Type
字段来确定响应主体的媒体类型(MIME Type),如果媒体类型是一个HTML文件,则将响应数据交给渲染进程(renderer process)来进行下一步的工作,如果是 zip 文件或者其它文件,会把相关数据传输给下载管理器。第四步:查找渲染进程
第五步:提交导航
Browser Process
会向 Renderer Process
发送IPC消息来确认导航,此时,浏览器进程将准备好的数据发送给渲染进程,渲染进程接收到数据之后,又发送IPC消息给浏览器进程,告诉浏览器进程导航已经提交了,页面开始加载。第六步:初始化加载完成
网页渲染原理
一个主线程(main thread)
多个工作线程(work thread)
一个合成器线程(compositor thread)
多个光栅化线程(raster thread)
构建DOM
子资源加载
img
、link
等标签,预加载扫描程序会把这些请求传递给Browser Process
的network thread进行资源下载。JavaScript的下载与执行
标签,渲染引擎会停止对HTML的解析,而去加载执行JS代码,原因在于JS代码可能会改变DOM的结构(比如执行document.write()
等API)
标签上添加了 async
或 defer
等属性,浏览器会异步的加载和执行JS代码,而不会阻塞渲染。样式计算 - Style calculation
标签或者
标签的CSS资源,会加载CSS代码,根据CSS代码确定每个DOM节点的计算样式(computed style)。布局 - Layout
绘制 - Paint
合成 - Compositing
光栅化
(rasterizing)。will-change
CSS 属性的元素,会被看做单独的一层,没有 will-change
CSS属性的元素,浏览器会根据情况决定是否要把该元素放在单独的层。GPU Process
的内存中。绘画四边形:包含图块在内存的位置以及图层合成后图块在页面的位置之类的信息。
合成帧:代表页面一个帧的内容的绘制四边形集合。
Browser Process
,但是Browser Process只知道事件发生的类型和发生的位置,具体怎么对这个点击事件进行处理,还是由Tab内的Renderer Process
进行的。Browser Process接受到事件后,随后便把事件的信息传递给了渲染进程,渲染进程会找到根据事件发生的坐标,找到目标对象(target),并且运行这个目标对象的点击事件绑定的监听函数(listener)。非快速滚动区域
(non-fast scrollable region),如果事件发生在这些存在标注的区域,合成器线程会把事件信息发送给主线程,等待主线程进行事件处理,如果事件不是发生在这些区域,合成器线程则会直接合成新的帧而不用等到主线程的响应。document.body.addEventListener('touchstart', event => {
if (event.target === area) {
event.preventDefault()
}
})
passtive
参数为 true,passtive
会告诉浏览器你既要绑定事件,又要让组合器线程直接跳过主线程的事件处理直接合成创建组合帧。document.body.addEventListener('touchstart', event => {
if (event.target === area) {
event.preventDefault()
}
}, {passive: true});
查找事件的目标对象(event target)
浏览器对事件的优化
requestAnimationFrame
之前。关注我,获资源干货 ?关注 程序员干货分享