HTML界面渲染的原理,浏览器渲染页面的原理及流程

浏览器将域名通过网络通信从服务器拿到html文件后,如何渲染页面呢?

# 加载HTML页面步骤

f52f26348e30d26a86a11d5d4365abfc.png

WARNING

1.当浏览器遇到link/script/img等请求后,都会开辟全新的线程去加载资源文件。开辟TASK QUEUE(任务队列)的线程,里面有各种任务,在等待着解析,

当主线程生成DOM树后,主线程会从TASK QUEUE(任务队列)的线程里拿到解析生成CSSOM的任务,一起构建渲染树(Render Tree)。

2.如果TASK QUEUE(任务队列)中没有解析完成的任务,主线程就一直等待,如果有处理好的,就渲染,形成事件循环。

# 浏览器如何渲染网页1.根据html文件构建DOM树和CSSOM(CSS Object Model)树。构建DOM树期间,如果遇到JS,阻塞DOM树及CSSOM树的构建,优先加载JS文件,加载完毕,再继续构建DOM树及CSSOM树。

2.构建渲染树(Render Tree)。

3.页面的重绘(repaint)与回流(reflow,也有称重排)。页面渲染完成后,若JS操作了DOM节点,根据JS对DOM操作动作的大小,浏览器对页面进行重绘或是重排。

37e8132df3b98be995da42c7a9fea16d.png

TIP若在构建DOM树的过程中,当 HTML 解析器遇到一个 script 标记时,即遇到了js,将立即阻塞DOM树的构建,将控制权移交给 JavaScript 引擎,等到 JavaScript 引擎运行完毕,浏览器才会从中断的地方恢复DOM树的构建。

其根本原因在于,JS会对DOM节点进行操作,浏览器无法预测未来的DOM节点的具体内容,为了防止无效操作,节省资源,只能阻塞DOM树的构建。譬如,若不阻塞DOM树的构建,若JS删除了某个DOM节点A,那么浏览器为构建此节点A花费的资源就是无效的。

若在HTML头部加载JS文件,由于JS阻塞,会推迟页面的首绘。为了加快页面渲染,一般将JS文件放到HTML底部进行加载,或是对JS文件执行async或defer加载。

# 回流和重绘(reflow和repaint)

我们都知道HTML默认是流式布局的,但CSS和JS会打破这种布局,改变DOM的外观样式以及大小和位置。因此我们就需要知道两个概念:replaint和reflow。

# reflow(回流,也称重排)

当浏览器发现布局发生了变化(渲染树节点发生改变),影响了节点的几何属性(如宽、高、内边距、外边距、或是float、position、display:none;等等),导致节点位置发生变化,此时触发浏览器回流(reflow),需要重新生成渲染树,大家称这个回退的过程叫reflow。reflow会从html这个root frame开始递归往下,依次计算所有的结点几何尺寸和位置,以确认是渲染树的一部分发生变化还是整个渲染树。reflow几乎是无法避免的,因为只要用户进行交互操作,就势必会发生页面的一部分的重新渲染,且通常我们也无法预估浏览器到底会reflow哪一部分的代码,因为他们会相互影响。

WARNING

回流必将引起重绘,而重绘不一定会引起回流。

# 何时会引起回流?

当页面布局和几何属性改变时就需要回流。下述情况会发生浏览器回流:添加或者删除可见的DOM元素;

元素位置改变——display、float、position、overflow等等;

元素尺寸改变——边距、填充、边框、宽度和高度

内容改变——比如文本改变或者图片大小改变而引起的计算值宽度和高度改变;

页面渲染初始化;

浏览器窗口尺寸改变——resize事件发生时;

# 如何减少和避免回流?

TIP

Reflow 的成本比 Repaint 的成本高得多的多。一个节点的 Reflow 很有可能导致子节点,甚至父节点以及兄弟节点的 Reflow 。在一些高性能的电脑上也许还没什么,但是如果 Reflow 发生在手机上,那么这个过程是延慢加载和耗电的。直接改变className,如果动态改变样式,则使用cssText(考虑没有优化的浏览器);

让要操作的元素进行”离线处理”,处理完后一起更新;

a) 使用DocumentFragment进行缓存操作,引发一次回流和重绘;

b) 使用display:none技术,只引发两次回流和重绘;

c) 使用cloneNode(true or false) 和 replaceChild 技术,引发一次回流和重绘;

不要经常访问会引起浏览器flush队列的属性,如果你确实要访问,利用缓存;

让元素脱离动画流,减少回流的Render Tree的规模;

# repaint(重绘)

repaint则是当我们改变某个元素的背景色、文字颜色、边框颜色等等不影响它周围或内部布局的属性时,屏幕的一部分要重画,但是元素的几何尺寸和位置没有发生改变。

WARNING

需要注意的是,display:none会触发reflow,而visibility: hidden属性则并不算是不可见属性,它的语义是隐藏元素,但元素仍然占据着布局空间,它会被渲染成一个空框。所以visibility:hidden只会触发repaint,因为没有发生位置变化。

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值