深入了解JavaScript阻塞渲染

目录
  • 到底几个线程
  • 主线程的任务
    • Parse HTML
    • Recaculate Style
    • Layout
    • Update Layer Tree
    • Paint
  • JS为啥阻塞渲染
  • 总结

前言:

在中文社区,这么多年一直流传一个说法:JS线程负责执行JSGUI渲染线程负责渲染,这两者是互斥的,所以JS执行时会阻塞渲染。但随着Dev Tools使用的增多,逐渐开始怀疑以上说法。本文会以实际案例来解释为什么JS阻塞渲染。

到底几个线程

在讲解JS线程与GUI线程互斥的文章中,通常会列出渲染进程包含的线程,比如:

  • GUI渲染线程
  • JS引擎线程
  • 事件触发线程
  • 定时触发器线程
  • HTTP请求线程

但是,我们以百度的搜索页举例,打开Performance面板开启录制:

上图录制结果中:

  • Chrome_ChildIOThread对应IO线程的任务记录,用户输入、网络、设备相关事件都与他相关
  • Raster记录光栅化线程池任务、GPU记录GPU合成位图的任务、Compositor记录合成线程的任务执行,以上三者都与浏览器渲染相关
  • Main记录渲染进程的主线程中的任务

从这个角度看,浏览器实际的线程情况与那些GUI线程相关的文章描述的并不相同。

主线程的任务

接下来,让我们进入Main。红线框内长短不一的灰色块,就是主线程中执行的任务。

注意看红框内的绿色块FP,代表First Paint(首次绘制):

那么在首次绘制前都要执行什么任务呢?可以看到主要有3个Task(任务):

第一个任务是请求HTML数据:

Parse HTML

当请求回HTML字节流后,开始第二个任务,将HTML字节流解析为DOM,这个任务的名字就是图中的蓝色块Parse HTML

注意其中有些执行时长不一的Evaluate Script,这些是解析DOM树过程中遇到的JS代码。

DOM树中可以看到这些阻塞DOM树生成的JS脚本:

他们的存在显著拉长了Parse HTML的用时。

Recaculate Style

解析完DOM树(蓝色Parse HTML)后,下一个任务是紫色Recaculate Style

他负责将HTML中的CSS样式(外联、内联)输出为styleSheetsstyleSheets有两个作用:

  • 可以与DOM树结合为页面带来样式
  • JS可以操作styleSheets改变页面样式

我们可以从控制台打印document.styleSheets直观感受他的存在:

Layout

有了DOM树与styleSheets,接下来需要为视图中可见部分生成一棵树(比如display: none部分就不需要在这棵树中显示)。

这个任务是紫色Layout

Update Layer Tree

用户看到的页面实际是由多层页面重叠后的结果,开发者可以用很多手段(比如z-index)改变某部分的层级。

比如滚动条就会形成自己独立的层级:

既然是多层结构,那么就需要更新每层的信息,这个任务是紫色的Update Layer Tree

Paint

我们可以发现,在FP之前,Update Layer Tree之后只剩下Paint这一任务了:

从字面意义讲,这就是绘制么?并不是。

Paint的任务是整理每一层页面的绘制信息,构成绘制列表,这些数据会交给合成线程负责后续绘制操作。

可以发现,具体的绘制操作是交由合成线程完成,他与JS所在线程(主线程)并不是互斥的。

JS为啥阻塞渲染

我们现在知道,JS执行与Paint任务都发生在主线程。

渲染被阻塞的原因很明显:因为Paint任务没有及时执行,即绘制列表没有及时提交给合成线程。

之所以没有及时执行,可能是因为JS执行时间过长,导致这一帧没有时间执行Paint

比如,我们打开B站,记录下主线程的任务。

可以看到,有个JS执行时长达到231.88ms,超过了一帧的时间,在此期间主线程就没时间执行Paint了:

总结

JS之所以阻塞渲染,是因为JS执行与渲染相关任务都在争夺主线程有限的资源。当JS执行时间过长,渲染相关任务就没时间执行了。

到此这篇关于深入了解JavaScript阻塞渲染的文章就介绍到这了,更多相关JS阻塞渲染 内容请搜索我们以前的文章或继续浏览下面的相关文章希望大家以后多多支持我们!

(0)

相关推荐

  • JS实现数据动态渲染的竖向步骤条

    本文实例为大家分享了JS实现数据动态渲染竖向步骤条的具体代码,供大家参考,具体内容如下 实现以下效果: 运用的知识点主要是html的伪元素.然后步骤条通过js动态渲染.最后一条数据的状态颜色状态为高亮状态. 直接上代码 html部分: <ul class="progress_box"> </ul> css部分: * { margin: 0; padding: 0; } ul { width: 360px; margin:100px auto; } li { po

  • 利用JS将图标字体渲染为图片的方法详解

    目录 前言 实现方式 html css js 效果 前言 在软件开发中肯定要用到图标,比如下图的 Groove 音乐中就用到了许多图标.一种获取这些图标的方法是把 Groove 音乐截个图,然后熟练地开启 Photoshop,开始抠图.这种方式很逊,效率也很低(虽然我刚开始就是这么干的). 如果打开 C:/Program File/WindowsApps(需要修改权限才能进入),可以发现几个名字里带 ZuneMusic 的文件夹,其中的某一个文件夹中会有字体文件 SegMVR2.ttf.这是一个

  • 渲染函数 & JSX详情

    目录 一.基础 二.节点.树以及虚拟 DOM 1.虚拟 DOM 三.createElement 参数 1.深入数据对象 2.完整示例 3.约束 四.使用 JavaScript 代替模板功能 1.v-if 和 v-for 2.v-model 3.事件 & 按键修饰符 4.插槽 五.JSX 六.函数式组件 1.向子元素或子组件传递 attribute 和事件 2.slots() 和 children 对比 七.模板编译 一.基础 Vue 推荐在绝大多数情况下使用模板来创建你的 HTML.然而在一些场

  • nuxt.js服务端渲染中axios和proxy代理的配置操作

    需要npm axios? 刚开始,我以为需要像普通的vue SPA开发那样,需要npm axios,这种方式的确可以生效.但在使用时并不方便.尤其是设置代理比较麻烦,而且在asyncData里与在普通methods里使用方式不一样. 后来在nuxt的github上发现了nuxt是默认集成了axios的,所以不需要npm axios,但是需要进行适当的配置. 以上是百度到的,发现老是报错,现在网上的教程完全是在扯淡,npm axios 是不需要安装了,但是 @nuxtjs/axios 要安装啊 第

  • 爬虫进阶-JS自动渲染之Scrapy_splash组件的使用

    目录 1. 什么是scrapy_splash? 2. scrapy_splash的作用 3. scrapy_splash的环境安装 3.1 使用splash的docker镜像 3.2 在python虚拟环境中安装scrapy-splash包 4. 在scrapy中使用splash 4.1 创建项目创建爬虫 4.2 完善settings.py配置文件 4.3 不使用splash 4.4 使用splash 4.5 分别运行俩个爬虫,并观察现象 4.6 结论 5. 了解更多 6. 小结 1. 什么是s

  • mustache.js实现首页元件动态渲染的示例代码

    前言 在项目开发过程中,特别是OA类软件,会针对邮件/待办/公告等模块在主页面进行快捷查看的元件展示要求,类似效果如下 ​ 针对框架层面,我们可以进行后台的可视化配置,使用mustache.js在主页面进行动态渲染,避免了对主页面的繁琐的硬编码工作,同时针对每个信息展示的元件进行内部个性化处理 表结构 ​ 包含了元件名称,元件模板路径,元件列表数据路由,查看更多路由,启用/禁用等 可视化配置 ​ ​ 模板定义 这里的模板直接使用的html文件,方便css与js的修改,简单的使用了mustache

  • jQuery+Ajax+js实现请求json格式数据并渲染到html页面操作示例

    本文实例讲述了jQuery+Ajax+js实现请求json格式数据并渲染到html页面操作.分享给大家供大家参考,具体如下: 1.先给json格式的数据: [ {"id":1,"name":"stan"}, {"id":2,"name":"jack"}, {"id":3,"name":"lucy"}, {"id&quo

  • 深入了解JavaScript阻塞渲染

    目录 到底几个线程 主线程的任务 Parse HTML Recaculate Style Layout Update Layer Tree Paint JS为啥阻塞渲染 总结 前言: 在中文社区,这么多年一直流传一个说法:JS线程负责执行JS,GUI渲染线程负责渲染,这两者是互斥的,所以JS执行时会阻塞渲染.但随着Dev Tools使用的增多,逐渐开始怀疑以上说法.本文会以实际案例来解释为什么JS阻塞渲染. 到底几个线程 在讲解JS线程与GUI线程互斥的文章中,通常会列出渲染进程包含的线程,比如

  • javascript页面渲染速度测试脚本分享

    复制代码 代码如下: /* 获取渲染开始的时间戳, 保存在数组PAGE_SPEED_TIME中 */<html><script type="text/javascript">/*tag*/PAGE_SPEED_TIME = [new Date().getTime()];</script><head>......</head> 复制代码 代码如下: ....../* 页面最末端,计算页面加载耗用的时间 */</body&g

  • 游览器中javascript的执行过程(图文)

    1. 大多数游览器的组件构成如图      在最底层的三个组件分别是网络,UI后端和js解释器.作用如下: (1)网络- 用来完成网络调用,例如http请求,它具有平台无关的接口,可以在不同平台上工作 (2)UI 后端- 用来绘制类似组合选择框及对话框等基本组件,具有不特定于某个平台的通用接口,底层使用操作系统的用户接口 (3)JS解释器- 用来解释执行JS代码 ps:上图和知识点主要来自<HOW BROWSERS WORK: BEHIND THE SCENES OF MODERN WEB BR

  • 简单的React SSR服务器渲染实现

    为什么要SSR 单页应用将UI层和内容都由javascript来渲染,搜索引擎或网页爬虫需要完成的HTML结构,因此单页应用如果只在客户端渲染,不利于SEO,此外尽管我们可以通过按需加载的形式来减少首页加载的js,但是通过js来渲染DOM的时候还是会有一定的时间延迟. 0.前言 服务端渲染在项目中不是刚需的东西,但有的时候也是需要做一个服务端渲染,项目要做服务端渲染当然是有很多好处的 首屏加载快,相比SPA单页应用还要有优势. SEO 优化 利于爬虫,爬取数据. 1. 简介 服务端渲染是指页面的

  • Vue项目数据动态过滤实践及实现思路

    这个问题是在下在做一个Vue项目中遇到的实际场景,这里记录一下我遇到问题之后的思考和最后怎么解决的(老年程序员记性不好 -.-),过程中会涉及到一些Vue源码的概念比如 $mount . render watcher 等 问题是这样的:页面从后台拿到的数据是由 0 . 1 之类的key,而这个key代表的value比如 0-女 . 1-男 的对应关系是要从另外一个数据字典接口拿到的:类似于这样的Api: { "SEX_TYPE": [ { "paramValue":

  • 利用 Chrome Dev Tools 进行页面性能分析的步骤说明(前端性能优化)

    背景 我们经常使用 Chrome Dev Tools 来开发调试,但是很少知道怎么利用它来分析页面性能,这篇文章,我将详细说明怎样利用 Chrome Dev Tools 进行页面性能分析及性能报告数据如何解读. 分析面板介绍 上图是 Chrome Dev Tools 的一个截图,其中,我认为能用于进行页面性能快速分析的主要是图中圈出来的几个模块功能,这里简单介绍一下: Network : 页面中各种资源请求的情况,这里能看到资源的名称.状态.使用的协议(http1/http2/quic...).

  • React 并发功能体验(前端的并发模式)

    React 是一个开源 JavaScript 库,开发人员使用它来创建基于 Web 和移动的应用程序,并且支持构建交互式用户界面和 UI 组件.React 是由 Facebook 软件工程师 Jordan Walke 创建,React 的第一个版本在七年前问世,现在,Facebook 负责维护.React框架自首次发布以来,React 的受欢迎程度直线飙升,热度不减. 2020 年 10 月,React 17 发布了,但令人惊讶的是--"零新功能".当然,这并不是真的表示没有任何新添加

  • Vue.js九个性能优化技巧(值得收藏)

    目录 Functional components Child component splitting Local variables Reuse DOM with v-show KeepAlive Deferred features Time slicing Non-reactive data Virtual scrolling 总结 参考资料 这篇文章主要参考了 Vue.js 核心成员Guillaume Chau在 19 年美国的 Vue conf 分享的主题:9 Performance se

  • preload对比prefetch的功能区别详解

    目录 一.前言 二.preload 2-1.定义: 2-2.好处: 2-3注意: 2-4.特殊用法 三.prefetch 3-1.定义: 3-2.实例: 四.preload 和 prefetch 的区别 一.前言 在使用@vue/cli工具构建的项目,打包上线之后,一般都能看到<link rel="preload">和<link rel="prefetch">这样的标签,对于preload与prefetch的作用和区别一直以来都不是太了解,所

  • vue项目中一定会用到的性能优化技巧

    目录 引言 性能优化标准 Lighthouse 通用常规优化手段 通用性能优化分析 FCP(First Contentful Paint) LCP(Largest Contentful Paint) SpeedIndex(速度指数) 排查性能瓶颈 分析包内容 利用chorme devtool 的代码覆盖率 针对vue 的特殊优化 图片懒加载 虚拟滚动 vue 中的函数式组件 利用v-show .KeepAlive 复用dom 分批渲染组件 最后 引言 提起性能优化 很多人眼前浮现的面试经验是不是

随机推荐