DOM渲染与优化 - CSS、JS、DOM解析和渲染阻塞问题

news2024/9/20 18:36:35

文章目录

  • DOM渲染
    • 面试题
    • DOM的渲染过程
      • DOM渲染的时机与渲染进程的概述
      • 浏览器的渲染流程
        • 1. 解析HTML生成DOM树:遇到`<img>`标签加载图片
        • 2. 解析CSS生成CSSOM(CSS Object Model): 遇见背景图片链接不加载
        • 3. 将DOM树和CSSOM树合并生成渲染树:加载可视节点的背景图片
        • 4. 遍历渲染树开始布局,计算每个节点的位置大小等信息,输出包含DOM元素样式和位置的布局树。
        • 5. 绘制:开始渲染图片
        • 6. 合成: 已绘制的不同图层合并成在一起,输出到屏幕。
      • CSS、JS、DOM解析和渲染阻塞问题
        • JS加载阻塞DOM渲染问题,怎么解决? - 异步JS,JS三种异步加载的方式
          • script 标签中的 async 和 defer 属性
        • DOMContentLoaded和Load
    • DOM渲染优化

DOM渲染

面试题

  • js的DOM渲染是单线程的,那渲染的过程是什么样的?浏览器渲染页面的过程?
  • script标签,包含async属性的script标签,包含defer属性的script标签对文档渲染有啥影响?
  • css是否阻塞页面的解析和渲染?css渲染会不会阻塞dom渲染,会不会阻塞dom树建立
  • js会阻塞dom渲染吗,图片加载会阻塞dom渲染吗?
  • Dom渲染是在事件循环机制哪里实现的
  • JS加载阻塞DOM渲染问题,怎么解决
  • 生成DOM树和CSSOM树之后怎么生成渲染树

DOM的渲染过程

DOM渲染的时机与渲染进程的概述

DOM的渲染将HTML,CSS,JS等资源后,解析-构建树-绘制,最后呈现给用户能看到的界面的这个过程。
页面的渲染,JS的执行,事件的触发都是在渲染进程中进行的。

渲染进程包含多个线程

  • JS引擎线程:JavaScript引擎V8,负责处理JavaScript脚本程序。

为什么js是单线程的,假如JS是多线程的,假设现在有2条线程,一条在dom节点上添加节点,另一条删除这个节点。

  • GUI 渲染线程: 负责渲染浏览器界面,解析 HTML,CSS,构建render树,布局和绘制等。

GUI 渲染线程与 JS 引擎线程是互斥的,当 JS 引擎执行时 GUI 线程会被挂起,GUI 更新会被保存在一个队列中等到 JS 引擎空闲时立即被执行。

  • 事件触发线程: 控制事件循环,当对应的事件符合条件被触发时,该线程会将事件添加到待处理的事件队列中,等待JS引擎的处理。
  • 定时器触发线程:当使用setTimeout或者setInterval时,需要定时器线程计时。计时完成后会将特定的事件推进事件触发线程的任务队列中,等待进入主线程执行。
  • 异步http请求线程:XMLHttpRequest在连通后通过浏览器新起一个线程请求。检测到状态变化时,如果有设置回调函数,异步线程就产生状态变更事件,将这个回调再放入事件队列中,再由JS引擎执行。

渲染进程的创建时机
每次新开一个标签页,都会创建一个新的渲染进程。
但有例外,比如从A页面里面打开一个新的页面B页面,而A页面和B页面又属于同一站点的话,A和B就共用一个渲染进程。

浏览器的渲染流程

1. 解析HTML生成DOM树:遇到<img>标签加载图片

在这里插入图片描述DOM树的结构可以通过document打印查看,DOM结构,DOM和HTML内容几乎是一样的,但是和HTML不同的是,DOM是保存在内存中树状结构,可以通过JavaScript来查询或修改其内容。
这个过程中,display:none的元素、script标签、注释也都会添加到DOM树中。

2. 解析CSS生成CSSOM(CSS Object Model): 遇见背景图片链接不加载

3. 将DOM树和CSSOM树合并生成渲染树:加载可视节点的背景图片

渲染树中只包含渲染可见的节点
从DOM树的根节点开始向下遍历每个子节点,忽略所有不可见的节点,比如display:nonehead标签。在CSSOM中为每个可见的子节点找到对应的规则并应用。

4. 遍历渲染树开始布局,计算每个节点的位置大小等信息,输出包含DOM元素样式和位置的布局树。

第一次确定节点大小和位置称为布局,之后重新触发页面布局可以称为回流

5. 绘制:开始渲染图片

遍历布局树进行分层,生成分层树后,为每个图层分别进行绘制,在绘制中不同的图层渲染互不影响。

在这里插入图片描述
如果一个节点没有对应的层,那么这个节点就从属于父节点的图层。

渲染引擎为特点的节点创建新的层

  1. 拥有层叠上下文属性的元素会被提升为单独一层
    2. 在这里插入图片描述
    比如非static的positionz-indexfilteropacity

  2. 需要剪裁(clip)的地方也会被创建为图层。

6. 合成: 已绘制的不同图层合并成在一起,输出到屏幕。

这个阶段可以开启GPU加速
在这里插入图片描述
所以图片加载不会阻塞DOM渲染

CSS、JS、DOM解析和渲染阻塞问题

概念

  1. DOM解析 :浏览器向服务器请求到了 HTML 文档后便开始解析,产物是 DOM(文档对象模型),到这里 HTML 文档就被加载和解析完成了。 DOM的解析就是生成DOM树的过程
  2. DOM渲染:浏览器是解析DOM生成DOM Tree,结合CSS生成的CSS Tree,最终组成render tree,再渲染页面的过程。

结论

  • async/defer的JS执行(同步的JS执行)会阻塞DOM的解析过程
    GUI 渲染线程与 JavaScript 引擎为互斥,当 JS 引擎执行时 GUI 线程会被挂起。直到 JS 程序一轮调度执行完成,才会接着执行。因此如果 JS 执行的时间过长,这样就会造成页面的渲染不连贯,导致页面渲染加载阻塞的感觉。

  • CSS不会阻塞DOM的解析,但会阻塞DOM的渲染

DOM解析和CSS解析是两个并行的进程,所以CSS本身不会阻塞DOM的解析
通过JS间接影响 CSS加载会阻塞后面的JS语句执行 --> JS语句阻塞DOM的解析

  • CSS加载会阻塞后面的JS语句执行
    GUI 渲染线程与 JavaScript 引擎为互斥

补充知识1:浏览器解析DOM时,虽然会一行一行向下解析,但是它会预先同时加载具有引用标记的外部资源(例如带有src标记的<script>标签),而在解析到此标签时,则无需再去加载,直接运行,以此提高运行效率。
补充知识2:浏览器无法预先知道脚本的具体内容,因此在碰到<script>标签时,会触发页面渲染,确保<script>脚本内能获取到DOM的最新的样式。

JS加载阻塞DOM渲染问题,怎么解决? - 异步JS,JS三种异步加载的方式

defer、async 仅仅是改变脚本的执行时机

JS三种异步加载的方式

方式执行时机执行顺序
type="module"浏览器加载 ES6 模块,整个页面解析完毕,再执行模块脚本。等同于defer属性使用相同的执行队列,谁在前面谁先执行。
script标签中defer属性页面解析完毕再执行如果有多个defer脚本,会按照它们在页面出现的顺序加载。放入队列中,先进先出。
script标签中async属性脚本下载完,渲染线程就会中断渲染,执行这个脚本以后,再继续渲染而多个async脚本是不能保证加载顺序的
script 标签JS 执行顺序是否阻塞解析 HTML
<script>在 HTML 中的顺序阻塞
<script async>网络请求返回顺序可能阻塞,也可能不阻塞
<script defer>在 HTML 中的顺序不阻塞
script 标签中的 async 和 defer 属性

渲染进程在解析 HTML 的时候,如果遇到一个没有任何属性的 script 标签,就会暂停解析,先发送网络请求获取该 JS 脚本的代码内容,然后让 JS 引擎执行该代码,当代码执行完成后再切换回渲染引擎继续渲染流程。
在这里插入图片描述
async、defer属性的js脚本,渲染引擎遇到这一行命令,就会开始下载脚本,同时直接执行后面的命令。

async脚本会在JS下载完毕后立即执行
假设此时HTML没有解析完,会暂停渲染,先让JS引擎执行代码,执行完毕后再切换回渲染引擎继续渲染流程。
在这里插入图片描述
HTML 解析完了之后,async脚本才加载完,然后再执行脚本
在这里插入图片描述
defer会等HTML加载解析完再执行
defer的优先级高于DOMContentLoaded事件。页面渲染完毕后先执行defer属性的脚本,再触发DOMContentLoaded事件。
在这里插入图片描述

DOMContentLoaded和Load

对于浏览器说,页面加载主要有两个事件

  • DOMContentLoaded: 就是当页面的内容解析完成后(页面DOM加载完成就触发),则触发该事件
  • Load:等待页面的所有资源都加载完成才会触发,这些资源包括css、js、图片视频

DOM渲染优化

从重绘和回流方面进行优化

  • 开启GPU加速
    • transform
    • opacity
    • will-change
  • JS优化
    • 对于 scroll 等事件进行防抖/节流处理。
    • 使用变量缓存对敏感属性值(offset等)的计算
    • 避免频繁改动使用style,采用修改class的方式

从其他渲染阶段

  • 使用Web Worker开启多线程,将纯计算的工作迁移到Web Worker上处理(防止js执行事件过程阻塞页面渲染)。
  • 使用CDN获取css等静态资源(加快css的加载速度)
  • 避免动画实现中丢帧造成卡顿现象,尽量不用计时器实现动画,而采用window.requestAnimationFrame(回调)

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

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

相关文章

【动手学深度学习】--语言模型

文章目录 语言模型1.学习语言模型2.马尔可夫模型与N元语法3.自然语言统计4.读取长序列数据4.1随机采样4.2顺序分区 语言模型 学习视频&#xff1a;语言模型【动手学深度学习v2】 官方笔记&#xff1a;语言模型和数据集 在【文本预处理】中了解了如何将文本数据映射为词元&…

ATFX汇市:美初请失业金人数21.6万人,连降四期,劳动力供需偏紧

ATFX汇市&#xff1a;9月7日&#xff0c;美国劳工部数据显示&#xff1a;美国至9月2日当周初请失业金人数最新值21.6万人&#xff0c;低于前值22.9万人&#xff08;修正前22.8万人&#xff09;&#xff0c;低于预期值23.4万人。回顾历史数据&#xff0c;美国初请失业率人数从25…

【数学建模】2023数学建模国赛C题完整思路和代码解析

C题第一问代码和求解结果已完成&#xff0c;第一问数据量有点大&#xff0c;经过编程整理出来了单品销售额的汇总数据、将附件2中的单品编码替换为分类编码&#xff0c;整理出了蔬菜各品类随着时间变化的销售量&#xff0c;并做出了这些疏菜品类的皮尔森相关系数的热力图&#…

NIFI实现JSON转SQL并插入到数据库表中

说明 本文中的NIFI是使用docker进行安装的&#xff0c;所有的配置参考&#xff1a;docker安装Apache NIFI 需求背景 现在有一个文件&#xff0c;里面存储的是一些json格式的数据&#xff0c;要求将文件中的数据存入数据库表中&#xff0c;以下是一些模拟的数据和对应的数据库…

传输层协议 --TCP报文格式详细介绍

一、 TCP协议格式 TCP如何将报头与有效载荷进行分离&#xff1f; 当TCP从底层获取到一个报文后&#xff0c;虽然TCP不知道报头的具体长度&#xff0c;但报文的前20个字节是TCP的基本报头&#xff0c;并且这20字节当中涵盖了4位的首部长度。 因此TCP是这样分离报头与有效载荷的…

Java——》ThreadLocal

推荐链接&#xff1a; 总结——》【Java】 总结——》【Mysql】 总结——》【Redis】 总结——》【Kafka】 总结——》【Spring】 总结——》【SpringBoot】 总结——》【MyBatis、MyBatis-Plus】 总结——》【Linux】 总结——》【MongoD…

ChatGPT:深度学习和机器学习的知识桥梁

目录 ChatGPT简介 ChatGPT的特点 ChatGPT的应用领域 ChatGPT的工作原理 与ChatGPT的交互 ChatGPT的优势 ChatGPT在机器学习中的应用 ChatGPT在深度学习中的应用 总结 近年来&#xff0c;随着深度学习技术的不断发展&#xff0c;自然语言处理技术也取得了显著的进步。其…

软件设计模式(二):工厂、门面、调停者和装饰器模式

前言 在这篇文章中&#xff0c;荔枝将会梳理软件设计模式中的四种&#xff1a;工厂模式、Facade模式、Mediator模式和装饰器Decorator模式。其中比较重要的就是工厂模式和装饰器模式&#xff0c;工厂模式在开发中使用的频数比较高。希望荔枝的这篇文章能讲清楚哈哈哈哈&#xf…

OpenCV(三十一):形态学操作

​​​​​​1.形态学操作 OpenCV 提供了丰富的函数来进行形态学操作&#xff0c;包括腐蚀、膨胀、开运算、闭运算等。下面介绍一些常用的 OpenCV 形态学操作函数&#xff1a; 腐蚀操作&#xff08;Erosion&#xff09;&#xff1a; erode(src, dst, kernel, anchor, iteration…

【LeetCode】剑指 Offer <二刷>(6)

目录 题目&#xff1a;剑指 Offer 12. 矩阵中的路径 - 力扣&#xff08;LeetCode&#xff09; 题目的接口&#xff1a; 解题思路&#xff1a; 代码&#xff1a; 过啦&#xff01;&#xff01;&#xff01; 题目&#xff1a;剑指 Offer 13. 机器人的运动范围 - 力扣&#…

docker-compose安装mysql

基于docker-compose快速安装mysql 目录 一、目录结构 1、 docker-compose.yml 2、 my.cnf 3、error.log 二、执行安装 三、连接使用 一、目录结构 1、 docker-compose.yml version: 3 services:mysql:image: registry.cn-hangzhou.aliyuncs.com/zhengqing/mysql:5.7 #…

Kubernetes核心概念

Kubernetes是一个工业级的容器编排平台。 Kubernetes核心功能 服务发现和负载均衡。容器的自动装箱&#xff0c;调度&#xff08;scheduling&#xff09;&#xff0c;按照容器的规格&#xff08;需要的cpu和内存等&#xff09;确定一个容器存放到集群中的哪一个机器上。进行自…

创建vue3项目并引用elementui

1.创建vu3项目&#xff1a; 执行命令 npm create vuelatest 2.终端会出现如下选项&#xff0c;不确定的直接enter键进入下一步&#xff1b; 3.然后再执行下方命令&#xff1a; cd <your-project-name> npm install4.安装依赖成功后引入elementui,执行命令&#xff1a…

高压电容器的内部结构是什么样的?

高压电容器的内部结构取决于其具体的设计和用途&#xff0c;但通常包括以下主要组件&#xff1a; 电介质&#xff1a;电介质是高压电容器内部的核心部分。它通常由绝缘材料制成&#xff0c;如聚丙烯薄膜、聚酯薄膜、陶瓷或其他高绝缘性材料。电介质的选择取决于电容器的电压等级…

盘点那些有高级客服分配功能的软件系统

过去&#xff0c;很多企业虽然有服务意识&#xff0c;但并不强烈&#xff0c;现在客户需求以及团队运营的发展推动着企业在客户管理的方式上采用更有效的服务方式来应对实际的变化&#xff0c;尤其是客服行业&#xff0c;所以很多企业在客服的管理和分配上下尽了功夫&#xff0…

Unity的UI管理器

1、代码 public class UIManager {private static UIManager instance new UIManager();public static UIManager Instance > instance;//存储显示着的面板脚本&#xff08;不是面板Gameobject&#xff09;&#xff0c;每显示一个面板就存入字典//隐藏的时候获取字典中对…

【自动化测试】之PO模式介绍及案例

目录 概念 PO三层模式&#xff1a; 1. 构建基础的 BasePage 对象层 2. 构建首页的 Page 层&#xff08;操作层&#xff09; 3.构建业务层 常用断言方法&#xff1a; 4. 构建用例集&#xff0c;执行文件&#xff0c;输出自动化测试报告 测试报告模板 概念 PO&#xff08…

【C++】详解红黑树并模拟实现

前言&#xff1a; 上篇文章我们一起学习了AVL树比模拟实现&#xff0c;我们发现AVL树成功地把时间复杂度降低到了O(logN)。但是同时我们不难发现一个问题&#xff0c;在构建AVL树中我们也付出了不小的代价&#xff0c;频繁的旋转操作导致效率变低。为了解决这个问题&#xff0c…

使用Fastchat部署vicuna大模型

FastChat是一个用于训练、提供服务和评估基于大型语言模型的聊天机器人的开放平台。其核心特点包括&#xff1a; 最先进模型&#xff08;例如 Vicuna&#xff09;的权重、训练代码和评估代码。一个分布式的多模型提供服务系统&#xff0c;配备 Web 用户界面和与 OpenAI 兼容的…

算法通关村第十七关:黄金挑战-跳跃游戏问题

黄金挑战-跳跃游戏问题 1. 跳跃游戏 LeetCode 55 https://leetcode.cn/problems/jump-game/ 思路分析 关键是判断能否到达终点&#xff0c;不用管每一步跳跃到哪里&#xff0c;而是尽可能的跳跃到最远的位置 看最多能覆盖到哪里&#xff0c;只要不断更新能覆盖的距离&#x…