浏览器渲染原理 - 输入url 回车后发生了什么

目录

  • 渲染时间点
  • 渲染流水线
    • 1,解析(parse)HTML
      • 1.1,DOM树
      • 1.2,CSSOM树
      • 1.3,解析时遇到 css 是怎么做的
      • 1.4,解析时遇到 js 是怎么做的
    • 2,样式计算 Recalculate style
    • 3,布局 layout
    • 4,分层 layer
    • 5,绘制 paint
    • 6,分块 tiling
    • 7,光栅化 raster
    • 8,画 draw
  • 常见面试题
    • 什么是 reflow
    • 什么是 repaint
    • 为什么 transform 效率高

在上一篇文章中,介绍了 浏览器的事件循环,其中提到了浏览器的进程模型。那浏览器是如何渲染页面的呢?

渲染时间点

浏览器会通过网络进程中的线程来通信,获取到 html 数据后生成渲染任务,发送给消息队列。

渲染主线程会执行渲染任务。整个渲染流程:把 html 字符串解析为像素点信息,再交给 GPU来渲染后在页面中展示。

在这里插入图片描述

渲染流水线

在这里插入图片描述

每个阶段都有明确的输入输出,上个阶段的输出会成为下个阶段的输入。形成一套完整的流水线。

1,解析(parse)HTML

会将 html 字符串解析为 2个树。因为字符串不好操作,对象更容易处理。

1.1,DOM树

也就是 document 对象。可以在控制台通过console.dir(document) 展示对象结构。
在这里插入图片描述

1.2,CSSOM树

包括:

  • <style> 内部样式
  • <link> 外部样式
  • style="" 内联样式
  • 浏览器默认样式表

在这里插入图片描述

注意,这里的 CSSOM树 ≠ document.styleSheets。因为 document.styleSheets 只包括内部样式外部样式,每写一个 <style><link> 就会多一个 CSSStyleSheet 样式表:

在这里插入图片描述

举例说明:

<html><head><style>body h1 {color: red;font-size: 3em;}div p {margin: 1em;color: blue;}</style></head><body><h1>下雪天的夏风</h1><div><p>求关注</p></div></body>
</html>

在这里插入图片描述

可以看到:

  • CSSStyleSheet 样式表
    • CSSStyleRule 规则对象
      • selectorText 选择器
      • style 样式(键值对)

另外,CSSStyleSheet 样式表是可以直接通过 js 操作的。

举例:通过 js 给页面所有 div 添加 border

document.styleSheets[0].addRule('div', 'border: 1px solid !important')

这样添加样式的方式,一般框架用的多。最终样式不会在内联样式中展现。

1.3,解析时遇到 css 是怎么做的

渲染主线程遇到 css 时,会启动一个预解析线程,让它来率先下载和解析 css。渲染主线程继续解析 html。

预解析线程会快速浏览,如果遇到外部样式link ,会通知网络线程来下载 css,下载完成后进行“解析”完成后交给渲染主线程。

并不是真正的解析,只是做一些前期工作,最终生成 CSSOM 树还是由渲染主线程来完成。

所以,css 代码不会阻塞解析 HTML。

在这里插入图片描述

1.4,解析时遇到 js 是怎么做的

没有生成所谓的 js 树,是因为 js 只需要执行一遍即可。DOM树和CSSOM树作为解析 HTML 的输出,后续还会有其他的操作。

渲染主线程遇到内部 js 时,直接启动 V8 引擎执行即可;遇到外部 js 时,会启动一个预解析线程,让它来下载 js,渲染主线程暂停

预解析线程会通知网络线程来下载 js,下载完成后再交给渲染主线程来执行。执行完继续解析 HTML。

这样做的原因:DOM 树是边解析边生成的,而 js 代码可能会修改之前已解析好的内容。

所以,js 代码会阻塞解析 HTML。

在这里插入图片描述

2,样式计算 Recalculate style

遍历DOM树,计算每个节点的最终样式 Computed Style。

这一过程,许多预设值会变成绝对值,比如 red 变为 rgb(255,0,0);相对单位变为绝对单位,比如rem 变为 px

最终会得到1个带有最终样式的 DOM 树。
在这里插入图片描述

可以在浏览器的 computed 窗口中,或使用 getComputedStyle() 查看某个元素的最终样式。

3,布局 layout

遍历DOM树的每个节点,根据 css 属性值计算每个节点的几何信息(尺寸,相对包含块的位置),生成一个 layout 树。

注意到 DOM 树和 layout 树不一定一一对应。
在这里插入图片描述
举例1:diaplay:none 的元素不会出现在 layout 树中。

问题来了,为什么<head> <link> 等元素默认是隐藏的?因为在浏览器默认样式表中,它们 diaplay:none
在这里插入图片描述
举例2:伪元素的 content 内容在 DOM 树中没有,在 layout 树中有。

在这里插入图片描述
举例3:内容必须在行盒中,行盒和块盒不能相邻。所以在 layout 树中会有匿名块盒

解释:“行级元素”,“块级元素”这些元素指的是 html。但元素的类型是 css 属性决定的。所以称为行盒或块盒。

在这里插入图片描述

4,分层 layer

现在 layout 布局树中每个节点的几何信息,尺寸位置等都明确了。渲染主线程会使用一套策略对整个布局树分层。

目的是提升效率,这样可以让之后页面的修改更新不会影响到其他层。类似 PS 中的图层,修改某一个图层不会影响到其他图层。

可以在浏览器控制台的 Layers 面板查看当前网页的分层信息。
也不会分太多的层,因为会比较占内存。滚动条是单独一层。

在这里插入图片描述

另外,和堆叠上下文有关的 css 属性(transform,opacity)会影响分层的决策。其中 will-change 属性能更大程度的影响分层角色,可能会将设置该属性的元素单独分一层。

因为这个属性会告诉浏览器,我可能会经常变化,浏览器最好掂量下。

5,绘制 paint

分层后,会对每层都生成绘制指令,类似于 canvas 中的 API 一样。其实canvas 用的就是浏览器内核的绘制功能。

指令举例:“笔”移动到 xx 坐标位置,画 100*100 的矩形,并用红色填充等等。

在这里插入图片描述

以上。渲染主线程的工作结束,剩下的步骤交给其他线程来完成。

在这里插入图片描述

6,分块 tiling

将每层都分为多个小的区域,浏览器视窗区域的优先级最高,靠近视窗区域的优先级次之。
在这里插入图片描述

分块逻辑:渲染主线程每个图层的绘制信息交给合成线程,合成线程又会启动多个分块线程来对每个图层进行分块。

合成线程也属于渲染线程

在这里插入图片描述

7,光栅化 raster

将每个块变成位图,位图就是每个像素点的信息。优先处理靠近视窗的块。

位图就是内存中的二位数组,其中记录了每个像素点的信息。

在这里插入图片描述

此过程会用到GPU来加速,用到显卡。
在这里插入图片描述

8,画 draw

合成线程现在拿到了所有的信息,在画之前还需要确认【指引信息 quad】,也就是位图相对的屏幕在哪里。

注意,之前布局树中的信息是相对于整个页面的。现在需要知道每个块相对于屏幕的位置信息。

步骤:合成线程将指引信息 --> GPU 进程 --> 硬件显卡,由显卡来呈现最终的像素信息。

GPU 做中转的原因是:GPU 是浏览器的进程。合成线程属于渲染进程,它是在沙盒中的,与硬件系统做隔离,提升安全性。所以渲染进程是没有调度系统硬件能力的。

在这里插入图片描述
而 css 中的 transform 属性就是在这一步完成的。这就是 transform 效率高的原因,直接跳过之前所有的步骤。

常见面试题

什么是 reflow

【recalculate layoutBlockFlow 重排】它的本质是重新计算 layout 树

当做了会影响 layout 树的操作后,比如修改几何尺寸相关的信息时,会引起重新计算 layout 树。

在这里插入图片描述

并且,为了避免连续多次的操作导致 layout 树反复计算,浏览器会合并这些操作,当 js 代码完成后统一计算。所以这一步骤是异步的。

同样因为这个原因,当 js 获取布局属性时,可能无法获取到最新的布局信息。

浏览器会在反复权衡下,最终决定获取属性时立即 reflow。

什么是 repaint

它的本质是重新根据分层信息计算了绘制指令

当改变了可见样式,比如颜色等和几何尺寸无关的属性时,就需要重新计算,会从【绘制】这一步骤开始重新执行。

而因为几何尺寸也属于可见样式,所以 reflow 一定会引起 repaint。

在这里插入图片描述

为什么 transform 效率高

因为 transform 既不会影响布局,也不会影响绘制,它只会影响渲染的最后一步【画】。而【画】是在合成线程中,不会影响到渲染主线程。同样无论渲染主线程多忙,也不会影响到 transform。

验证代码如下,当渲染主线程卡死时,transform 不受影响。

<!DOCTYPE html>
<html lang="en"><head><style>.common {width: 50px;height: 50px;background-color: salmon;border-radius: 50%;margin: 10px;}.ball1 {animation: move1 1s alternate infinite;}.ball2 {position: relative;left: 0;animation: move2 1s alternate infinite;}@keyframes move1 {to {transform: translate(100px);}}@keyframes move2 {to {left: 100px;}}</style></head><body><button id="btn">死循环3s</button><div class="common ball1"></div><div class="common ball2"></div><script>btn.addEventListener("click", function () {delay(3000);});function delay(duration) {var start = Date.now();while (Date.now() - start < duration) {}}</script></body>
</html>

效果:
在这里插入图片描述

滚动也是一样的逻辑,如果 js 有一段上面的死循环,并不会影响到滚动。因为只有视窗内元素的位置变了,直接执行【画 draw】这一步骤。

以上。


参考:渡一教育。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/43410.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Spring Cloud 系列之OpenFeign:(7)链路追踪zipkin

传送门 Spring Cloud Alibaba系列之nacos&#xff1a;(1)安装 Spring Cloud Alibaba系列之nacos&#xff1a;(2)单机模式支持mysql Spring Cloud Alibaba系列之nacos&#xff1a;(3)服务注册发现 Spring Cloud 系列之OpenFeign&#xff1a;(4)集成OpenFeign Spring Cloud …

PHP酒店点菜管理系统mysql数据库web结构apache计算机软件工程网页wamp

一、源码特点 PHP 酒店点菜管理系统是一套完善的web设计系统&#xff0c;对理解php编程开发语言有帮助&#xff0c;系统具有完整的源代码和数据库&#xff0c;系统主要采用B/S模式开发。 代码下载 https://download.csdn.net/download/qq_41221322/88232051 论文 https://…

前端技术Vue学习笔记--005

Vue学习笔记 一、非父子通信-event bus 事件总线 作用&#xff1a;非父子组件之间&#xff0c;进行简易消息传递。&#xff08;复杂场景用----Vuex&#xff09; 使用步骤&#xff1a; 创建一个都能访问的事件总线 &#xff08;空Vue实例&#xff09;-----utils/EventBus.js /…

两个数组的交集-C语言/Java

描述 给定两个数组 nums1 和 nums2 &#xff0c;返回 它们的交集 。输出结果中的每个元素一定是 唯一 的。我们可以 不考虑输出结果的顺序。&#xff08;1 < nums1.length, nums2.length < 1000&#xff0c;0 < nums1[i], nums2[i] < 1000&#xff09; 示例1 输入…

一键批量修改文件夹名称,中文瞬间变日语,轻松搞定重命名

大家好&#xff01;现在为了更好地适应全球化发展&#xff0c;许多人都有了海外交流、旅行、学习的需求。但是难免遇到一个问题&#xff1a;在电脑中的中文文件夹名称如何快速翻译成日语&#xff1f; 首先&#xff0c;第一步&#xff0c;我们需要打开文件批量改名&#xff0c;…

AWS EKS 集群自动扩容 Cluster Autoscaler

文章目录 一&#xff0c;需求工作需求说明 二&#xff0c;部署精简命令执行1&#xff0c;要求2&#xff0c;查看EC2 Auto Scaling groups Tag3&#xff0c;创建Serviceaccount需要的Policy&#xff0c;Role4&#xff0c;部署Cluster Autoscaler5&#xff0c;验证6&#xff0c;常…

zotero在不同系统的安装(win/linux)

1 window系统安装 zotero 官网&#xff1a; https://www.zotero.org/ 官方文档 &#xff1a;https://www.zotero.org/support/ (官方)推荐常用的插件: https://www.zotero.org/support/plugins 入门视频推荐&#xff1a; Zotero 文献管理与知识整理最佳实践 点击 exe文件自…

【环境配置】Windows 10 安装 PyTorch 开发环境,以及验证 YOLOv8

Windows 10 安装 PyTorch 开发环境&#xff0c;以及验证 YOLOv8 最近搞了一台Windows机器&#xff0c;准备在上面安装深度学习的开发环境&#xff0c;并搭建部署YOLOv8做训练和测试使用&#xff1b; 环境&#xff1a; OS&#xff1a; Windows 10 显卡&#xff1a; RTX 3090 安…

DeepSort:基于检测的目标跟踪的经典

本文来自公众号“AI大道理” DeepSORT在SORT的基础上引入了深度学习的特征表示和更强大的目标关联方式&#xff0c;有效地减少了身份切换的数量&#xff0c;缓解了重识别问题。 ​ 1、DeepSORT简介 DeepSORT的主要思想是将目标检测和目标跟踪两个任务相结合。 首先使用目标检…

硬件产品经理:从入门到精通(新书发布)

目录 简介 新书 框架内容 相关课程 简介 在完成多款硬件产品从设计到推向市场的过程后。 笔者于2020年开始在产品领域平台输出硬件相关的内容。 在这个过程中经常会收到很多读者的留言&#xff0c;希望能推荐一些硬件相关的书籍或资料。 其实&#xff0c;笔者刚开始做硬…

10. 实现业务功能--退出登录

目录 1. 实现 Controller 2. 单体测试 3. 实现前端界面 退出的具体实现逻辑如下&#xff1a; 1. 用户访问退出接口 2. 服务器注销 Session( 在 Controller 中可以直接进行处理 &#xff09; 3. 返回成功或失败 4. 如果返回成功浏览器跳转到相应页面 5. 结束 一般来说&#…

使用VS2015打开.pro文件后,编译报错

编译报错内容&#xff1a; MSB8036 找不到 Windows SDK 版本10.0.18362.0。请安装所需的版本的 Windows SDK 或者在项目属性页中或通过右键单击解决方案并选择“重定解决方案目标”来更改 SD 方法&#xff1a; 1.右键点击 Solution上&#xff0c;在弹出的框中点击“Retarget…

调整数组使奇数全部都位于偶数前面

题目内容&#xff1a; 输入一个整数数组&#xff0c;实现一个函数&#xff0c; 来调整该数组中数字的顺序使得数组中所有的奇数位于数组的前半部分&#xff0c; 所有偶数位于数组的后半部分。 题目思路&#xff1a; 将奇数部分放在前半部分&#xff0c;偶数部分放在后半部分&am…

学习笔记230804---restful风格的接口,delete的传参方式问题

如果后端提供的删除接口是restful风格&#xff0c;那么使用地址栏拼接的方式发送请求&#xff0c;数据放在主体中&#xff0c;后端接受不到&#xff0c;当然也还有一种可能&#xff0c;后端在这个接口的接参设置上是req.query接参。 问题描述 今天遇到的问题是&#xff0c;de…

新榜 | CityWalk本地生活商业价值洞察报告

如果说现在有人问&#xff0c;最新的网络热词是什么? “CityWalk”&#xff0c;这可能是大多数人的答案。 近段时间&#xff0c;“CityWalk”刷屏了各种社交媒体&#xff0c;给网友们带来了一场“城市漫步”之旅。 脱离群体狂欢&#xff0c;这个在社交媒体引发热议的词汇背后又…

首发 | FOSS分布式全闪对象存储系统白皮书

一、 产品概述 1. 当前存储的挑战 随着云计算、物联网、5G、大数据、人工智能等新技术的飞速发展&#xff0c;数据呈现爆发式增长&#xff0c;预计到2025年中国数据量将增长到48.6ZB&#xff0c;超过80%为非结构化数据。 同时&#xff0c;数字经济正在成为我国经济发展的新…

锐捷无线产品运维(Web登录、 命令行登录)

目录 登录AP产品 Console登录&#xff08;只可以现场登录&#xff09; Web/Telnet/SSH登录&#xff08;可以现场、远程登录&#xff09; 配置AP的管理地址 通过Web界面远程登录 通过Telnet、SSH等命令行的方式登录 登录AC产品 Console登录&#xff08;只可以现场登录&a…

[bug] 记录version `GLIBCXX_3.4.29‘ not found 解决方法

在使用mediapipe 这个库的时候&#xff0c;首次使用出现 GLIBCXX_3.4.29’ not found 错误&#xff0c; 看起来是安装mediapipe 的时候自动升级了 matplotlib 这个库&#xff0c;导致依赖的 libstd.so 版本不满足了&#xff0c;GLIBCXX_3.4.29 is an object from libstdc.so.…

【c语言】字符函数与字符串函数(上)

大家好呀&#xff0c;今天给大家分享一下字符函数和字符串函数&#xff0c;说起字符函数和字符串函数大家会想到哪些呢&#xff1f;&#xff1f;我想到的只有求字符串长度的strlen,拷贝字符串的strcpy,字符串比较相同的strcmp,今天&#xff0c;我要分享给大家的是我们一些其他的…