Skip to content

webkit学习 #3

@justcodebryan

Description

@justcodebryan

Webkit是什么

WebKit是一种用来让网页浏览器绘制网页排版引擎。它被用于Apple Safari。其分支Blink被用于基于Chromium的网页浏览器,如OperaGoogle Chrome。 - 摘自维基百科

当前市场上只有 3 个主要的浏览器引擎:Mozilla 的 Gecko、Google 的 Blink、还有苹果的 WebKit(Blink 的近亲)

Blink 是怎么回事?Blink 是 Google Chrome 浏览器的渲染引擎,V8 是 Blink 内置的 JavaScript 引擎。

所以v8是Blink的子集

标准浏览器组件

  • Parsing (HTML, XML, CSS, JavaScript)(解析器)
  • Layout(布局)
  • Text and graphics rendering(文字和图形渲染)
  • Image decoding(图像解码)
  • GPU interaction(GPU 交互)
  • Network access(网络访问)
  • Hardware acceleration(硬件加速)

不同的浏览器的异同点

这些浏览器的渲染引擎的共同点

  1. DOM, window, document
  2. CSSOM
  3. CSS解析, 属性值的处理
  4. HTML解析和DOM构建
  5. 布局和位置
  6. 开发者工具
  7. 其他的一些特性, 例如: contenteditable, pushState, File API, most SVG, CSS Transform math, Web Audio API, localStorage

浏览器渲染引擎的不同点

  1. GPU 相关技术

    • 3D 转换
    • WebGL
    • 视频解码
  2. 将 2D 图像绘制到屏幕

    • 解析方式
    • SVG 和 CSS 渐变绘制
  3. 文字绘制和断字

  4. 网络层(SPDY、预渲染、WebSocket 传输)

  5. JavaScript 引擎

    • JavaScriptCore 在 WebKit repo 中。V8 和 JavaScriptCore 被绑定在 WebKit 中。
  6. 表单控制器的渲染

  7. <video> 和 <audio> 的元素表现和解码实现

  8. 图像解码

  9. 页面导航 前进 / 后退

    • pushState() 的导航部分
  10. SSL 功能,比如 Strict Transport Security 和 Public Key Pins

2D图像部分, 不同的引擎用的是不同的库来渲染图像

img

WebKit Diagram

Chrome (OS X) Safari (OS X) QtWebKit Android Browser Chrome for iOS
Rendering Skia CoreGraphics QtGui Android stack/Skia CoreGraphics
Networking Chromium network stack CFNetwork QtNetwork Fork of Chromium’s network stack Chromium stack
Fonts CoreText via Skia CoreText Qt internals Android stack CoreText
JavaScript V8 JavaScriptCore JSC (V8 is used elsewhere in Qt) V8 JavaScriptCore (without JITting) *

WebKit的网页渲染过程

加载和渲染

浏览器的主要作用: URL -> 可视化的图像

两个过程:

  1. 网页加载过程, URL -> 构建DOM tree
  2. 网页渲染过程, DOM tree -> 可视化图像

两个过程交叉, 难以明确的区分

特征: 网页通常比我们的屏幕可视面积要大

整个过程中包含两块: 数据和模块

模块: HTML解释器, CSS解释器, JS引擎, 布局和绘图模块

数据: 网页内容, DOM, 内部表示和图像

数据的流向:

  • 从网页的URL到构建完DOM树

  • 从DOM树到构建完WebKit的绘图上下文

  • 从绘图上下文到生成最终的图像

image-20201201101121828

1. 用户输入网页URL, WebKit调用资源加载器加载该URL对应的网页
2. 加载器依赖网络模块建立链接, 发送请求并接受答复
3. WebKit接受到各种网页或者资源的数据, 其中某些资源可能是同步或者异步获取的
4. 网页被交给HTML解释器转变成一系列的词语(Token)
5. 解释器根据词语构建节点(Node), 形成DOM树
6. 如果节点是JavaScript代码, 调用JavaScript引擎解释并执行
7. JavaScript代码可能会修改DOM树的结构
8. 如果节点需要依赖其他资源, 例如图片, CSS, 视频等, 调用资源加载器来加载它们, 不会阻碍当前DOM树的继续创建, 如果是JavaScript资源URL(没有标记异步方式), 需要停止当前DOM树的创建, 知道JavaScript的资源加载并被JavaScript引擎执行后才继续DOM树的创建

DOM树构建完成之后 -> DOMContent事件

DOM树建完并且网页所依赖的资源都加载完之后 -> onload事件

CSS+DOM tree -> RenderObject tree

  1. CSS文件被CSS解释器解释成内部表示结构
  2. CSS解释器工作完成之后, 在DOM 树上附加解释后的样式信息, 形成RenderObject tree
  3. RenderObject节点在创建的同时, WebKit会根据网页的层次结构创建RenderLayer树, 同时构建一个虚拟的绘图上下文

image-20201201104300611

RenderObject Tree的创建并不是表示DOM树被销毁, 四种内部表示结构会一直存在

根据绘图上下文来生成最终的图像, 这一过程主要依赖2D和3D图形库

image-20201201104329896

具体过程:

  1. 绘图上下文是一个与平台无关的抽象类, 它将每个绘图操作桥接到不同的具体实现类, 也就是绘图具体实现类
  2. 绘图实现类也可以有简单的实现, 也可能有复杂的实现
  3. 绘图实现类将2D图形库或者3D图形库绘制的结果保存下载,交给浏览器来同浏览器界面一起显示

WebKit架构

image-20201201110920422

虚线框表示该部分模块在不同浏览器使用的WebKit内核中的实现是不一样的

chromium的多进程架构

优势:

  1. 避免的单个页面的不响应或者崩溃而影响整个浏览器的稳定性, 特别是对用户界面的影响
  2. 当第三方插件崩溃时不会影响页面或者浏览器的稳定性, 因为第三方插件也用单独的进程来运行
  3. 方便了安全模型的实施, 沙箱模型是基于多进程架构的

主要包含以下进程类型:

  1. Browser进程: 浏览器的主进程, 负责浏览器界面的显示, 各个页面的管理是所有其他类型进程的祖先, 负责他们的创建和销毁等工作, 他有且仅有一个

    方框代表进程, 连线代表IPC进程间通信

    image-20201201113623062

  2. Render进程, 负责页面的渲染工作, 可能有多个

  3. NPAPI插件进程, 该进程是为NPAPI类型的插件而创建, 其创建的基本原则是每种类型的插件是只会创建一次, 而且仅当时才被创建

  4. GPU进程, 最多只有一个, 当且仅当GPU硬件加速打开的时候才会被创建, 主要用于对3D图像加速调用的实现

  5. Pepper插件进程: 同NPAPI插件进程, 为Pepper插件创建的进程

  6. 其他类型的进程

特征:

  1. Browser进程和页面的渲染是分开的, 这保证了页面的渲染导致的崩溃不会导致浏览器主界面的崩溃
  2. 每个网页是独立的进程, 这保证了页面之间相互不影响
  3. 插件进程也是独立的, 插件本身的问题不会影响浏览器主界面和网页
  4. GPU硬件加速进程也是独立的

Chromium允许用户配置Render进程被创建的方式

  • Process-per-site-instance: 每个页面都创建一个独立的Render进程(好处是互不影响, 坏处是资源的巨大浪费)
  • Process-per-site: 属于同一个域的页面共享同一个进程, 而不同属一个域的页面则分属不同的进程(好处内存消耗小, 坏处可能出现特别大的render进程)
  • Process-per-tab: 每个tab都创建一个独立的进程, 不管是否是不同域不同实例
  • Single Process: 不为页面创建任何独立的进程, 所有渲染工作都是在Browser进程中进行. 他们是Browser进程中的多个线程. 在Android WebView中被采用

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions