浏览器事件循环最详细的帖子总结

浏览器事件循环

浏览器是多进程多线程的

这样设计提高了浏览器的安全性和稳定性,即使某个标签页奔溃,也不会影响到其她标签页或者进程。

  1. 浏览器主进程: 负责页面展示(标签页的创建、销毁,导航栏的前进后退、网络请求、文件管理)
  2. 插件进程: 大部分浏览器支持插件的扩展
  3. 网络进程: 负责网络资源的加载
  4. 渲染进程: 包括了 主线程、多个工作线程、甚至包括合成线程、多个光珊组成的
  5. javaScript的执行以及用户的交互等。

浏览器渲染进程

主线程: 它主要负责解析HTML、CSS、执行js,响应用户操作等一些事物
由于主线程是单线程的,所以导致了产生了异步任务, 而事件循环(消息队列)是异步任务的实现方式

如何理解主线程单线程呢

首先主线程是单线程的,在浏览器源代码中,他执行方式是通过一个 for(;;)来执行的,这个死循环表示主线程是一个007的🐮🐎,会一个一个的把包装好的任务顺序执行。

如果他是多线程,一个线程执行js、一个线程解析html、一个线程解析css、一个线程响应用户操作。多线程提高了程序的性能和效率。但是容易导致一下几种情况:

  1. 竞态条件和数据竞争:多线程处理可能导致访问共享内存的竞争条件,可能导致数据不一致和死锁等问题。为了解决这些问题,需要进行同步操作,这会增加代码的复杂度和开销。
  2. 安全问题:多线程环境存在安全漏洞,如数据泄露、内存溢出等问题,这会给程序带来潜在的风险和危害。
  3. 性能问题:虽然多线程处理可以提高程序的并行性和效率,但是在某些情况下,会导致过多的上下文切换和内存消耗,从而降低程序的性能和稳定性。
  4. 编程难度高:多线程编程比单线程编程更复杂,需要处理并发问题、同步和通信等问题。这需要开发人员具备更多的多线程编程经验和技能,也增加了程序的开发和维护难度。
  5. 浏览器环境的限制:在浏览器环境下,JavaScript的执行环境是单线程的,这就意味着在渲染过程中,如果遇到了JavaScript代码,浏览器必须停止渲染并等待JavaScript执行完毕。即使使用了Web Workers或其他技术来在后台运行其他线程,仍然会受到浏览器环境的限制和影响。

如何理解JS的异步呢

异步是单线程的解决方案

为什么说 异步是单线程的解决方案呢,想象一下,如果没有异步,我们设置一个定时器,5秒后执行,这五秒会卡在这里等待,用户想点击其他地方,浏览器也不给响应,页面有些更新也无法及时得到更新和绘制。定时器如此,网络请求也如此、其他异步任务也一样。这样就导致了浏览器主线程的阻塞,导致效率特别低下,用户体验极其不好,所以异步就应运而生了。
**浏览器如何处理异步任务: **浏览器通过将计时器、网络、事件监听等异步任务交给渲染进程的其他线程去处理,这样主线程就是一个一直繁忙的状态,不会阻塞主线程的任务,用户的感知是流畅的,使之浏览器用不阻塞、最大程度的保持了单线程的流畅运行。

异步任务什么时机交个主线程来执行呢

1. 任务没有优先级、消息队列有优先级
根据W3C得解释,每个任务有不同的类型,不同的任务可以属于不同的队列、相同的任务类型,不能出现在不同的队列,不同的任务有不同的优先级(google的源代码里面定义了不同任务的不同的优先级),在每一次任务循环过程中,浏览器自主的决定取哪一个队列的任务,但浏览器必须有一个微队列,并且微队列必须有最高的优先级,必须先执行。

2. google浏览器如何调度的呢
首先我们以三个队列来举例子微队列 延时队列 交互队列来进行举例:

首先浏览器渲染进程的主线程一直在循环执行该队列所有包装好的任务,执行完毕后查看微任务队列中有没有任务,有的话,需要讲微任务放在主线程中执行,执行完成后继续看微任务队列中有没有任务,如果没有,去交互队列中查看任务,如果有包装好的任务,将包装好的任务放在主线程执行,执行完毕后再去查看微任务队列中有没有任务,如果有继续执行微任务队列中包装好的任务,没有则继续查看交互队列中的任务,循环执行,如果交互队列没有任务了,则取出一个延时队列中的任务,放在主线程中,执行完毕后仍然会检查微队列和其他高于此队列的任务,如果有按照优先级执行

3. 另外附送一道题:JS中的计时器能否做到精准计时

答案当然是否定的了,主要原因如下

  • 首先浏览器的计时器调用的是操作系统的计时器,计算机的计时器本身就有偏差,而且最准确的计时是通过原子钟来确定的,所以肯定是无法绝对的上的精准
  • 其次早期的浏览器本省就存在4ms的延迟,其次在最新的W3C的标准,超过5层嵌套后,就会增加4ms的延迟,具体源代码如下:
    // Step 11 of the algorithm at
    // https://html.spec.whatwg.org/multipage/timers-and-user-prompts.html requires
    // that a timeout less than 4ms is increased to 4ms when the nesting level is
    // greater than 5.
    constexpr int kMaxTimerNestingLevel = 5;
    constexpr base::TimeDelta kMinimumInterval = base::Milliseconds(4);
    constexpr base::TimeDelta kMaxHighResolutionInterval = base::Milliseconds(32);
    
  • 最后,收到事件循环的影响,在主线程执行完后,去拿延时队列的计时器任务,也会有对应的延迟,所以综上所述,js的计时器,不是很精准。
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
浏览器事件循环机制是一种执行模型,用于处理浏览器中的异步任务。它的基本原理是通过一个事件队列来管理异步任务的执行顺序,确保每个任务都能按照规定的顺序得到执行。 事件循环机制的核心是事件循环线程,它负责处理所有的异步任务。当浏览器遇到一个异步任务时,它会将任务添加到事件队列中,然后继续执行同步任务。当同步任务执行完毕后,事件循环线程会开始从事件队列中取出任务,按照顺序执行它们。 事件循环机制的另一个重要的概念是回调函数,它是异步任务完成后需要执行的函数。当浏览器取出一个任务时,它会检查该任务是否有回调函数,如果有,就执行该函数。如果没有,就直接进入下一个任务。 事件循环机制的实现还涉及到一些微任务和宏任务的概念。微任务是指在当前任务执行完毕后立即执行的任务,而宏任务则是指需要等到下一个事件循环周期才执行的任务。常见的微任务包括Promise的then()和catch()方法、MutationObserver的回调函数等,而常见的宏任务包括setTimeout、setInterval、requestAnimationFrame等。 总之,浏览器事件循环机制的原理是通过一个事件队列来管理异步任务的执行顺序,确保每个任务都能按照规定的顺序得到执行。它是浏览器中实现异步任务的核心机制,理解它对于开发高效的异步代码非常重要。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值