前言
首先声明该篇笔记部分是转载(抄)的,原文见
什么是Webkit
Webkit架构是现有chromium内核渲染引擎Blink的前身,Webkit的使用在很多场景下收到限制:
- webkit应用场景和google要发展的方向不匹配,webkit作为一个开源的浏览器内核,提供嵌入式接口(高达几百个), 而Google想商业化自己的浏览器,前者是面向开发者,后者面向用户。用户并不关心内部实现,而开发者需要关心,webkit如果改了架构, 这对开发者极不友好(对于开发者来说,了解这么庞大的一个内核是需要花费很多的时间的)。所以google决定自己做,不受制与人。
- google想提高自己产品的地位并且控制浏览器市场,这是它从开源试炼者到浏览器标准引导者的分水岭,Chromium内核Blink的开源不是情怀,是想让更多的浏览器厂商 为之动摇,用他们自己的浏览器内核(Blink),这样,它就有能力控制浏览器市场,占据有利的市场份额。
在多进程架构出现之前,浏览器的每个tab都是揉在一起的,这导致如果一个tab中的页面出现了未知错误,如果内部出现一个uncaughtError,整个 浏览器就有可能全退了,用户需要再次打开浏览器。对于浏览器软件架构的设计理念 – 速度,安全,稳定,易用,是极其不符的,因为 如果出现了安全漏洞所有渲染进程都是一条绳上的蚂蚱,很不稳定。
出于以上原因,Chromium从应用的视角变成了平台,技术架构也随之发生了改变,他们把一部分任务分摊开,如果是render进程出现的错误, 则在对应的tab上弹出一个页面崩溃的提示,点击确定之后,此tab就会消失,也就是对应的渲染进程。所以对于用户体验来说,多进程架构是 可行的。如图
一个 Browser 进程,和若干个render进程(上图示例为两个),render进程就是我们在浏览器中打开的tab,所以render进程和tab是一一对应的关系(实际上某些 特殊情况下有很多其他策略,比如同源一个Render进程)。
这完全符合平台化的chromium设计,把每个渲染进程,也就是用户(开发者)的脚本运行的环境,打造成一个沙盒,这里所有涉及网络安全和本地存储等 安全风险较大的模块,全部通过IPC发送给Browser进程去处理。而每个渲染进程中又有一些线程,比如IO线程和主线程(上图为HTML Renderer),主线程我们不陌生, IO线程主要与Browser进程通讯。下面会介绍各个线程的作用。
什么是Blink
Blink是Web平台的渲染引擎。粗略地说,Blink 实现了在浏览器选项卡中呈现内容的所有内容:实现 Web 平台的规范(例如 HTML 标准),包括 DOM、CSS 和 Web IDL;嵌入 V8 并运行 JavaScript;向底层网络堆栈请求资源;构建 DOM 树;计算样式和布局;嵌入 Chrome Compositor 并绘制图形。
Blink 被 Chromium、Android WebView 和 Opera 等许多客户通过内容公共 API 嵌入。
Blink 自己并不发起网络请求等敏感行为,Blink 是运行在render中的,render是运行在沙箱里的,因此Blink 只是对敏感行为请求做一个排队和转发。
浏览器进程和渲染进程
浏览器进程
从上图中可以看出浏览器进程中大致可以分为两个线程,主线程(UI线程)用于处理从浏览器界面的交互到衍生出一个渲染进程, 而IO线程,用于渲染进程和的消息传输。
UI/主线程
WebContents使用过electron的同学会熟悉一点,它表示的就是网页内容,但并不能向NW.js访问一个页面的上下文对象,只能通过IPC去通信。 由于一个页面有可能还会打开一个小窗口(window.open)所以这里这个名字是复数形式。也就是说创建一个渲染继承呢好难过之前, 必定创建一个WebContents实例。
WebContents上层大致有RenderViewHost,和RenderProcessHost两个类(如果细化大概有十几个类名),但RenderViewHost并不是和WebContents 一一对应的关系。
RenderViewHost表示从一个url输入到加载完毕(tab页上的小圈停止转动,onload事件)这个过程中的状态管理。大致分为三个状态,start, commit, finish. 开始解析url为start,然后进入commit阶段,它检测是否为合法地址或ssl证书失效,如果非法就直接render失败信息(常见的在chrome中输入url然后直接提示你 不存在的url或不可访问的地址等等都是在这个阶段检测的),如果通过检测,就去解析从这个url中获取的内容(通常为HTML格式),当把所有网络资源加载完毕, 此时到了finish阶段。这就是一个RenderViewHost实例的生命周期。
那么为什么一个webContents有可能对应多个RenderViewHost呢?因为一个页面中还会导航到另一个地址,这时为了缓存策略,不能直接舍弃掉当前已经加载好了的这个RenderViewHost, 当我们用 History API 或点击浏览器的后退按钮时,会直接把之前的页面渲染状态呈现出来,而不是重新加载一遍(这一点大多数人在浏览网页时都体会得到)。 所以RenderViewHost实例是和历史访问的条数对应的。下面再来一张多RenderViewHost的图。
上图中browser进程中也有两个RenderProcessHost实例(个数对应渲染进程),第二个RenderProcessHost拥有两个RenderViewHost,说明它有一个历史访问页面。
而RenderProcessHost主要用于给RenderProcess发送请求和处理来自Render进程处理的结果,RenderProcess收集的页面的任何敏感请求都是发送给RenderProcessHost进行处理
chromium 中的 RenderView(渲染视图)是渲染器进程中的一部分,负责管理和显示网页的视图内容。以下是关于 Chromium 的 RenderView 的一些关键信息:
功能:RenderView 负责将网页文档渲染为可视化的内容,包括 HTML、CSS 和 JavaScript 等。它负责处理用户输入(如鼠标点击和键盘输入)以及页面交互事件(如点击链接和提交表单)。RenderView 还负责协调和管理网页内容的布局和绘制。
在Chromium中,ResourceDispatcher(资源调度器)是一个关键组件,负责管理网络请求和响应的分发。以下是关于 Chromium 中 ResourceDispatcher 的一些关键信息:
ResourceDispatcher 负责处理从渲染进程发出的网络请求,并将其分发到适当的资源加载器。它管理网络请求的调度顺序,确保它们按照正确的顺序发送和接收。ResourceDispatcher 还负责处理重定向、身份验证、缓存和安全性等相关问题。
为什么这里有多个RenderView 呢?因为有时候有的页面里,可能会有多个web document(iframe可以加载新的document),每个RenderView 管理一个document,RenderView 和上面的RenderViewHost是一一对应的
IO线程
IO线程没什么好说的,主要负责和渲染,GPU进程通信
渲染进程
渲染进程是浏览器中的大动脉,动脉内是整个页面中的网络资源,本地存储,渲染层级树(Render Layer Tree),运送到心脏中处理(browser进程) 而每个动脉旁还有一些静脉,也就是线程,每个渲染进程中中至少有四个线程,根据不同的上下文还会创建更多的线程。
浏览器进程和渲染进程就知道上面这么多就行了
blink内核
Blink有一个主线程,N个工作线程。
几乎所有重要的事情都发生在主线程上。所有JavaScript(除了worker)、DOM、CSS、样式和布局计算都在主线程上运行。Blink被高度优化,以最大程度地提高主线程的性能。
对于跨线程通信,必须使用PostTask API进行消息传递。除了一些真正需要出于性能原因使用共享内存编程的地方外,不鼓励使用共享内存编程。这就是为什么在Blink代码库中不会看到太多MutexLocks的原因。
Blink就是页面的渲染器,简单理解就是Blink包含了页面的元素(html、js、css)如何和用户交互的API,RenderView 在处理页面元素的时候就需要向Blink(老版本的chrome是Webkit)调取API,比如说页面需要解析图片,图片在Webkit中是以ImageElement存在的,该ImageElement有src、图片大小等属性和处理属性的API,RenderView 调用这些API进行页面处理
源码目录概述
为什么要看renderer,因为就是renderer渲染的前端页面
//third_party/blink/renderer具有以下目录:
1 | platform/:Blink的一个集合,它是分解出来的较低级别功能。例如,几何和图形工具。 |
Blink and WebKit and V8
WebKit
WebKit 是一个开源的浏览器渲染引擎,最早由苹果从 KDE 的 KHTML 和 KJS 派生而来,用于 Safari 浏览器。
WebKit 包括两个核心子组件:WebCore负责 HTML、CSS 的解析和渲染;JavaScriptCore负责 JavaScript 的解析和执行(Safari 的 JS 引擎)
Blink
Blink 是 Google 在 2013 年从 WebKit fork 出来的一个独立渲染引擎项目,用于 Chromium 项目。
Blink 是 WebKit 的一个分支,但发展到现在,已经相当不同了。
Chromium 浏览器(包括 Chrome、Edge、Opera 等)使用的是 Blink + V8 架构,而非原始 WebKit。
所以:Blink ≠ WebKit,但 Blink 起源于 WebKit,后者可以看作是 Blink 的“祖先”。
V8
V8 是 Google 开发的 JavaScript 引擎,专门用于执行 JS 代码。
V8 是用 C++ 编写的,它不是渲染引擎的一部分,而是专门负责 JS 的编译和执行(JIT)。
V8 被集成到 Chromium 的 Renderer 进程中,与 Blink 一起协同工作。
所以Blink负责解析 HTML/CSS、构建 DOM、布局、绘制;V8执行 JS 代码(运行逻辑)
Chromium 多进程架构中它们怎么配合
在 Chromium 架构中,每个 Tab(页面)基本上是一个独立的 Renderer 进程,里面包含了:
1 | css复制编辑Renderer 进程 |
配合如下:
- Blink 负责解析 HTML/CSS,构建 DOM 和渲染页面;
- 当页面有 JS 代码时,Blink 会把 JS 代码交给 V8 来执行;
- JS 执行过程中如果涉及到 DOM 操作,V8 会通过绑定的 Blink DOM 接口操作 DOM;
- 所有 JS 引起的 UI 变化,最终都由 Blink 触发渲染流程。




