【前端性能优化】浏览器渲染原理与性能优化
目录
- 1. 浏览器渲染基本步骤
- 2. 构建DOM树、CSSOM树
- 3. 构建渲染树
- 4. 计算渲染树的布局
- 5. 将布局渲染到屏幕上
- 6. 渲染优化
1. 浏览器渲染基本步骤
浏览器主要有以下步骤:
- 浏览器通过HTTP协议向服务端请求页面数据
- 将请求回来的HTML文件解析成DOM树
- 将请求回来的CSS文件解析成CSSOM树
- 将DOM树和CSSOM树结合在一起,生成渲染树(render tree)
- 计算渲染树的布局,这实际上是回流的过程
- 将布局渲染到屏幕上,这实际上是重绘的过程
大致过程如图所示:
这里主要说说后面解析的过程。
2. 构建DOM树、CSSOM树
构建DOM树:
首先来看HTML文件的解析,在解析过程中,如果遇到 <script>
就会停止页面的解析,先执行标签中的JavaScript代码,如果代码时外联的形式,也需要等待外联的JavaScript代码下载并执行完才继续执行解析HTML的工作,解析完HTML文件之后,就会触发DOMContentLoaded
事件,这时就可以操作DOM了。
构建CSSOM树:
下面来看CSS的解析,我们从上面的图中可以看到HTML解析和CSS解析是同步进行的,也就是并行处理的,这样就不会在渲染的内容没有样式。在解析过程中,如果遇到script标签,和上面的处理方式一样。CSS解析器最终会将CSS解析为CSSStyleSheet(也就是CSSOM树),具体的结果如下:
CSS是一种渲染阻塞资源(render blocking resource),它需要完全被解析完毕之后才能进入生成渲染树的环节。
由于CSS有些属性具有继承性,后面定义的样式可能会覆盖或修改前面的样式,所以只有当所有的CSS代码都执行渲染完之后才能进入下一个环节。在CSSOM构建完成之前,页面都会处于白屏状态,所以,一般都是在文件的头部引入CSS文件。
3. 构建渲染树
当DOM树和CSSOM树都解析完之后,就会一起合成渲染树( Render Tree ),如下图所示:
在合并生成渲染树的过程中,有以下几点需要注意:
- 元素如果被设置为
display:non
e,在 DOM 树中依然会显示,但是在 Render 树中不会显示; - 元素如果被设置为
visibility:none
,那么 DOM 树和 Render 树中都会显示; - 我们经常说的脱离文档流,其实就是脱离 Render Tree。
4. 计算渲染树的布局
这一步实际上就是回流的过程。在这一阶段,会从渲染树的根节点开始遍历,由于渲染树的每个节点都是一个Render Object 对象,这个对象包含元素的的宽高、位置、颜色、内容等信息。所以浏览器会根据这些信息来确定每个节点对象在页面上的位置和大小,这一阶段输出的就是盒子模型,它会精确捕获每个元素在屏幕内的确切位置和大小,不过需要注意的是:设置了float,absoulte,fixed的元素会发生位置偏移。
5. 将布局渲染到屏幕上
在绘制阶段,浏览器会遍历渲染树,调用渲染器的paint()
方法在屏幕上显示其内容。
上述五个步骤都是浏览器渲染进程中的GUI渲染线程完成的。
GUI渲染线程主要的工作如下:
- 负责渲染浏览器页面,解析HTML、CSS,构建DOM树、CSSOM树、渲染树和绘制页面
- 当界面需要重绘或由于某种操作引发回流时,该线程就会执行
6. 渲染优化
针对JavaScript:
JavaScript既会阻塞HTML的解析,也会阻塞CSS的解析。因此我们可以对JavaScript的加载方式进行改变,来进行优化:
(1)尽量将JavaScript文件放在body的最后
(2) body中间尽量不要写<script>
标签
(3)- <script>
标签的方式有三种,有一种就是我们常用的直接引入,还有两种就是使用 async 属性和 defer 属性来异步引入,两者都是去异步加载外部的JS文件,不会阻塞DOM的解析(尽量使用异步加载)。三者的区别如下:
- script 立即停止页面渲染去加载资源文件,当资源加载完毕后立即执行js代码,js代码执行完毕后继续渲染页面
- async 是在下载完成之后,立即异步加载,加载好后立即执行,多个带async属性的标签,不能保证加载的顺序
- defer 是在下载完成之后,立即异步加载。加载好后,如果 DOM 树还没构建好,则先等 DOm 树解析好再执行;如果DOM树已经准备好,则立即执行。多个带defer属性的标签,按照顺序执行
针对CSS:
使用css有三种方式:使用link、@import、内联样式,其中link和@import都是导入外部样式。它们之间的区别:
- link:浏览器会派发一个新等线程(HTTP线程)去加载资源文件,与此同时GUI渲染线程会继续向下渲染代码
- @import:GUI渲染线程会暂时停止渲染,去服务器加载资源文件,资源文件没有返回之前不会继续渲染(阻碍浏览器渲染)
- style:GUI直接渲染
另外外部样式如果长时间没有加载完毕,浏览器为了用户体验,会使用浏览器会默认样式,确保首次渲染的速度。所以CSS一般写在headr中,让浏览器尽快发送请求去获取css样式。
所以,在开发过程中,导入外部样式使用link,而不用@import。如果css少,尽可能采用内嵌样式,直接写在style标签中。
针对DOM树、CSSOM树:
可以通过以下几种方式来减少渲染的时间:
- HTML文件的代码层级尽量不要太深
- 使用语义化的标签,来避免不标准语义化的特殊处理
- 减少CSSD代码的层级,因为选择器是从左向右进行解析的
减少回流与重绘:
这里就不多说了,参考《【前端性能优化】回流与重绘》
最后,再补充一个知识点:Load 和 DOMContentLoaded 区别是什么?
- Load 事件触发代表页面中的 DOM,CSS,JS,图片已经全部加载完毕。
- DOMContentLoaded 事件触发代表初始的 HTML 被完全加载和解析,不需要等待 CSS,JS,图片加载
【前端性能优化】浏览器渲染原理与性能优化相关推荐
- 浏览器渲染原理以及性能优化
浏览器渲染原理以及性能优化 浏览器渲染原理 进程与线程 Request请求阶段 Response响应阶段 浏览器渲染网页注意事项 浏览器渲染网页阻塞顺序 DOM的重绘和回流 Repaint & ...
- 前端学习(一) 浏览器渲染原理
前言 浏览器的内核是指支持浏览器运行的最核心的程序,分为两个部分,一是渲染引擎,另一个是JS引擎,渲染引擎在不同的浏览器中也不是都相同的.目前市面上常见的浏览器内核可以分为4种: Trident( I ...
- 前端性能优化之浏览器渲染原理和关键渲染路径、复合线程、图层及优化、JS 开销及优化和 HTML 和 CSS 优化
一.浏览器渲染原理和关键渲染路径 浏览器构建渲染树,DOM 树和 CSSDOM 树合成为 Render Tree 渲染树. 浏览器的渲染流程,如下所示: JavaScript -> Style ...
- 如何从8 道面试题中,看出浏览器渲染过程与性能优化
前言 移动互联网时代,用户对于网页的打开速度要求越来越高.百度用户体验部研究表明,页面放弃率和页面的打开时间关系如下图 所示. 根据百度用户体验部的研究结果来看,普通用户期望且能够接受的页面加载时间在 ...
- 前端浏览器渲染原理及优化
文章目录 一.浏览器组成 1. 对浏览器内核的理解 2. 浏览器的主要组成部分 二.浏览器渲染原理 1.浏览器的渲染过程 步骤一: 步骤二: 步骤三: 步骤四: 步骤五: 2.相关概念 ①重排(更新元 ...
- 浏览器渲染机制面试_前端面试大全:浏览器渲染原理-文件无法渲染
在这一篇文章中,我们将一起学习浏览器渲染原理这部分的知识.你可能会有疑问,我又不是做浏览器研发的,为什么要来学习这个?其实我们学习浏览器渲染原理更多的是为了解决性能的问题,如果你不了解这部分的知识,你 ...
- 【浏览器渲染原理】步骤及优化
[浏览器渲染原理]步骤及优化 文章目录 [浏览器渲染原理]步骤及优化 一.对浏览器内核的理解 二.浏览器的主要组成部分 三.浏览器的渲染过程 四.浏览器渲染优化 ① 针对JavaScript: ② 针 ...
- 浏览器渲染原理_web前端培训课程
在我们正式开始学习之前,首先让我们了解一些浏览器的一些知识点,然后再对浏览器渲染原理深刻的理解一下,这次学习是针对Chrome浏览器的渲染机制. 最新的Chrome浏览器包括:1个浏览器主进程,一个G ...
- 浏览器渲染机制面试_浏览器渲染原理
本文目录结构 问题 浏览器渲染原理 渲染过程 1. 浏览器接收到 HTML ⽂件并转换为 DOM 树 当我们打开⼀个⽹⻚时,浏览器都会去请求对应的 HTML ⽂件.虽然平时我 们写代码时都会分为 JS ...
最新文章
- 服务器日志显示乱码,CentosOS 6.5 服务器 控制台输出中文乱码,日志打印中文也乱码...
- 程序 算法与数据结构
- MySQL和java连连看_用 JAVA 开发游戏连连看(之一)动手前的准备
- 如何用Word 2007写Blog
- 单片机小白学步系列(十六) 单片机/计算机系统概述:模块化思想
- DistBelief 框架下的并行随机梯度下降法 - Downpour SGD
- CSS: SASS用法指南 (附视频)
- Java基础学习笔记(五)Iterator
- 代码织入 android,这可能是Android最傻瓜式的AOP框架
- 代码回滚:Reset、Checkout、Revert的选择(转)
- windows安装docker环境并配置镜像
- 【博客559】更出色的网络监控采集方案---Telemetry(遥测技术)
- JavaWeb专栏之(三):Eclipse创建JavaWeb项目
- Python入门学习小记:100以内素数/质数之和
- input的各种事件
- java.io.IOException Failed to replace a bad datanode
- jquery实现轮播图,可点击左右切换
- AU插件安装 - FabFilter、RX
- 【教学类-11-01】20221103《扑克牌4*4》(大班个别化活动-益智区》)
- 【星球问答精选】我想打造个性化的高效工作流,不会编程怎么办?