面试常考题: 输入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,它们提供了有关元素滚动状态的信息,即元素内容的总大小和当前滚动位置

相关推荐
Qrun14 分钟前
Windows11安装nvm管理node多版本
前端·vscode·react.js·ajax·npm·html5
中国lanwp15 分钟前
全局 npm config 与多环境配置
前端·npm·node.js
JELEE.1 小时前
Django登录注册完整代码(图片、邮箱验证、加密)
前端·javascript·后端·python·django·bootstrap·jquery
TeleostNaCl3 小时前
解决 Chrome 无法访问网页但无痕模式下可以访问该网页 的问题
前端·网络·chrome·windows·经验分享
前端大卫5 小时前
为什么 React 中的 key 不能用索引?
前端
你的人类朋友5 小时前
【Node】手动归还主线程控制权:解决 Node.js 阻塞的一个思路
前端·后端·node.js
小李小李不讲道理7 小时前
「Ant Design 组件库探索」五:Tabs组件
前端·react.js·ant design
毕设十刻7 小时前
基于Vue的学分预警系统98k51(程序 + 源码 + 数据库 + 调试部署 + 开发环境配置),配套论文文档字数达万字以上,文末可获取,系统界面展示置于文末
前端·数据库·vue.js
mapbar_front8 小时前
在职场生存中如何做个不好惹的人
前端
牧杉-惊蛰8 小时前
纯flex布局来写瀑布流
前端·javascript·css