深入理解JavaScript之Event Loop

前言

最近阅读《高性能JavaScript》时,第六章谈到“通过定时器将JavaScript执行代码的控制权先让给浏览器用于更新UI状态,然后再将控制权交回给JavaScript代码,这样就可以使得页面更为流畅”,就联想到了之前理解的事件循环。

这篇文章就是为了解释为什么这么做可以提升页面的流畅度。

事件循环(Event Loop)

Internal.gif

单线程的JavaScript

总所周知,JavaScript语言的一大特点就是单线程,也就是说在一个时间段里,JavaScript只能做一件事情(浏览器是多线程)。 多线程可以实现应用的并行处理,从而以更高的CPU利用率提高整个应用程序的性能和吞吐量

但是JavaScript却以单线程进行,为什么呢?

JavaScript是浏览器脚本语言,用于与用户交互以及操作DOM。 考虑如下情况,如果有两个并发的操作,对同一个DOM节点分别进行删除和修改样式,此时浏览器就无法决定到底采用哪个线程的操作。类似数据库,我们可以采用“锁”来处理并发,但是这会平添复杂度。所以,JavaScript语言没有支持多线程操作。 那又考虑这种情况,既然JavaScript是单线程,在某一时刻内只能执行特定的一个任务,并且会阻塞其它任务执行。那么如果用户触发了一个非常耗时的I/O操作,那么按道理后续的所有操作都得等到I/O操作完成后方可进行。但是,事实上,后续的任务不必等待这个耗时的I/O操作完成,原因就是JavaScript与生俱来的异步和回调

而这背后恰好就是本文的主题——————事件循环

定义

事件循环包含了至少两个任务队列,宏任务队列和微任务队列。

宏任务

宏任务包含创建文档对象、解析HTML、执行主线JavaScript代码、更改当前URL以及各种事件,例如页面加载、输入、网络事件和定时器等等。宏任务运行完成后,浏览器继续其他的任务调度,如重新渲染页面或者垃圾回收。

微任务

微任务包括promise、回调函数、DOM发生变化等。微任务更新应用程序的状态,必须在浏览器任务继续执行其他任务(渲染UI视图或者进行下一个宏任务)之前执行。

两个基本原则

  1. 一次处理一个任务
  2. 一个任务开始直到运行完成,不会被其他任务中断

EC06193617CCE1FF11A9C3C68CF8DDF3.png
无论是宏任务队列还是微任务队列,二者在同一时刻都只执行一个任务,不过二者也有重要的区别: 在一次循环中,最多处理一个宏任务,而微任务队列中所有的微任务都会被处理

在微任务队列清空后,事件循环会检查当前是否需要重新渲染UI,如果需要则渲染UI视图。

补充

  1. 两个任务队列都是独立于事件循环的,这意味着任务队列的添加发生在事件循环外。
  2. 所有微任务都会在下一次渲染前完成,目的是在渲染前更新应用程序状态。
  3. 浏览器会尝试以每秒渲染60次页面,以达到每秒60帧的速度。所以,一次循环最理想的时间应该不超过16ms。
  4. 浏览器完成页面渲染后,进入下一轮事件循环迭代后,可能出现3种情况
    1. 如果事件循环执行到“is rendering needed”且浏览器处于另一个16ms结束之前(即浏览器尚未自动触发页面渲染时),浏览器可能不会选择在当前的时间循环中执行更新UI操作,因为更新UI是一个复杂且耗性能的操作。
    2. 如果事件循环执行到“is rendering needed”且浏览器刚好离上一次渲染16ms左右时(即浏览器即将自动触发页面渲染时),此时浏览器会进行UI更新。
    3. 执行下一个事件循环耗时超过16ms,浏览器将无法以目标帧率重新渲染页面,且UI无法被更新。如果延迟不大是很难察觉到,但是,如果有非常耗时的操作,这个时候用户会觉得网页十分卡顿,甚至浏览器会提示“无响应脚本”。

前情回顾

现在,用事件循环和简单的例子来分析《高性能的JavaScript》中的那句话。 需求:给包含1000个数字的数组中的每个元素取绝对值(假设对一个数字进行需求操作耗时1ms)。

情况1(不使用定时器): 由于JavaScript主线程代码属于宏任务的一种,所以一次事件循环需要处理1000个数字,所以1s事件循环才进行到UI更新阶段,但是由于耗时过长,UI状态不会被更新,页面出现卡顿甚至堵塞。

情况2(使用定时器): 将一次处理1000个数字的任务分割为20个每次处理50个数字的任务。由于定时器是宏任务的一种,所以一次事件循环只处理50个数字,由于此时微任务队列为空,所以50ms后事件循环进行到UI更新阶段,然后根据情况进行UI渲染,页面未出现卡顿或者堵塞。

当然,如果只是单纯的处理数据,我们可以考虑使用Web Workers

总结

  1. JavaScript是单线程的,同一时刻是只能执行一个任务。
  2. 事件循环包含一个宏任务队列和至少一个微任务队列。事件循环一次迭代,至多执行一个宏任务但是会执行完所有的微任务。
  3. Web应用越复杂,积极主动管理UI线程就越重要,即使JavaScript代码很重要,也不能影响用户体验。

参考

  1. 《High Performance JavaScript》
  2. 《Secrets of the JavaScript Ninja》
  3. 《HTML 5.2》

更多专业前端知识,请上 【猿2048】www.mk2048.com

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

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

相关文章

使用EasyPoi导出Excel

Excel模板来自自己写死的一个excel模板,相当于是用户查询数据,数据填充到一个模板的Excel里,再导出Excel /*创建模板*/String a request.getSession().getServletContext().getRealPath("/resource/河南能源化工集团安全监控系统联网系统…

Hazelcast入门

7月,我写了一个博客向Java开发人员介绍erlang,重点介绍了这两种语言之间的一些异同。 erlang虚拟机具有许多令人印象深刻的内置功能,其中之一是它们独立于位置并且可以互相通信。 这意味着可以通过编写很少的代码行在VM之间同步数据。 如果您…

android手机最低内存,原神手机端需要哪些配置 手机端最低配置要求介绍

原神是一款由米哈游自主研发的全新开放世界冒险游戏,游戏最近迎来了pc端的首次测试,而且在不久之后就会开启原神手机端的公测版本,那么手机端需要什么配置呢?小编带来了详细的介绍。移动端预下载:9月25日下午16&#x…

AnswerOpenCV一周佳作欣赏(0615-0622)

一、How to make auto-adjustments(brightness and contrast) for image Android Opencv Image Correctionim using OpenCV for Android. I would like to know,how to make image correction(auto adjustments of brightness/contrast) for image(bitmap) in android via Open…

vuex最简单、最详细的入门文档

如果你在使用 vue.js , 那么我想你可能会对 vue 组件之间的通信感到崩溃 。 我在使用基于 vue.js 2.0 的UI框架 ElementUI 开发网站的时候 , 就遇到了这种问题 : 一个页面有很多表单 , 我试图将表单写成一个单文件组件 , 但是表单 ( 子组件 ) 里的数据和页面 ( 父组件 ) 按钮交…

Vue生命周期详解 对应代码解析

-使用GitHub阅览 对于Vue的实例,比如 const app new Vue({...})浏览器解析到这段代码的时候,自动执行beforeCreate > created > beforeMount > mounted方法,每当data的某个属性值更改了,比如app.mes "hi"&…

所有其他指标均无用

对于队列,无论是实现为JMS ,数据库表(即Ruby的Delayed :: Job用于队列的什么),甚至是Amazon的SQS ,用于评估队列状态的最常见指标是其长度。 从本质上讲,可以基于在任何给定时间队列中驻留多少消…

类似苹果数据线的android,除了常见的安卓、苹果、Type-c,还有哪些你不知道的手机数据线?...

随着智能手机日益发展,辅助智能手机的数据线配件也越来越多样。现在我们最常见的无非就是标准Micro usb口、正反随便插的Type-c接口、还有苹果Lightning数据线,那么除了这些类型数据线,你知道如今市面上还有哪些更方便好用的手机数据线吗&…

团体程序设计天梯赛L3-019 代码排版(23分)

打算学完编译原理后再次实现它。。。 以下为比较“杂乱”的方法: 海量数据: https://pan.baidu.com/s/1Prd0ZqNLoCLLvXyJjCef3w 如果大家有发现这个程序的问题,请联系我,谢谢啦~~~ 我很疑惑,不知道错在哪里&#xff0c…

canvas入门实战--邀请卡生成与下载

1.前言 写了很多的javascript和css3的文章,是时候写一篇canvas的了。canvas是html5提供的一个新的功能!至于作用,就是一个画布。然后画笔就是javascript。canvas的用途非常的广,特别是html5游戏以及数据可视化这两个方面。现在can…

javascript 数组求交集/差集/并集/过滤重复

最近在小一个小程序项目,突然发现 javscript 对数组支持不是很好,连这些基本的功能,都还要自己封装.网上查了下,再结合自己的想法,封装了一下,代码如下. //数组交集 Array.prototype.intersect function(){let mine this.concat();for (var i 0; i < arguments.length; …

Apache ActiveMQ 5.9发布

Apache ActiveMQ团队刚刚发布了新的ActiveMQ 5.9版本 。 Apache ActiveMQ 5.9发布 自从先前的5.8版本以来&#xff0c;此版本是8个月的辛苦工作。 在此发行版中&#xff0c;我们将像往常一样对代理进行增强&#xff0c;并使用最新的协议&#xff08;例如AMQP和MQTT&#xff…

android 美颜录像,Android 关于美颜/滤镜 利用PBO从OpenGL录制视频

前言上次我写了一遍文章《Android 关于美颜/滤镜 从OpenGl录制视频的一种方案》&#xff0c;里面利用ImageReader来从获取Surface上获取数据&#xff0c;但是经过熊皮皮的提醒&#xff0c;我发现多PBO的确可以实现跟ImageReader一样的效果&#xff0c;并且版本要求仅为Android4…

DAY77-Django框架(八)

今日内容&#xff1a;创建多表模型、多表数据操作、基于对象的跨表查询、基于双下划线的跨表查询 一、创建多表模型 class Author(models.Model):# id如果不写,会自动生成,名字叫nid,并且自增id models.AutoField(primary_keyTrue)name models.CharField(max_length32)sex m…

Async Await

接着上一篇Generator co的使用 https://juejin.im/post/5ab51336f265da239d493ff4 这里继续说说js异步处理的方法 async await( 即Generator的语法糖) async 是“异步”的简写&#xff0c;async 用于申明一个 function 是异步的&#xff0c;而 await 用于等待一个异步方法执行…

Java对象到对象映射器

我在该项目上使用了Dozer一段时间。 但是&#xff0c;最近我遇到了一个非常有趣的错误&#xff0c;它促使我环顾四周&#xff0c;并尝试使用其他“对象到对象”映射器。 这是我找到的工具列表&#xff1a; 推土机&#xff1a;推土机是Java Bean到Java Bean的映射器&#xff…

android媒体播放框架,Android 使用超简单的多媒体播放器JiaoZiVideoPlayer

在之前的项目中用到了视频播放的功能&#xff0c;在网上看了看使用了大家用的比较多的一个开源项目JiaoZiVideo可以迅速的实现视频播放的相关功能。JiaoZiVideo的简单使用集成了JiaoZiVideo后仅需这几行代码就可以实现播放视频JZVideoPlayerStandard jzVideoPlayerStandard (J…

送福利:ROKID 语音开发板免费送,开启你的物联网之旅

都让一让&#xff0c;我说个事情&#xff1a;掘金联合 Rokid 开发者社区给大家发福利啦&#xff01; 掘金联合 Rokid 开发者社区为大家准备了一些福利&#xff0c;只要秀出你的 skill 和技术栈&#xff0c;就有可能获得 Rokid 全栈语音智能开发套件。 ? Rokid开箱试用活动 活…

点击复制文本

点击按钮&#xff0c;进行文本复制操作。实现这个功能需要二点&#xff1b; 一&#xff1a;用window.getSelection().selectAllChildren(“”)获取要复制的内容 二&#xff1a;用document.execCommand ("Copy");进行复制操作 关键代码 window.getSelection().selec…

6.25

TEXT 94 Cancer biology 肿瘤生物学 Cramping tumours 断了肿瘤的活路&#xff08;陈继龙编译&#xff09; Jan 18th 2007 From The Economist print edition An old observation about cancer cells may lead to a new treatment 早年发现的肿瘤细胞的一个特征可能为治疗肿瘤打…