我们经常写 HTML 、 CSS 和 JavaScript ,写好这些之后,我们就会在浏览器中看到页面,那浏览器究竟在这背后做了一些什么事情呢?本篇文章将揭晓答案!
了解浏览器的渲染原理是我们在通往更深层次的前端开发中不可缺少的,它可以让我们从更深层次、角度去考虑性能优化等~
下面进入正文~
进程、线程
浏览器会分配一个线程“自上而下,从左到右”依次解析和渲染代码,那么进程和线程是什么,它们之间有着怎样的关系呢?
进程
一个进程就是一个程序运行的实例。当启动一个程序的时候,操作系统会为该程序创建一块内存,用来存放代码,运行中的数据和一个执行任务的主线程,这样的一个运行环境就叫进程
线程
线程不能单独存在,它是由进程来启动和管理的。线程依附于进程,进程中使用多线程并行处理能提升运算效率
两者之间的关系
1、进程中的任意一线程执行出错,都会导致整个进程的崩溃
2、线程之间可以共享数据
3、当一个进程关闭后,操作系统会回收进程所占用的内存
4、进程之间的内容相互隔离
渲染机制
从HTML、CSS和JavaScript开始
了解浏览器的渲染原理,我们就要从理解 HTML 、 CSS 和 JavaScrip 开始,我们先来看一张图
HTML (超文本标记语言),顾名思义,由标记(标签)和文本组成,每个标签都有自己的语意,浏览器会根据标签和文本展示对应的内容。
CSS (层叠样式表),由选择器和属性组成,它可以改变 HTML 的样式,比如上图中,我们改变了 span 的颜色由蓝色为绿色。
JavaScript ,我们可以通过 JS 完成很多事情,例如上图中修改样式。
下面开始分析渲染的原理
渲染流水线
渲染模块由于渲染的机制的复杂,被划分为了很多子阶段,输入的 HTML 经过这些子阶段,最后会输出为像素。这样的处理流程就叫做 渲染流水线
按照渲染的时间顺序,流水线可分为几个子阶段:构建 DOM 树、样式计算、布局阶段、分层、绘制、分块、光栅化和合成
构建DOM树
由于浏览器无法直接理解和使用 HTML ,所以需要将 HTML 转换为浏览器能够理解的结构( DOM 树)
树结构示意图
DOM树的构建过程
我们来分析一下下面这段代码会构建出一棵什么样的 DOM 树
我们先将上面的代码运行,然后在浏览器控制台输入 document ,看看会有什么效果
我们一层级一层级的打开就会看到如上图的效果,我们可以根据这每一层级展开的效果,绘制出一棵 DOM 树结构,如下:
接下来,我们试一下利用 JS 修改一下内容,看有什么改变:
我们可以看到“浏览器”的文字变成了“chrome”
再来看一下 DOM 树是否有改变
我们看到在“浏览器”的位置换成了“chrome”,那么如何让 DOM 节点拥有样式?
样式计算
样式计算,顾名思义,就是 计算出 DOM 节点中每个元素的具体样式 ,这个阶段会分为三部分:
把 CSS 转换为浏览器能够理解的结构
转换样式表中的属性值,使其标准化
计算出 DOM 树中每个节点的样式
CSS样式来源
link 导入外部样式资源
浏览器会新开辟一个线程,去服务器获取对应的资源文件(不阻碍主线程的渲染)
style 内嵌样式
从上到下解析,解析完继续解析 DOM 结构。在真实项目中,如果 css 代码不是很多,或是移动端项目,我们应该使用内嵌式,以此来减少 http 资源的请求,提高页面渲染速度
行内样式
@import 导入
它是同步的,不会开辟新线程去加载资源文件,而是让主线程去获取,这阻碍 DOM 结构的继续渲染;只有把外部样式导入进来,并且解析后,才会继续渲染 DOM 结构
把CSS转换为浏览器能够理解的结构
浏览器就像不能理解 HTML 一样,不理解 CSS ,所以当渲染引擎接收到 CSS 文件时,会执行转换操作,将 CSS 文本转换为浏览器可以理解的 styleSheets 结构。
在 HTML 中,在浏览器中输入 document 可以查看 html 的结构。在 css 中,可以输入 document.styleSheets 看到 css 的结构
现在的结构是空的,我们来加一些样式,看看效果
转换样式表中的属性值,使其标准化
属性值标准化就是将所有值转换为渲染引擎容易理解的、标准化的计算值。我们大致看一下效果:
标准化前
body { font-size: 2em; color: black; font-weight: bold; ...}复制代码
标准化后
body { font-size: 16px; color: rgb(0, 0, 0); font-weight: 700; ...}复制代码计算出DOM树中每个节点的具体样式
样式计算有两个CSS的规则:继承规则和层叠规则
CSS继承规则
CSS 继承就是每个 DOM 节点都包含有父节点的样式。我们来看一下下面这段代码中如何应用到 DOM 节点上
<!DOCTYPE html><html lang="en"><head> <meta charset="UTF-8"> <title>Document</title> <style> h1 { color: red; } div { color: blue; } span { font-size: 16px; } </style></head><body> <h1>掘金</h1> <div> <span>浏览器</span> <span>渲染原理</span> 构建DOM树 </div></body></html>