Webkit 内核初探

  • 作者: 阿吉
  • 校对&整理: lucifer

当下浏览器内核主要有 Webkit、Blink 等。本文分析注意是自 2001 年 Webkit 从 KHTML 分离出去并开源后,各大浏览器厂商魔改 Webkit 的时期,这些魔改的内核最终以 Chromium 受众最多而脱颖而出。本文就以 Chromium 浏览器架构为基础,逐层探入进行剖析。

引子

这里以一个面试中最常见的题目从 URL 输入到浏览器渲染页面发生了什么?开始。

这个很常见的题目,涉及的知识非常广泛。大家可先从浏览器监听用户输入开始,浏览器解析 url 的部分,分析出应用层协议 是 HTTPS 还是 HTTP 来决定是否经过会话层 TLS 套接字,然后到 DNS 解析获取 IP,建立 TCP 套接字池 以及 TCP 三次握手,数据封装切片的过程,浏览器发送请求获取对应数据,如何解析 HTML,四次挥手等等等等。 这个回答理论上可以非常详细,远比我提到的多得多。

本文试图从浏览器获取资源开始探究 Webkit。如浏览器如何获取资源,获取资源时 Webkit 调用了哪些资源加载器(不同的资源使用不同的加载器),Webkit 如何解析 HTML 等入手。想要从前端工程师的角度弄明白这些问题,可以先暂时抛开 C++源码,从浏览器架构出发,做到大致了解。之后学有余力的同学再去深入研究各个底层细节。

本文的路线循序渐进,从 Chromium 浏览器架构出发,到 Webkit 资源下载时对应的浏览器获取对应资源如 HTML、CSS 等,再到 HTML 的解析,再到 JS 阻塞 DOM 解析而产生的 Webkit 优化 引出浏览器多线程架构,继而出于安全性和稳定性的考虑引出浏览器多进程架构。

一. Chromium 浏览器架构

Webkit 内核初探_第1张图片

(Chromium 浏览器架构)

我们通常说的浏览器内核,指的是渲染引擎。

WebCore 基本是共享的,只是在不同浏览器中使用 Webkit 的实现方式不同。它包含解析 HTML 生成 DOM、解析 CSS、渲染布局、资源加载器等等,用于加载和渲染网页。

JS 解析可以使用 JSCore 或 V8 等 JS 引擎。我们熟悉的谷歌浏览器就是使用 V8。比如比较常见的有内置属性 [[scope]] 就仅在 V8 内部使用,用于对象根据其向上索引自身不存在的属性。而对外暴露的 API,如 __proto__ 也可用于更改原型链。实际上 __proto__ 并不是 ES 标准提供的,它是浏览器提供的(浏览器可以不提供,因此如果有浏览器不提供的话这也并不是 b ug)。

Webkit Ports 是不共享的部分。它包含视频、音频、图片解码、硬件加速、网络栈等等,常用于移植。

同时,浏览器是多进程多线程架构,稍后也会细入。

在解析 HTML 文档之前,需要先获取资源,那么资源的获取在 Webkit 中应该如何进行呢?

二.Webkit 资源加载

HTTP 是超文本传输协议,超文本的含义即包含了文本、图片、视频、音频等等。其对应的不同文件格式,在 Webkit 中 需要调用不同的资源加载器,即 特定资源加载器。

而浏览器有四级缓存,Disk Cache 是我们最常说的通过 HTTP Header 去控制的,比如强缓存、协商缓存。同时也有浏览器自带的启发式缓存。而 Webkit 对应使用的加载器是资源缓存机制的资源加载器 CachedResoureLoader 类。

如果每个资源加载器都实现自己的加载方法,则浪费内存空间,同时违背了单一职责的原则,因此可以抽象出一个共享类,即通用资源加载器 ResoureLoader 类。 Webkit 资源加载是使用了三类加载器:特定资源加载器,资源缓存机制的资源加载器 CachedResoureLoader 和 通用资源加载器 ResoureLoader

既然说到了缓存,那不妨多谈一点。

资源既然缓存了,那是如何命中的呢?答案是根据资源唯一性的特征 URL。资源存储是有一定有效期的,而这个有效期在 Webkit 中采用的就是 LRU 算法。那什么时候更新缓存呢?答案是不同的缓存类型对应不同的缓存策略。我们知道缓存多数是利用 HTTP 协议减少网络负载的,即强缓存、协商缓存。但是如果关闭缓存了呢? 比如 HTTP/1.0 Pragma:no-cache 和 HTTP/1.1 Cache-Control: no-cache。此时,对于 Webkit 来说,它会清空全局唯一的对象 MemoryCache 中的所有资源。

资源加载器内容先到这里。浏览器架构是多进程多线程的,其实多线程可以直接体现在资源加载的过程中,在 JS 阻塞 DOM 解析中发挥作用,下面我们详细讲解一下。

三.浏览器架构

浏览器是多进程多线程架构。

对于浏览器来讲,从网络获取资源是非常耗时的。从资源是否阻塞渲染的角度,对浏览器而言资源仅分为两类:阻塞渲染如 JS 和 不阻塞渲染如图片。

我们都知道 JS 阻塞 DOM 解析,反之亦然。然而对于阻塞,Webkit 不会傻傻等着浪费时间,它在内部做了优化:启动另一个线程,去遍历后续的 HTML 文档,收集需要的资源 URL,并发下载资源。最常见的比如

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