面试常考题: 输入url到页面渲染发生了什么(后半段)

前言

当我们在面试时,面试官问我们输入url到页面渲染时发生了一些什么过程,许多小伙伴们可能就觉得这不就是读取html,css,js吗,但其实,这其中发生许多事,也有很多考点。这个问题在我们面试过程中十分容易被问到,小伙伴们跟着我这篇文章一起来看看吧。

当我们在浏览器中输入一串url,按下回车之后,最终一套完整的页面就呈现在我们的眼前,包括 DNS 解析、建立 TCP 连接、发送 HTTP 请求、接收响应、解析 HTML、构建 DOM 树、执行 JavaScript、渲染页面等。在这篇文章中我们就来说说浏览器加载到了资源后干的事。

浏览器加载到了资源

  1. 解析 HTML,生成 DOM 树: 浏览器首先会解析 HTML 代码,将其转换为 DOM(文档对象模型)树。DOM 树是由 HTML 元素节点、文本节点和属性节点等组成的树状结构,表示了 HTML 文档的层次结构和元素之间的关系。
  2. 解析 CSS,生成 CSSOM 树: 浏览器接着会解析 CSS 代码,将其转换为 CSSOM(CSS 对象模型)树。CSSOM 树是由 CSS 规则、选择器和属性等组成的树状结构,表示了 CSS 样式表的层次结构和样式规则的应用关系。
  3. 结合 DOM 树和 CSSOM 树,生成 Render Tree: 浏览器会将 DOM 树和 CSSOM 树结合起来,生成渲染树(Render Tree)。渲染树只包含需要显示的可见元素,不包含隐藏的或不可见的元素。渲染树中的每个节点称为渲染对象,它包含了元素的样式和布局信息。
  4. 计算布局,得到每个结点的几何信息: 浏览器根据渲染树中每个渲染对象的样式信息和布局规则,计算出每个节点的几何信息,包括位置、尺寸、边距等。这个过程称为布局或回流。
  5. 绘制页面,GPU 绘制: 最后,浏览器使用计算出的几何信息,将渲染树中的每个节点绘制到屏幕上。浏览器通过 GPU(图形处理单元)来加速绘制过程,将渲染对象转换为图形和像素,最终呈现为可视化的页面。

在这个过程中,会发生回流重绘,什么是回流和重绘呢?

什么是回流

  • 浏览器计算页面布局的过程叫做回流
  • 当一个容器的几何属性发生变更时, 页面会发生回流
  1. 改变窗口的尺寸
  2. 改变元素的尺寸
  3. 增加或删除可见的元素
  4. 页面初次渲染

什么是重绘?

  • 将已经计算好布局的容器在屏幕上展现出来
  • 元素的非几何属性变化时, 会发生重绘
  1. 修改背景颜色
  2. 修改背景图片
  3. 边框颜色
  4. 字体颜色
  • 回流一定重绘, 重绘不一定回流

我们了解了回流和重绘的机制,我们下面来看一段代码,看看发生了多少次回流:

js 复制代码
<div id="app">hello</div>

<script>
    let app = document.getElementById('app')
    app.style.position = 'relative';

    app.style.width =  '100px'
    app.style.height = '200px'
    app.style.left= '20px'
    app.style.right = '20px'
</script>

小伙伴们是不是跟我当时学一样,脱口而出发生了四次回流,但答案显然是不是的。如果是在老版本的浏览器中,那确实是发生了四次回流,而现如今我们常用的浏览器,都是有一套自己的优化策略的,因为回流是很造成资源消耗的,比如上述代码,这里只发生了一次回流。我们上面的四次操作都修改了容器的几何属性,影响到了元素的布局,浏览器在计算新的布局时会将他们合并在一起,一次性考虑这些属性的变化,所以这里这发生了一次回流

js 复制代码
app.style.width =  '100px'
console.log(app.style.width);

app.style.height = '200px'
console.log(app.style.height);

app.style.left= '10px'
console.log(app.style.left);

app.style.right = '10px'
console.log(app.style.right);

看看这段代码,小伙伴们是不是就会说也只发生了一次回流,跟我一开始接触时一模一样,但是这里发生了四次回流,这就跟我们刚刚所说的浏览器的优化策略有关了。优化策略的底层原理其实是浏览器维护了一个渲染队列,当我们用代码变更元素样式可能导致回流时,渲染队列会先保留这个操作,浏览器会继续执行下面的代码,如果还有相同的行为,会继续进入渲染队列,直到没有元素样式被修改,渲染队列会批量的执行这些操作,所以只发生一次回流。

但有一些js的代码被浏览器碰到了会强制执行渲染队列中的内容,就比如上述代码console.log()括号里面的代码,他们会强制执行渲染队列,所以这里就回流了四次。那么有哪些代码会强制执行渲染队列呢:

  • 盒模型属性(Box Model Properties): 包括offsetWidthoffsetHeightclientWidthclientHeight,它们提供了有关元素盒模型的信息,即元素在页面中所占据的空间大小、可见内容的大小等。

  • 位置属性(Position Properties): 包括offsetTopoffsetLeftclientTopclientLeft,它们提供了有关元素位置的信息,即元素相对于其父元素或视口的偏移量、边框的大小等。

  • 滚动属性(Scroll Properties): 包括scrollHeightscrollWidthscrollTopscrollLeft,它们提供了有关元素滚动状态的信息,即元素内容的总大小和当前滚动位置

相关推荐
腾讯TNTWeb前端团队13 分钟前
helux v5 发布了,像pinia一样优雅地管理你的react状态吧
前端·javascript·react.js
uhakadotcom3 小时前
视频直播与视频点播:基础知识与应用场景
后端·面试·架构
范文杰4 小时前
AI 时代如何更高效开发前端组件?21st.dev 给了一种答案
前端·ai编程
拉不动的猪4 小时前
刷刷题50(常见的js数据通信与渲染问题)
前端·javascript·面试
拉不动的猪4 小时前
JS多线程Webworks中的几种实战场景演示
前端·javascript·面试
FreeCultureBoy5 小时前
macOS 命令行 原生挂载 webdav 方法
前端
uhakadotcom5 小时前
快速开始使用 n8n
后端·面试·github
uhakadotcom5 小时前
Astro 框架:快速构建内容驱动型网站的利器
前端·javascript·面试
uhakadotcom5 小时前
了解Nest.js和Next.js:如何选择合适的框架
前端·javascript·面试
uhakadotcom5 小时前
React与Next.js:基础知识及应用场景
前端·面试·github