首页 > 其他分享 > js 和 css 是如何影响DOM树构建的?

js 和 css 是如何影响DOM树构建的?

时间:2022-12-18 11:01:05浏览次数:36  
标签:脚本 文件 执行 DOM JavaScript js 解析 css

大家好,我是coderBin

js 和 css 是如何影响DOM树构建的?

先做个总结,然后再进行具体的分析:

CSS不会阻塞DOM的解析,但是会影响JAVAScript的运行,javaSscript会阻止DOM树的解析,最终css(CSSOM)会影响DOM树的渲染,也可以说最终会影响渲染树的生成。

接下来我们先看javascript对DOM树构建和渲染是如何造成影响的,分成三种类型来讲解:

JavaScript脚本在html页面中

<html>
  <body>
    <div>1</div>
    <script>
      let div1 = document.getElementsByTagName('div')[0]
      div1.innerText = 'bin'
    </script>
    <div>test</div>
  </body>
</html>

两段div中间插入一段JavaScript脚本,这段脚本的解析过程就有点不一样了。

当解析到script脚本标签时,HTML解析器暂停工作,javascript引擎介入,并执行script标签中的这段脚本。

因为这段 javascript 脚本修改了DOM中第一个div中的内容,所以执行这段脚本之后,div节点内容已经修改为 bin 了。脚本执行完成之后,HTML解析器恢复解析过程,继续解析后续的内容,直至生成最终的DOM。

html页面中引入javaScript文件

//foo.js 
let div1 = document.getElementsByTagName('div')[0] 
div1.innerText = 'bin'
<html>
  <body>
    <div>1</div>
    <script type="text/javascript" src='foo.js'></script>
    <div>test</div>
  </body>
</html>

这段代码的功能还是和前面那段代码是一样的,只是把内嵌JavaScript脚本修改成了通过javaScript文件加载。

其整个执行流程还是一样的,执行到JAVAScript标签时,暂停整个DOM的解析,执行javascript代码,不过这里执行javascript时,需要现在在这段代码。这里需要重点关注下载环境,因为javascript文件的下载过程会阻塞DOM解析,而通常下载又是非常耗时的,会受到网络环境、javascript文件大小等因素的影响。

优化机制:

谷歌浏览器做了很多优化,其中一个主要的优化就是预解析操作。当渲染引擎收到字节流之后,会开启一个预解析线程,用来分析HTML文件中包含的JavaScript、CSS等相关文件,解析到相关文件之后,会开启一个预解析线程,用来分析HTML文件中包含的javascprit、css等相关文件、解析到相关文件之后,预解析线程会提前下载这些文件。

再回到 DOM 解析上,我们知道引入 JavaScript 线程会阻塞 DOM,不过也有一些相关的策略来规避,比如使用 CDN 来加速 JavaScript 文件的加载,压缩 JavaScript 文件的体积。

另外,如果 JavaScript 文件中没有操作 DOM 相关代码,就可以将该 JavaScript 脚本设置为异步加载,通过 async 或 defer 来标记代码,使用方式如下所示:

<script async type="text/javascript" src='foo.js'></script>
<script defer type="text/javascript" src='foo.js'></script>

async和defer区别:

  • async:脚本并行加载,加载完成之后立即执行,执行时机不确定,仍有可能阻塞HTML解析,执行时机在load事件派发之前。
  • defer:脚本并行加载,等待HTML解析完成之后,按照加载顺序执行脚本,执行时机DOMContentLoaded事件派发之前。

html页面中有css样式

//theme.css 
div {color:blue}
<html>
<head>
    <style src='theme.css'></style>
</head>
<body>
  <div>1</div>
  <script>
      let div1 = document.getElementsByTagName('div')[0]
      div1.innerText = 'bin' // 需要 DOM
      div1.style.color = 'red' // 需要 CSSOM
  </script>
  <div>test</div>
</body>
</html>

该示例中,JavaScript 代码出现了 div1.style.color = ‘red’ 的语句,它是用来操纵 CSSOM 的,所以在执行 JavaScript 之前,需要先解析 JavaScript 语句之上所有的CSS 样式。所以如果代码里引用了外部的 CSS 文件,那么在执行 JavaScript 之前,还需要等待外部的 CSS 文件下载完成,并解析生成 CSSOM 对象之后,才能执行 JavaScript 脚本。

而 JavaScript 引擎在解析 JavaScript 之前,是不知道 JavaScript 是否操纵了 CSSOM的,所以渲染引擎在遇到 JavaScript 脚本时,不管该脚本是否操纵了 CSSOM,都会执行CSS 文件下载,解析操作,再执行 JavaScript 脚本。所以说 JavaScript 脚本是依赖样式表的,这又多了一个阻塞过程。

总结:通过上面三点的分析,我们知道了 JavaScript 会阻塞 DOM 生成,而样式文件又会阻塞js的执行。


每文一句:每一日所付出的代价都比前一日高,因为你的生命又消短了一天,所以每一日都要更积极。今天太宝贵,不应该为酸苦的忧虑和辛涩的悔恨所销蚀,抬起下巴,抓住今天,它不再回来。

本次的分享就到这里,如果本章内容对你有所帮助的话欢迎点赞+收藏。文章有不对的地方欢迎指出,有任何疑问都可以在评论区留言。希望大家都能够有所收获,大家一起探讨、进步!

标签:脚本,文件,执行,DOM,JavaScript,js,解析,css
From: https://blog.51cto.com/u_15875573/5950818

相关文章

  • 前端开发系列123-进阶篇之generate Virtual-DOM
    title:前端开发系列123-进阶篇之generateVirtual-DOMtags:categories:[]date:2019-07-0600:00:08本文介绍通过render函数创建DOM的基本过程(仅仅核心部分),更多......
  • 前端开发系列119-进阶篇之commonJS规范和require函数加载的过程
    title:前端开发系列119-进阶篇之commonJS规范和require函数加载的过程tags:categories:[]date:2019-04-1500:00:08今晚接到个面试电话,被问到node中require函数......
  • @JSONField 和 @JsonFormat,前后端日期格式转换
    DTO:前端向后端接口请求时的对象。VO:后端向前端响应的对象。前端:vue后端:SpringBoot+MybatisPlus涉及的两个包:com.alibaba.fastjson.annotation.JSONField;com.......
  • Json Net 简单的文件读取和写入
    ▲读写的文件XiaoMing.json:{"Name":"小明","Sex":"男","Age":12}JsonWriteTest.json:{"StartX":1.23,"StartY":1.24,"EndX":10,"EndY":"YY","Fa......
  • 原生js实现rsa加密
    原生js实现rsa加密示例createNewUserKey().then(function(keyPairs){encrypt("thisisorigintext",keyPairs[0]).then(function(res){console.log('......
  • css2
    用了次html写笔记很让我emo我还是用回md吧有出错的「地方」,我会即使改正的emmetCSS的复合选择器CSS的元素显示模式CSS的背景1.Emmet语法简介Emmet插......
  • Vue 中实现全局引入 scss 变量
    导读最终实现的效果是:在vue文件的style标签中以及其它scss文件中都可以直接使用全局配置的scss变量,不需要再导入对应的scss文件。目录结构src│App.vue│......
  • JVM 使用jstat分析系统的垃圾回收情况
    jstat-gcutil输出结果分析_助你了解jvm命令,查找JVM堆栈信息,分析性能问题。下面介绍一下jstat命令:jstat:虚拟机统计信息监视工具(JVMStatisticsMonitoringTool)说明:监......
  • cpp jsoncpp serialize anddeserialize complete example
    //Model/Book.h#pragmaonce#ifndef__Book_H__#define__Book_H__#include<chrono>#include<ctime>#include<fstream>#include<iostream>#include<jsoncpp/......
  • Next.js 开发商 Vercel 正式推出 Edge Functions
    Next.js开发商Vercel正式推出EdgeFunctions来源:OSCHINA编辑: 白开水不加糖2022-12-1707:49:24 0Next.js框架背后的开发商Vercel 宣布推出Edg......