首页 > 其他分享 >浏览器事件循环 event loop(消息循环)

浏览器事件循环 event loop(消息循环)

时间:2023-10-18 15:48:22浏览次数:35  
标签:浏览器 渲染 队列 循环 线程 事件 执行 event loop

 打开浏览器 即 开启一个浏览器进程 (主要负责浏览器UI,用户交互,子进程拉起关闭等)
  并由浏览器进程拉起网络进程(多Tab共享)采用多线程模式,GPU 进程(多Tab共享)等

  当每开启一个 tab 页,浏览器进程会负责为该 Tab 拉起一个渲染进程,每一个渲染进程都会拉起一个渲染主线程(单线程模式),以保证多 tab 之间的独    立性

1、渲染主线程的工作

  解析HTML 、 解析CSS、 计算样式、 布局、 处理图层、 调用GPU(画页面)、 执行 js 代码、 执行事件(消息)函数 、调取计时器 等等  

2、渲染主线程单线程会带来的问题及解决方案

  2.1 执行 js 代码过程中, 遇到异步事件(setTimeout,setInterval,Promise,fetch等) 或 渲染任务(改变dom) 或 用户交互 时,如何做到不阻碍js执行(页面卡死)

  解决这个问题的关键 其实就是 渲染主线程的 工作原理

  渲染主线程就是一个处于无限循环的事件(消息)处理器(Google 浏览器如此写到  for(;;) )

  执行 js ,渲染等的过程,就是在执行事件,当没有任务的时候,进入休眠,有新的任务时,唤醒

    那么渲染主线程的任务从哪里获得呢  答案是 消息(事件)队列 (message queue)

  W3C 规定这个东西是 event loop, Google源码 叫 message loop

     那么队列里的消息来自于哪里呢 

  答案是 来自其他所有线程,包含计时器线程、网络线程、交互线程等

    那么这些线程为什么会生成任务呢

  答案是 渲染主线程 在执行事件时 遇到了 异步事件(setTimeout,setInterval,Promise,MutationObserver,XHR,fetch,addEventListener等) 或 渲染任务(改变dom) 或 用户交互 时,分配相应任务给这些线程,而主线程继续向下执行

  总结就是 浏览器通过异步执行的方式,在遇到需要异步执行的任务时,主线程生成任务并交给相应线程去执行,而自己继续向下执行,当其他线程完成时,将回调函数包装成任务,加入到相应的队列中去,等待主线程的调度执行,从而保证了浏览器永不阻塞,即最大限度的保证了渲染主线程即使是单线程也能流畅运行

  2.2 当事件处理器处理完一个事件后,如何决定下一个谁被执行呢,按队列先进先出么,有没有紧急的事件要插队呢

  答案是 有的,W3C 只规定了浏览器必须有存在于 正常队列(宏队列)之外的 微队列,这个队列的执行顺序处于最高,只有该队列中没有了事件,才能去执行其它队列

  但是随着业务对发展,仅仅两个队列已经远远无法满足,于是衍生出了多种队列,但 要基于以下原则,同一种类型的事件只能在一个队列中,不同种类型的事件,可以分属于不同队列中,且微队列执行优先级最高

  其中主要的有 微队列 (执行优先级最高),延时队列:计时器线程计时结束后返回的事件(执行优先级中),交互队列:用户操作后产生的事件(执行优先级高),渲染队列

  2.3 关于以上原则,没有例外么

  答案是 当然有,而需要我们前端明确知道的暂时只有一个,那就是页面渲染的 reflow ,js 修改 dom  时不会立即生效,修改完后立即获取dom元素尺寸等事件时,会立即同步执行渲染,而不是等待当前事件执行结束

 

 

  

标签:浏览器,渲染,队列,循环,线程,事件,执行,event,loop
From: https://www.cnblogs.com/ygrzzttzjzzzszz/p/17772284.html

相关文章

  • Laravel 代码重构:使用 Services, Events, Jobs, Actions 来重构控制器方法
    我听到关于Laravel最热门的问题之一是「如果构建项目」。如果我们缩小范围,它的大部分听起来像「如果逻辑不应该在控制器中,那么我们应该把它放在那里?」问题是这些问题没有单一的正确答案。Laravel给予了你自主选择结构的灵活性,这既是好事,也是坏事。你不会在官方的Laravel文档......
  • 《动手学深度学习 Pytorch版》 9.1 门控循环单元(GRU)
    我们可能会遇到这样的情况:早期观测值对预测所有未来观测值具有非常重要的意义。考虑一个极端情况,其中第一个观测值包含一个校验和,目标是在序列的末尾辨别校验和是否正确。在这种情况下,第一个词元的影响至关重要。我们希望有某些机制能够在一个记忆元里存储重要的早期信息。如......
  • 循环语法之编程模拟音乐播放器
    以音乐播放器软件的界面作为导入提问学生:如果需要自己生成一个歌单,在歌单中有哪些较为重要的组成部分?提取关键元素:歌曲名;歌手;歌曲顺序编程实现一:利用顺序结构实现一个简单的歌单回顾字符串类型与print()函数,实现下列代码songname1="画"songname2="借我"songname3="......
  • 使用 'for' 循环遍历字典
    内容来自DOC[https://q.houxu6.top/?s=使用'for'循环遍历字典](https://q.houxu6.top/?s=使用'for'循环遍历字典)d={'x':1,'y':2,'z':3}forkeyind:print(key,'对应于',d[key])Python如何知道它只需要从字典中读取key?ke......
  • break、continue、return在循环中用法的区别
    1.break:(1).结束当前整个循环,执行当前循环下边的语句。忽略循环体中任何其它语句和循环条件测试。(2).只能跳出一层循环,如果你的循环是嵌套循环,那么你需要按照你嵌套的层次,逐步使用break来跳出。2.continue:(1).终止本次循环的执行,即跳过当前这次循环中continue语句后尚未执......
  • What is click event?
    先不去讨论它语法、原理,先描述一下它的功能性,Clickevent想要实现的效果是?开发者在UI界面上放置一个按钮,并且开发者写了一段功能函数,当有人点击了这个UI按钮,就会自动去执行这段功能函数。这就是点击按钮想要的效果。点击事件的实现原理思考常见的按钮点击事件的简要实现......
  • Spring源码分析系列——循环依赖解析(附详尽流程图)
    前言本文分析spring循环依赖,我们知道构造函数填充属性是天然无法解决循环依赖的,而且解决循环依赖必须至少需要一个单例bean提前暴露。用xml标签配置属性bean,和@autowire注解注入属性bean,注入属性过程是不一样的。(1)xml标签配置属性bean是在解析xml过程中直接将属性值填充到be......
  • 城投行业融资迈向“筹融用管还评”卓越循环,用友Fast by BIP 很在行
    二十大报告指出,“要建设现代化产业体系,坚持把发展经济的着力点放在实体经济上,推进新型工业化”。在这个大方向指引下,城投企业的思维将从过去的注重基础设施建设转向注重产业,从注重资产转向注重现金流;一系列政策也在大力推进城投行业的“投融建管营”一体化发展建设,要求实现更高效、......
  • Vue性能优化--在Vue中,千万别用属性数组作为循环的对象
    在Vue中,千万别用属性数组作为循环的对象methods:{test(){...上面省略业务逻辑1万字 //16位像素数组letdcmbuffer=newUint16Array(dcmInfo._dictionary.dict["7FE00010"].Value[0]asArrayBuffer);this.currentImageInfo={......
  • 实验二 c语言分支与循环基础应用编程
    实验一源代码#include<stdio.h>#include<stdlib.h>#include<time.h>#defineN5#defineN1374#defineN2465intmain(){ intnumber; inti; srand(time(0)); for(i=0;i<N;i++) { number=rand()%(N2-N1+1)+N1; printf("20238329%04......