Chrome 架构

2020-09-21  本文已影响0人  _1633_

    本文是 浏览器工作原理与实践 的 读书笔记 ,方便自己记忆。

浏览器

    浏览器 是 用户访问互联网最重要的接口。本质上,浏览器是方便一般互联网用户通过界面解析和发送 HTTP 协议的软件。


浏览器对前端的重要性

    前端的主要工作环境就是浏览器,前端只有了解了浏览器才能清楚的了解目前项目的问题,优化的方向,从而做出更好的产品,了解浏览器工作原理对 前端人员的意义

    1 从更高的维度审视页面

       要开发 流畅 的页面,或者诊断 Web 页面中的 性能问题,就需要了解 URL 是怎么变成页⾯的,只有弄懂这些之后,才可以站在全局的角度定位问题或者写 出高效的代码。了解了浏览器原理,通过全视野快速定位项目中 不合理 的地方。比如,首屏的显示就涉及了DNS、HTTP、DOM 解析、CSS 阻塞、 JavaScript 阻塞等技术因素,其中⼀项没处理好就可能导致整个页⾯的延时。

       了解了浏览器的工作原理,更加可以把这些知识点串成线,连成网,最终形成自己的知识体系,练就像专家⼀样思考问题、解决问题的能力。

    2 在快节奏的技术迭代中把握本质

          如果了解了浏览器的工作机制,那么你可以梳理出来前端技术的发展脉络,更加深刻地理解当前的技术,同 时你也会清楚其不⾜之处,以及演化⽅向。

        前端技术是如何针对这些核心诉求做演进 的: 

          ① 首先是脚本执行速度问题:不断修订和更新语⾔本⾝,这样你就应该知道ES6、ES7、ES8; 颠覆性地使用新的语⾔,WebAssembly;

          ② 前端模块化开发:WebComponents 的出现, 如果理解了浏览器工作原理,那么你会对 WebComponents 中涉及的 Shawdow DOM、HTML Templates 等 技术有更深刻的理解。

          ③ 渲染效率问题:如果理解浏览器的渲染流程,那么你应该知道⽬前页面的渲染依然存在很⼤缺陷,然后你就清楚如何避开这些问题,从而开发出更加⾼效的 Web 应⽤。


内核

   对于操作系统来说,内核是操作系统的核心,是第一层基于硬件的软件扩充,通过内核提供最核心最基础的服务。

   应用程序通过内核进行系统调用来使用计算机硬件,内核代码简洁高效。对于浏览器来说,同样存在浏览器内核,与操作系统内核相似,浏览器内核需要提供 API 给浏览器开发者使用,同时提供最核心的功能,如 加载  渲染网页,调用操作系统所提供的服务(比如 调用 CPU 等等)。

    对于浏览器厂商来说,高效使用和开发 浏览器内核 是 核心问题,对于 Web 开发者来说,理解浏览器内核的基本机制,才能开发出高性能的 Web 应用。


浏览器内核定义

   降维来讲,我们可以初步认为浏览器中 负责将表示页面的字符转变成可视化的图像的模块 就是 浏览器内核。不同的浏览器内核对网页编写语法的解释也有不同,因此同一网页在不同的内核的浏览器里的渲染(显示) 效果也可能不同,这也是网页编写者需要在不同内核的浏览器中测试网页显示效果的原因。

    我们这里研究的是 chrome 浏览器, 因为 chrome 的使用率比较高,chrome 以前是 Webkit 内核,现在是 Blink 内核。


Chrome架构

    chrome 打开一个页面需要启动多少个进程? 一般情况下需要 4个。

     进程 和 线程

        ⼀个进程就是⼀个程序的运行实例。详细解释就是,启动⼀个程序的时候,操作系统会为该程序创建⼀块内存,用来存放代码、运⾏中的数据和⼀个执⾏任务的主线程,我们把这样的⼀个运行环境叫 进程

       线程是依附于进程的,而进程中使用多线程 并行处理(同一时刻处理多个任务,大大提升性能)能提升运算效率 。

     进程和线程之间的关系有以下4个特点:

        1 进程中的任意⼀线程执行出错,都会导致整个进程的崩溃;

        2 线程之间共享进程中的数据;

        3 当⼀个进程关闭之后,操作系统会回收进程所占⽤的内存;

        4 进程之间的内容相互隔离(进程之间的通信 需要 IPC 机制)

            进程隔离式为了保护操作系统中进程互不干扰的技术,每一个进程只能访问自己占有的数据,避免数据 数据相互 ‘串场’。也正是因为进程之间的数据式相互隔离的,所以一个进程挂了,并 不会影响 其他的进程。


 原来的单进程浏览器时代

     单进程浏览器 是指 浏览器的 所有功能模块都运行在 同一个进程 里面, 这些模块包括了 网络、插件、Javascript 运行环境、渲染引擎 和 页面 等。

     单进程浏览器时代的问题

       1 不稳定

         早期浏览器需要借助插件 来实现类似 Web视频等功能,但是 插件是最容易出现问题的模块,并且还运行在浏览器进程中,所以 一个插件的崩溃 会导致 整个浏览器进程的崩溃。除了 插件 ,渲染引擎模块也不稳定,通常 一些复杂的 JavaScript 代码 就可能 引起 渲染引擎模块的崩溃 进而导致 整个 浏览器的奔溃。

       2 不流畅

         Javascript 运行在渲染进程中,所以 即使 阻塞了进程 也只是影响 当前的渲染页面,并不影响浏览器 和 其他页面,因为 其他页面的脚本 运行在 它们自己的渲染进程中。

       3 不安全

           不安全可以从 插件 和 页面脚本 两个方面解释:1 插件可以使用 C/C++ 代码编写,通过插件可以获取到 操作系统的任意资源,当你在页面运行一个插件时,也就意味着这个插件能完全操作你的电脑。如果是个恶意插件,那么他就可以做任何事情,比如释放病毒、窃取你的账号密码,引起安全问题;2 页面脚本可以通过浏览器的漏洞来获取系统权限,同样产生安全问题。 


   现在的 chrome 多进程架构

        4个主要进程

多进程

      浏览器进程(Browser):控制 Chrome 应用程序。包括地址栏、书签、后退和前进按钮等。还需要处理 Web 浏览器的权限管理,例如网络请求和文件访问。

      渲染器进程(Renderer):控制选项卡内,网站里显示的所有内容。核心任务是将 HTML、CSS 和 JavaScript 转换为用户可以与之交互的网页,排版引擎 Blink 和 JavaScript 引擎 V8 都是运行在该进程中,默认情况下,Chrome 会为每个 Tab 标签创建⼀个渲染进程。出 于安全考虑,渲染进程都是运⾏在沙箱模式下。渲染进程当然是多线程的,它包括了:GUI渲染线程、JS引擎线程、事件触发线程、定时触发器线程、异步http请求线程

 渲染器进程

         GUI 渲染线程

            负责渲染页面,布局和绘制

            页面需要重绘和回流时,该线程就会执行

            与 js 引擎线程 互斥,防止渲染结果不可预期

        JS 引擎线程

            负责处理解析和执行 javascript 脚本程序

            只有一个 JS 引擎线程(单线程)

            与 GUI 渲染线程互斥,防止渲染结果不可预期

         事件触发线程

            用来控制事件循环(鼠标点击、setTimeout、ajax等)

            当事件满足触发条件时,将事件放入到 JS 引擎所在的执行队列中

         定时触发器线程

            setInterval 与 setTimeout 所在的线程

            定时任务并不是由 JS 引擎计时的,是由定时触发线程来计时的

            计时完毕后,通知事件触发线程

         异步http请求线程

            浏览器有一个单独的线程用于处理AJAX请求

            当请求完成时,若有回调函数,通知事件触发线程

      插件进程(Plugin):主要是负责插件的运⾏,例如:Flash,因插件易崩溃,所以需要通过插件进程来隔离,以保证插件进程崩溃 不会对浏览器和⻚⾯造成影响。

      GPU 进程:独立于其他进程,专用于处理 GPU 任务,它被分成不同的进程,因为 GPU 会处理来自多个进程的请求,并将它们绘制在相同的 Surface 中。

     网络进程:主要负责页⾯的网络资源加载,之前是作为⼀个模块运⾏在浏览器进程⾥⾯的,直至最近才独立出来,成为⼀个单独的进程。


进程之间的相互协作

显示页面的过程

    首先,当我们是要浏览一个网页,我们会在浏览器的地址栏里输入URL,这个时候 Browser Process 会向这个URL发送请求,获取这个 URL 的 HTML 内容,然后将 HTML 交给 Renderer Process,Renderer Process 解析 HTML 内容,解析遇到需要请求网络的资源又返回来交给Browser Process进行加载,同时通知 Browser Process,需要 Plugin Process 加载插件资源,执行插件代码。解析完成后,Renderer Process 计算得到图像帧,并将这些图像帧交给GPU Process,GPU Process 将其转化为图像显示屏幕。


  多进程带来的好处

    多进程带来的好处,就是解决了单进程的缺点, 那么它是如何解决的:

     1 稳定性:由于 进程是相互隔离 的,所以当⼀个页面或者插件崩溃时,影响到的仅是当前的页面进程或者插件进程,并不会影响到浏览器和其他页⾯,这就完美地解决了页面或者插件的崩溃会导致整个浏览器崩溃,也就是不稳定的问题;

稳定性

     2 流畅性:JavaScript 也是运行在渲染进程中的,所以即使 JavaScript 阻塞了渲染进程,影响到的也只是当前的渲染页面,并不会影响浏览器和其他页⾯,因为其它页面的脚本是运行在它们自己的渲染进程中的;

     3 安全性:采用多进程架构的额外好处 是可以使用 安全沙箱, 降维来说,可以把沙箱看成是 操作系统给进程上了一把锁,沙箱里面的程序可以运行,但是不能再你的硬盘上写入任何数据,也不能再敏感位置读取任何数据,例如你的文档。 Chrome 把插件进程 和 渲染进程 锁再沙箱里面,这样,即使它们执行了恶意程序,恶意程序也无法突破沙箱取获取系统权限。


  多进程带来的问题

      凡事都有两面性,多进程带来好处的同时,也出现的新的问题:

      1 更高的资源占用:因为每个进程都会包含公共基础结构的副本(如 JavaScript 运行环境),这就意味着浏 览器会消耗更多的内存资源。  

         由于进程都有自己私有的内存空间,因此每个进程可能都会保存某个公共基础设施(比如 Chrome 的 JavaScript 引擎 V8)的多个副本。这会导致内存占用增多。为节省内存,Chrome 会限制自己可以打开的进程数量。限制的条件取决于设备内存和CPU配置。达到限制条件后,Chrome 会用一个进程处理同一个站点的多个标签页。

      2 更复杂的体系架构:浏览器各模块之间耦合性高、扩展性差等问题,会导致现在的架构已经很难适应新的 需求了。

    Chrome架构进化的目标是将整个浏览器程序的不同部分服务化,便于分割或合并。基本思路是在高配设备中,每个服务独立开进程,保证稳定;在低配设备中,多个服务合并为一个进程,节约资源。同样的思路也应用到了 Android 上。

    注意: Chrome 的默认策略是,每个标签对应一个渲染进程(Process-per-tab)。但是如果从一个页面打开了新页面,而新页 面和当前页面属于同一站点时,那么新页面会复用父页面的渲染进程。官方把这个默认策略叫 process-per-site-instance。


引用资料

    浏览器工作原理与实践

    Inside look at modern web browser

上一篇下一篇

猜你喜欢

热点阅读