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

相关推荐
everyStudy43 分钟前
前端五种排序
前端·算法·排序算法
甜兒.2 小时前
鸿蒙小技巧
前端·华为·typescript·harmonyos
她似晚风般温柔7894 小时前
Uniapp + Vue3 + Vite +Uview + Pinia 分商家实现购物车功能(最新附源码保姆级)
开发语言·javascript·uni-app
王中阳Go5 小时前
字节跳动的微服务独家面经
微服务·面试·golang
Jiaberrr5 小时前
前端实战:使用JS和Canvas实现运算图形验证码(uniapp、微信小程序同样可用)
前端·javascript·vue.js·微信小程序·uni-app
everyStudy6 小时前
JS中判断字符串中是否包含指定字符
开发语言·前端·javascript
城南云小白6 小时前
web基础+http协议+httpd详细配置
前端·网络协议·http
前端小趴菜、6 小时前
Web Worker 简单使用
前端
web_learning_3216 小时前
信息收集常用指令
前端·搜索引擎
Ylucius6 小时前
动态语言? 静态语言? ------区别何在?java,js,c,c++,python分给是静态or动态语言?
java·c语言·javascript·c++·python·学习