前端学习(一) 浏览器渲染原理

前言

浏览器的内核是指支持浏览器运行的最核心的程序,分为两个部分,一是渲染引擎,另一个是JS引擎,渲染引擎在不同的浏览器中也不是都相同的.目前市面上常见的浏览器内核可以分为4种: Trident( IE ), Gecko( FireFox ), Blink( Chrome,Opera ), Webkit( Safari ),以 Webkit 为例,对现代浏览器的渲染过程进行一个深度的剖析

页面加载过程

简介要点如下:

  • 浏览器根据 DNS 服务器得到域名的 IP 地址
  • 向这个 IP 的机器发送 HTTP 请求
  • 服务器收到,处理并返回 HTTP 请求
  • 浏览器得到返回内容

浏览器渲染过程

大体上分为如下三部分

  1. 浏览器会解析三个东西:

    1.1 一是HTML/SVG/XHTML, HTML 字符串描述了一个页面的结构,浏览器会把 HTML 结构字符串解析转换 DOM 树形结构

    1.2 二是CSS,解析 CSS 会产生 CSS 规则树,它和 DOM 结构比较像

    1.3 三是 JavaScript 脚本,等到 JavaScript 脚本文件加载后, 通过 DOM API 和 CSSOM API 来操作 DOM Tree 和 CSS Rule Tree

  2. 解析完成后,浏览器引擎会通过 DOM Tree 和 CSS Rule Tree 来构造 Rendering Tree

    2.1 Rendering Tree 渲染树并不等同于 DOM树,渲染树只会包括需要显示的节点和这些节点的样式信息

    2.2 CSS 的Rule Tree 主要是为了完成匹配并把 CSS Rule 附加上 Rrendering Tree 上的每个 Element(也就是每个 Frame)

    2.3 然后,计算每个 Frame 的位置,又叫做 layout 和 reflow 过程

  3. 最后通过调用操作系统 Native GUI 的 API 绘制

构建DOM

浏览器会遵循一套步骤将文件转换为 DOM 树:
构建DOM的具体步骤

  • 浏览器从磁盘或网络读取 HTML 的原始字节,并根据文件的指定编码将它们转换成字符串
  • 将字符串转换为Token,例如<html> <body>等. Token 中会标志出当前 Token 是"开始标签"或是"结束标签"或"文本"等信息,以维护节点与节点间的关系
  • 生成节点对象并构建DOM.构建 DOM 的过程中,不是等所有 Token 都转换完成后再去生成节点对象,而是一边生成 Token 一边消耗 Token 来生成节点对象,即每个Token被生成后,会立刻消耗这个 Token 创建出节点对象.带有结束标签标志的 Token 不会创建节点对象

假设有段 HTML 文本:

<html>
<head>
    <title>Web page parsing</title>
</head>
<body>
    <div>
        <h1>Web page parsing</h1>
        <p>This is an example Web page.</p>
    </div>
</body>
</html>

上面这段HTML会解析成这样:
请添加图片描述

构建CSSOM

DOM 会捕获页面的内容,但浏览器还需要知道页面如何展示, 所以需要构建CSSOM

构建CSSOM的过程和构建DOM的过程非常相似,当浏览器接收到一段CSS,浏览器首先要做的是识别出Token,然后构建节点并生成CSSOM
请添加图片描述
假设有这一段CSS:

body {font-size: 16px;}
p {color: red;}
p span {display:none;}
span {font-size: 14px;}
img {float: right;}

在经过一系列步骤后生成的CSSOM:
请添加图片描述
从图中还可以看出.body节点的子节点继承了 body 的样式规则(font-size: 16px).这就是层叠规则以及CSS为什么叫CSS(层叠样式表)

注意:CSS 匹配 HTML 元素是一个相当复杂和有性能问题的事情,所以,DOM树要小,CSS要尽量用id和class,不要过度层叠下去

构建渲染树

生成 DOM 树和 CSSOM 树之后,就要将这两棵树组合为渲染树.

渲染树只会包括需要显示的节点和这些节点的样式信息,如果某个节点是 display: none ,n那么就不会再渲染树中显示

渲染过程中,如果遇到 <script> 就停止渲染,执行 JS 代码.因为浏览器有 GUI 渲染线程与 JS 引擎线程,为了防止渲染出现不可预期的结果,这两个线程是互斥的关系. JavaScript 的加载,解析与执行会阻塞 DOM 的构建,也就是说,在构建 DOM 的时候,HTML 解析器若遇到了 JavaScript,就会暂停构建 DOM,等到 JavaScript 加载完毕,浏览器再从中断的地方恢复 DOM 构建

JS 文件不只是阻塞 DOM 的构建,它会导致 CSSOM 也阻塞 DOM 的构建

因为JavaScript不只是可以改 DOM,它还可以改 CSSOM.因为不完整的 CSSOM 是无法使用的,所以如果浏览器此时尚未完成 CSSOM 的下载和构建,却想要加载运行脚本,那么浏览器将延迟脚本执行和 DOM 构建,直至其完成 CSSOM 的下载和构建.也就是说, 在这种情况下,浏览器会先下载并构建 CSSOM,再执行JavaScript,最后再继续构建 DOM

因此,想首屏渲染的越快,就越不应该在首屏就加载 JS 文件,这也是都建议将 script 标签放在 body 标签底部的原因.当然在当下,并不是说 script 标签必须放在底部,因为你可以给 script 标签添加 defer 或者 async 属性

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值