浏览器-架构

前言:

浏览器作为最重要的开发环境,是前端开发人员必须掌握的基础知识点,它贯穿着前端的整个网络体系。对浏览器原理的了解,决定着编写前端代码性能的上限。

CPU 与 GPU:

CPU 和 GPU 作为计算机中最重要的两个计算单元直接决定了计算性能。

CPU :

浏览器-架构_第1张图片
CPU 是计算机的大脑,负责处理各种不同的任务。在过去,大多数 CPU 是单芯片的,核心被安置在同一个芯片上。更新的 CPU 可以支持多核心,运算能力大大加强。

GPU:

浏览器-架构_第2张图片
GPU 是另一个计算机的组成部分,与 CPU 不同,GPU 更擅长利用多核心同时处理单一的任务。像命名那样,GPU 最初被用于处理图像。这就是为什么使用 GPU 可以更快、更顺畅的渲染页面内容。随着 GPU 的发展,越来越多的计算任务也可以使用 GPU 来处理。


进程与线程:

浏览器-架构_第3张图片
进程是应用正在运行的程序。而线程是进程中更小的一部分。当应用被启动,进程就被创建出来。程序可以创建线程来帮助其工作。操作系统会为进程分配私有的内存空间以供使用,当关闭程序时,这段私有的内存也会被释放。其实还有比线程更小的存在就是协程,而协成是运行在线程中更小的单位。async/await 就是基于协程实现的。

进程间通信(IPC):

浏览器-架构_第4张图片
一个进程可以让操作系统开启另一个进程处理不同的任务。当两个进程需要通信时,可以时用 IPC(Inter Process Communication)。

浏览器结构:

现代浏览器结构:
浏览器-架构_第5张图片

用户界面(The User Interface):

主要提供用户与Browser Engine交互的方法。包括地址栏、前进/后退按钮、书签菜单等。除了浏览器主窗口显示的您请求的页面外,其他显示的各个部分都属于用户界面。

浏览器引擎(The Browser Engine):

协调(主控)UI和 The Rendering Engine(在用户界面和呈现引擎之间传送指令)。 提供对The Rendering Engine的高级接口,一方面它提供初始化加载Url和其他高级的浏览器动作(如刷新、向前、退后等)方法。另一方面Browser Engine也为User Interface提供各种与错误、加载进度相关的消息。

呈现引擎(The Rendering Engine):

为给定的URL提供可视化的展示。它解析JavaScript、Html、Xml,并且User Interface中展示的layout。其中关键的组件是Html解析器,它可以让Rendering Engine展示差乱的Html页面。 值得注意:不同的浏览器使用不同的Rendering Engine。例如IE使用Trident,Firefox使用Gecko,Safai使用Webkit。Chrome和Opera使用Webkit(以前是Blink)

网络(The Networking):

基于互联网HTTP和FTP协议,处理网络请求。另外网络模块还提供获得到文档的缓存,以减少网络传输。为所有平台提供底层网络实现,其提供的接口与平台无关。

JavaScript 解释器(The JavaScript Interpreter):

用于解析和执行 JavaScript 代码,得到的结果传输到Rendering Engine来展示。

用户界面后端(The UI Backend):

用于绘制基本的窗口小部件,比如组合框和窗口。其公开了与平台无关的通用接口,而在底层使用操作系统的用户界面方法。

数据存储(The Data Storage):

这是持久层。浏览器需要在硬盘上保存各种数据,例如 Cookie、书签和偏好设置。新的 HTML 规范 (HTML5) 定义了“网络数据库”,这是一个完整(但是轻便)的浏览器内数据库。

主流浏览器的架构:

FireFox:

浏览器-架构_第6张图片
火狐浏览器的渲染引擎(Rendering Engine)使用的是Gecko;XML Parser解析器是Expat;Java Script解释器是Spider-Monkey(c语言实现)。

Chrome:

浏览器-架构_第7张图片
Chrome的渲染引擎Rendering Engine使用的是WebKit;XML Parser: libXML解析XML,libXSLT处理XSLT;JS解释器使用C++实现的V8引擎;

IE:

浏览器-架构_第8张图片
IE的渲染引擎主要是Trident,Scripting Engine有JScript和VBScript。

浏览器内核:

浏览器最重要或者说核心的部分是“Rendering Engine”,可大概译为“渲染引擎”,不过我们一般习惯将之称为“浏览器内核”。

渲染进程最重要的工作就是将 HTML、CSS 和 Javascript 代码转换成一个可以与用户产生交互的页面。
浏览器-架构_第9张图片

主要包括以下线程:

1. 浏览器 GUI 渲染线程:
  • HTML Parser 解析HTML文档,将元素转换为树结构DOM节点,称之为DOM Tree。
  • CSS Parser 解析Style数据,包括外部的CSS文件以及在HTML元素中的样式,用于创建CSS Tree,并合成Render Tree。
  • Layout 过程为每个节点计算出在屏幕中展示的准确坐标。
  • Painting 遍历 Render Tree,调用UI Backend提供的接口绘制每个节点。

2. JavaScript 引擎线程:

JS引擎线程负责解析Javascript脚本,一个Tab页(renderer进程)中无论什么时候都只有一个JS线程在运行JS程序。

GUI渲染线程与JS引擎线程是互斥的,所以如果JS执行的时间过长,这样就会造成页面的渲染不连贯,导致页面渲染加载阻塞:

  • 减少 JavaScript 加载对 DOM 渲染的影响(将 JavaScript 代码的加载逻辑放在 HTML 文件的尾部,减少对渲染引擎呈现工作的影响;
  • 避免重排,减少重绘(避免白屏,或者交互过程中的卡顿;
  • 减少 DOM 的层级(可以减少渲染引擎工作过程中的计算量);
  • 使用 requestAnimationFrame 来实现动画效果。

3. 浏览器定时触发器线程:

浏览器定时计数器并不是由 JavaScript 引擎计数的, 因为 JavaScript 引擎是单线程的, 如果处于阻塞线程状态就会影响记计时的准确, 因此通过单独线程来计时并触发定时是更为合理的方案.。

4. 浏览器事件触发线程:

事件被触发时该线程会把事件添加到待处理队列的队尾,等待 JavaScript 引擎的处理。这些事件可以是当前执行的代码块如定时任务、也可来自浏览器内核的其他线程如鼠标点击、AJAX 异步请求等,但由于 JavaScript 的单线程关系所有这些事件都得排队等待 JavaScript 引擎处理。

浏览器 http 异步请求线程:

在 XMLHttpRequest 在连接后是通过浏览器新开一个线程请求, 将检测到状态变更时,如果设置有回调函数,异步线程就产生状态变更事件放到 JavaScript 引擎的处理队列中等待处理。

Chrome浏览器中的多进程:

借助进程和线程,浏览器可以被设计成单进程、多线程架构,或者利用 IPC 实现多进程、多线程架构。

浏览器-架构_第10张图片
浏览器进程作为 Chrome 中最核心的进程,管理着 Chrome 中的其他进程,而 Renderer 则负责渲染不同的站点。

进程工作内容:

浏览器-架构_第11张图片

  • 浏览器进程(Browser process)
    浏览器进程负责管理 Chrome 应用本身,包括地址栏、书签、前进和后退按钮。同时也负责可不见的功能,比如网络请求、文件按访问等,也负责其他进程的调度。

  • 渲染进程(Renderer process)
    渲染进程负责站点的渲染,其中也包括 JavaScript 代码的运行,web worker 的管理等。

  • 插件进程(Plugin process)
    插件进程负责为浏览器提供各种额外的插件功能,例如 flash。

  • GPU 进程(GPU process)
    GPU 进程负责提供成像的功能。

总结:

  • 浏览器进程做为最重要的进程负责大多数页签外部的工作,包括地址栏显示、网络请求、页签状态管理等。
  • 不同的渲染进程负责不同的站点渲染工作,渲染进程间彼此独立。
  • 渲染进程在渲染页面的过程中会通过浏览器进程获取站点资源,只有安全的资源才会被渲染进程接收到。
  • 渲染进程中主线程负责除了图像生成外绝大多数工作,如何减少主线程上代码的运行是交互性能优化的关键。
  • 渲染进程中的合成线程和栅格线程负责图像生成,利用分层技术可以优化图像生成的效率。
  • 当用户与页面发生交互时,事件的传播途径从浏览器进程到渲染进程的合成线程再根据事件监听的区域决定是否要传递给渲染进程的主线程处理。

参考:
Chrome 浏览器架构

你可能感兴趣的:(浏览器,浏览器)