浅谈浏览器页面渲染过程

作为前端开发,和浏览器打交道是必不可少的事情,因此我们需要对浏览器的相关原理有一个较为全面的了解,更要对浏览器的渲染过程深入的掌握,目的是将我们编写的代码渲染到页面时更流畅,提高用户的交互体验。

为了解上述过程,首先需要了解浏览器作为单独系统的组成部分。

浏览器主要结构:

1. 用户界面 - 包括地址栏、后退/前进按钮、书签目录等,也就是你所看到的除了用来显示你所请求页面的主窗口之外的其他部分。

2. 浏览器引擎 - 用来查询及操作渲染引擎的接口。

3. 渲染引擎 - 用来显示请求的内容,例如,如果请求内容为html,它负责解析html及css,并将解析后的结果显示出来。

4. 网络 - 用来完成网络调用,例如http请求,它具有平台无关的接口,可以在不同平台上工作。

5. UI后端 - 用来绘制类似组合选择框及对话框等基本组件,具有不特定于某个平台的通用接口,底层使用操作系统的用户接口。

6. js解释器 - 用来解释执行JS代码。

7. 数据存储 - 属于持久层,浏览器需要在硬盘中保存类似cookie的各种数据,Html5定义了web database技术,这是一种轻量级完整的客户端存储技术

 

从上面组件功能所知,页面的加载和渲染过程,需要网络系统、渲染引擎、javascript解释器和浏览器引擎共同协助互相配合执行。

浏览器页面渲染过程(CHROME为例)

浏览器页面渲染可拆分为两部分

页面导航:用户输入URL,浏览器进程请求和准备处理。

页面渲染:获取到相关资源后,渲染器进程负责选项卡内部的渲染处理。

页面导航过程

当用户在地址栏中输入内容时,会进行以下处理。

1.浏览器进程的 UI 线程会进行处理:如果是 URI,则会发起网络请求来获取网站内容,不是则进入搜索引擎。

2.若要发起网络请求,请求过程由网络线程来完成。HTTP 请求响应如果是 HTML 文件,则将请求回来的数据传递到渲染器进程;如果是其他文件会将数据传递到下载管理器。

3.如果请求响应为 HTML 内容,此时浏览器应导航到请求站点,网络线程便通知 UI 线程数据准备就绪。

4.接着UI 线程会寻找一个渲染器进程来进行网页渲染。当数据和渲染器进程都准备好后,HTML 数据通过 IPC 从浏览器进程传递到渲染器进程中。

5.渲染器进程接收 HTML 数据后,将开始加载资源并渲染页面。

6.渲染器进程完成渲染后,通过 IPC 通知浏览器进程页面已加载。

流程图:

页面渲染过程

主要有渲染器进程负责,它的核心工作是将选项卡内部的 HTML、CSS 和 JavaScript 转换为可交互的页面。

整体上,渲染器进程渲染页面的流程基本如下。

解析(Parser):解析 HTML/CSS/JavaScript 代码。

布局(Layout):确定每个节点位置、大小、颜色、是否换行、各种position/overflow/z-index属性等计算。

绘制(Paint):判断元素渲染层级顺序。

光栅化(Raster):将计算后的信息转换为屏幕上的像素。

流程如下图:

解析

渲染器进程的主线程会解析以下内容:

解析 HTML 内容,产生一个 DOM 节点树;

解析 CSS,产生 CSS 规则树;

解析 Javascript 脚本,由于 Javascript 脚本可以通过 DOM API 和 CSSOM API 来操作 DOM 节点树和 CSS 规则树,因此该过程中会等待 JavaScript 运行完成才继续解析 HTML。

解析完成后,我们得到了 DOM 节点树和 CSS 规则树,下一阶段是布局。

布局

通过解析之后,渲染器进程知道每个节点的结构和样式,但如果需要渲染页面,浏览器还需要进行布局,布局过程便是通过 DOM 节点树和 CSS 规则树来构造渲染树(Render Tree)的过程。

绘制

在绘制步骤中,渲染器主线程会遍历渲染树来创建绘制记录。

需要注意的是,如果渲染树发生了改变,则渲染器会触发重绘(Repaint)和重排(Reflow)。

重绘:屏幕的一部分要重画,比如某个 CSS 的背景色变了,但是元素的几何尺寸没有变。

重排:元素的几何尺寸变了(渲染树的一部分或全部发生了变化),需要重新验证并计算渲染树。

为了不对每个小的变化都进行完整的布局计算,渲染器会将更改的元素和它的子元素进行脏位标记,表示该元素需要重新布局。其中,全局样式更改会触发全局布局,部分样式或元素更改会触发增量布局,增量布局是异步完成的,全局布局则会同步触发。

重排需要涉及变更的所有的结点几何尺寸和位置,成本比重绘的成本高得多的多。所以我们要注意以避免频繁地进行增加、删除、修改 DOM 结点、移动 DOM 的位置、Resize 窗口、滚动等操作,因为这些操作可能会导致性能降低。

光栅化

通过解析、布局和绘制过程,浏览器获得了文档的结构、每个元素的样式、绘制顺序等信息。将这些信息转换为屏幕上的像素,这个过程被称为光栅化。

光栅化可以被 GPU 加速,光栅化后的位图会被存储在 GPU 内存中。根据前面介绍的渲染流程,当页面布局变更了会触发重排和重绘,还需要重新进行光栅化。此时如果页面中有动画,则主线程中过多的计算任务很可能会影响动画的性能。

因此,现代的浏览器通常使用合成的方式,将页面的各个部分分成若干层,分别对其进行栅格化(将它们分割成了不同的瓦片),并通过合成器线程进行页面的合成。

 

 合成过程如下:

1.当主线程创建了合成层并确定了绘制顺序,便将这些信息提交给合成线程;

2.合成器线程将每个图层栅格化,然后将每个图块发送给光栅线程;

3.光栅线程栅格化每个瓦片,并将它们存储在 GPU 内存中;

4.合成器线程通过 IPC 提交给浏览器进程,这些合成器帧被发送到 GPU 进程处理,并显示在屏幕上。

合成的真正目的是,在移动合成层的时候不用重新光栅化。因为有了合成器线程,页面才可以独立于主线程进行流畅的滚动。

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值