从进程和线程了解浏览器的工作原理

进程和线程

进程(process)和线程(thread)是操作系统的基本概念。

现代操作系统都是可以同时运行多个任务的,比如:用浏览器上网的同时还可以听音乐。对于操作系统来说,一个任务就是一个进程,比如打开一个浏览器就是启动了一个浏览器进程,打开一个 Word 就启动了一个 Word 进程。

有些进程同时不止做一件事,比如 Word,它同时可以进行打字、拼写检查、打印等事情。在一个进程内部,要同时做多件事,就需要同时运行多个“子任务”,我们把进程内的这些“子任务”称为线程。

由于每个进程至少要做一件事,所以一个进程至少有一个线程。

系统会给每个进程分配独立的内存,因此进程有它独立的资源。同一进程内的各个线程之间共享该进程的内存空间(包括代码段,数据集,堆等)。

如果电脑是 windows 系统,打开任务管理器,可以看到有一个后台进程列表,在这里我们可以看到每个进程的内存资源信息以及 CPU 占有率。

我们再用官方的术语描述一下:

进程是 CPU 资源分配的最小单位(是能拥有资源和独立运行的最小单位)。

线程是 CPU 调度的最小单位(是建立在进程基础上的一次程序运行单位)。

浏览器是多进程的

理解了进程和线程之后,接下来我们对浏览器进行一定程度上的认识。

浏览器是多进程的,每打开一个 tab 页,就相当于创建了一个独立的浏览器进程。

图中打开了 Chrome 浏览器的多个 tab 页,在 Chrome 任务管理器中可以看到有多个进程,每一个 tab 页有一个独立的进程。

注意:浏览器应该也有自己的优化机制,有时候打开多个 tab 页,在 Chrome 任务管理器中会看到有些进程被合并了,所以每个 tab 页对应一个进程并不一定是绝对的。

浏览器包含哪些进程?

为了简化理解,这里仅列举主要进程。

  • Browser 进程:浏览器的主进程,只有一个。

    • 负责浏览器界面的显示与交互;

    • 各个页面的管理,创建和销毁其他进程;

    • 网络的资源管理、下载等。

  • Renderer 进程:也称为浏览器渲染进程浏览器内核,内部是多线程的。主要负责页面渲染,脚本执行,事件处理等。

  • 第三方插件进程:每种类型的插件对应一个进程,仅当使用该插件时才创建。

  • GPU 进程:最多一个,用于 3D 绘制等。

浏览器多进程的优势

  • 由于默认 新开 一个 tab 页面 新建 一个进程,所以单个 tab 页面崩溃不会影响到整个浏览器;

  • 同样,第三方插件崩溃也不会影响到整个浏览器;

  • 多进程可以充分利用现代 CPU 多核的优势;

  • 方便使用沙盒模型隔离插件等进程,提高浏览器的稳定性。

系统为浏览器新开的进程分配内存、CPU 等资源,所以内存和 CPU 的资源消耗也会更大。

浏览器内核(渲染进程)

前面说了这么多的进程,对普通前端操作来说,最重要的还是渲染进程。

浏览器的渲染进程是多线程的,页面的渲染,JS的执行,事件的循环等,都在这个进程内执行。

渲染进程通常由以下常驻线程组成:

1. GUI 渲染线程

负责渲染浏览器界面,解析 HTML、CSS,构建 DOM tree和 render tree,布局和绘制等。当界面需要重绘(repaint)或由于某种操作引发回流(reflow)时,该线程就会执行。

2. JS 引擎线程

也称为 JS 内核,负责解析 JavaScript 脚本,运行代码。

  • JavaScript 是单线程的

    JavaScript 为什么是单线程的?这与它的用途有关。JavaScript 作为浏览器脚本语言,主要用途是与用户互动以及操作 DOM。这也决定了它只能是单线程的,否则会带来很复杂的同步问题。想想一下,如果 JavaScript 同时有连个线程,一个线程在某个 DOM 节点上添加内容,另一个线程删除了这个 DOM 节点,这时浏览器应该以哪个线程为准呢?所以,为了避免复杂性,JavaScript 从一开始就是单线程。

  • GUI 渲染线程 与 JS 引擎线程是互斥的

    由于 JavaScript 可以操作 DOM,如果在修改元素属性的同时渲染界面(即 JavaScript 引擎线程和 GUI 渲染线程同时运行),那么渲染线程前后获得的元素数据就可能会不一致。因此,为了防止渲染出现不可预期的结果,浏览器设置 GUI 渲染线程与 JS 引擎为互斥的关系。当 JS 引擎执行时,GUI 线程被挂起,GUI 更新被保存在一个队列中,等到 JS 引擎线程空闲时立即被执行。

  • JS 阻塞页面加载

    由于 GUI 渲染线程与 JS 引擎线程是互斥的,当浏览器在执行 JavaScript 的时候,GUI 渲染线程会被保存在一个队列中,直到 JS 程序执行完成,才会接着执行。因此如果 JS 执行时间过长,就会造成页面的渲染不连贯,导致页面渲染加载阻塞。

3. 事件触发线程

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

4. 定时触发器线程

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

5. 异步 http 请求线程

XMLHttpRequest 在建立连接后,通过浏览器新开一个线程请求,一旦检测到状态变更并且设置有回调函数,异步线程就产生状态变更事件,将这个回调再放入事件队列中,等待 JS 引擎空闲时处理。

Browser 进程和 Renderer 进程的通信过程

打开浏览器的一个 tab 页时,我们看下其中的大致过程:

  • Browser 进程收到用户请求,通过网络下载获取页面内容,然后将该任务通过RendererHost接口传递给 Renderer 进程;

  • Renderer 进程的 Renderer 接口收到消息,简单解释后,交给 GUI 渲染线程开始渲染;

    • GUI 渲染线程接收请求,加载网页并渲染网页,这个过程中可能需要 Browser 进程获取资源和 GPU 进程来帮助渲染,也可能会有 JS 引擎线程操作 DOM(可能造成回流并重绘);

    • 最后 Renderer 进程将结果传递给 Browser 进程;

  • Browser 进程接收到结果,并将结果绘制出来。

到这里应该对浏览器的运作有一定理解了,我们再来看下浏览器是怎么渲染页面的。

浏览器的渲染流程

浏览器内核拿到页面内容后,渲染过程大概分为以下几个部分:

  1. 解析 HTML 文件,生成 DOM tree;同时解析 CSS 文件以及样式元素中的样式数据,生成 CSS Rules。
  2. 构建 render tree:根据 DOM tree 和 CSS Rules 来构建 render tree,它可以让浏览器按照正确的顺序绘制内容。
  3. 布局(layout / reflow):计算各元素尺寸、位置。
  4. 绘制(paint):绘制页面像素信息。
  5. 浏览器将各层信息发送给 GPU,GPU 将各层信息合成(composite),显示在屏幕上。

补充:
Webkit 将 render tree 中的元素称为 render object (或 renderer),每一个 render object 都代表一个的矩形区域,通常对应于相关节点的 CSS 框,这些矩形的排列顺序就是它们在屏幕上显示的顺序。

Render object 和 DOM 节点是相对应的,但并非一一对应。非可视化的 DOM 元素不会插入 render tree 中,例如“head”元素 和 一些 display: none 的节点就没必要放在 render tree 中了。

这里只是大致的过程,详细步骤可以看参考资料中的第一篇。
渲染完成后,接下来就是 JavaScript 逻辑处理了。

参考资料

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 158,233评论 4 360
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 67,013评论 1 291
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 108,030评论 0 241
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 43,827评论 0 204
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 52,221评论 3 286
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 40,542评论 1 216
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 31,814评论 2 312
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 30,513评论 0 198
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 34,225评论 1 241
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 30,497评论 2 244
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 31,998评论 1 258
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 28,342评论 2 253
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 32,986评论 3 235
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 26,055评论 0 8
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 26,812评论 0 194
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 35,560评论 2 271
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 35,461评论 2 266

推荐阅读更多精彩内容