【从浏览器地址栏输入 url 到请求返回的过程】——6. 浏览器渲染页面(浏览器的渲染机制)

前言

相关问题​

  • 浏览器如何渲染页面
  • 有哪些提高浏览器渲染性能的方法

一、浏览器渲染的基本流程?

不同的浏览器内核不同,所以渲染过程不太一样。虽然主流浏览器渲染过程叫法有区别,但是主要流程还是相同的。下面就WebKit主流程:
在这里插入图片描述

1.1 HTML解析出DOM Tree

HTML Parser的任务是将HTML标记解析成DOM Tree,举个🌰,下面这段html代码

<html>
	<head>
		<title>web page parsing</title>
	</head>
	<body>
		<div>
			<h1>web page parsing</h1>
			<p>this is an example</p>
		</div>
	</body>
</html>

经过解析之后的DOM Tree大概是:
在这里插入图片描述

1.2 CSS解析出Style Rules

CSS ParserCSS解析成Style RulesStyle Rules也叫CSSOM(CSS Object Model)。StyleRules也是一个树形结构,根据CSS文件整理出来的类似DOM Tree的树形结构。

浏览器解析文档,当遇到<script>标签的时候,会立即解析脚本,停止解析文档(因为JS可能会改动DOM和CSS,所以继续解析会造成浪费)。 如果脚本是外部的,会等待脚本下载完毕,再继续解析文档。现在可以在script标签上增加属性defer或者async。 脚本解析会将脚本中改变DOM和CSS的地方分别解析出来,追加到DOM TreeStyle Rules上。

1.3 Render Tree

Render Tree是和 DOM 元素相对应的,但并非一一对应。Render Tree实际上就是一个计算好样式与HTML对应的(包括哪些显示,那些不显示)的Tree

1.4 Layout布局

创建渲染树后,下一步就是布局(Layout),或者叫回流(reflow,relayout),这个过程就是通过渲染树中渲染对象的信息,计算出每一个渲染对象的位置和尺寸,将其安置在浏览器窗口的正确位置,而有些时候我们会在文档布局完成后对DOM进行修改,这时候可能需要重新进行布局,也可称其为回流,本质上还是一个布局的过程,每一个渲染对象都有一个布局或者回流方法,实现其布局或回流。

对渲染树的布局可以分为全局和局部的,全局即对整个渲染树进行重新布局,如当我们改变了窗口尺寸或方向或者是修改了根元素的尺寸或者字体大小等;而局部布局可以是对渲染树的某部分或某一个渲染对象进行重新布局。

布局是一个从上到下,从外到内进行的递归过程,从根渲染对象,即对应着HTML文档根元素,然后下一级渲染对象,如对应着元素,如此层层递归,依次计算每一个渲染对象的几何信息(位置和尺寸)

1.5 painting(绘制)

在绘制阶段,系统会遍历Render Tree,并调用呈现器的paint方法,将呈现器的内容显示在屏幕上。
在绘制阶段涉及到两个考点重绘和回流(重排)

重绘:当页面中元素样式的改变并不影响它在文档流中的位置时(例如:color、background-color、visibility等),浏览器会将新样式赋予给元素并重新绘制它,这个过程称为重绘

回流:无论通过什么方式影响了元素的几何信息(元素在视口内的位置和尺寸大小),浏览器需要重新计算元素在视口内的几何属性,这个过程叫做回流。

二、浏览器渲染性能的优化​

2.1减少渲染中的重排重绘

回流的开销是比较大的,那么怎么减少回流呢?
什么操作会造成回流:

  1. 页面首次渲染
  2. 浏览器窗口大小发生改变
  3. 元素尺寸或位置发生改变
  4. 元素内容变化(文字数量或图片大小等等)
  5. 元素字体大小变化
    6 .添加或者删除可见的DOM元素
    7 .激活CSS伪类(例如::hover)
  6. 查询某些属性或调用某些方法
    clientWidth、clientHeight、clientTop、clientLeft
    offsetWidth、offsetHeight、offsetTop、offsetLeft
    scrollWidth、scrollHeight、scrollTop、scrollLeft
    scrollIntoView()、scrollIntoViewIffNeeded()
    getComputedStyle()【IE】
    scrollTo()

如何减少回流:
css

  1. 避免使用table布局;
  2. 尽可能在DOM树的最末端改变class;
  3. 将动画效果应用到position属性为absolute或fixed的元素上:使它脱离文档流,否则会引起父元素及后续元素频繁回流
  4. 避免使用CSS表达式(例如:calc())。
  5. 开启 **GPU 加速,**利用 css 属性 transform 等,比如改变元素位置,我们使用translate 会比使用绝对定位改变其 left 、top 等来的高效,因为它不会触发重排或重绘,transform 使浏览器为元素创建⼀个GPU 图层,这使得动画元素在一个独立的层中进行渲染。当元素的内容没有发生改变,就没有必要进行重绘。

JS

  1. 避免频繁操作样式,最好一次性重写style属性,或者将样式列表定义为class并一次性更改class属性。
  2. 避免频繁操作DOM,创建一个documentFragment,在它上面应用所有DOM操作,最后再把它添加到文档中。
  3. 也可以先为元素设置display: none,操作结束后再把它显示出来。因为在display属性为none的元素上进行的DOM操作不会引发回流和重绘。
  4. 避免频繁读取会引发回流/重绘的属性,如果确实需要多次使用,就用一个变量缓存起来。

2.2 优化影响渲染的资源​

在浏览器解析 HTML的过程中,CSS 和 JS 都有可能对页面的渲染造成影响。优化方法包括以下几点:

  • 关键 CSS 资源放在头部加载。
  • JS 通常放在页面底部。
  • 为 JS 添加 async 和 defer 属性。
  • body 中尽量不要出现 CSS 和 JS。
  • 为 img 指定宽高,避免图像加载完成后触发重排。
  • 避免使用 table, iframe 等慢元素。原因是 table 会等到它的 dom 树全部生成后再一次性插入页面中;iframe 内资源的下载过程会阻塞父页面静态资源的下载及 css, dom树的解析
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值