浏览器的事件循环

其实在我们电脑的操作系统中,每一个运行的程序都会由自己的进程(可能是一个,也可能有多个),浏览器就是一个程序,它的运行在操作系统中,拥有一组自己的进程(主进程,渲染进程,网络进程,GPU进程....)

浏览器:各个进程之间是相互独立的(这样不会因为一个进程的问题导致其他的进程奔溃不能使用),而进程之间又是需要相互协作的。

01:主进程

管理整个的浏览器窗口(用户界面,地址栏,书签栏等等),他还负责创建和销毁渲染进程,并通过进程之间的IPC通信与渲染进程通信(管理浏览器的各个组件)

02:渲染进程
也成为页面进程,每个独立的页面都有自己的独立渲染进程(渲染引擎),进行负责解析HTML,CSS,JS,然后渲染到我们看到的视觉

★ 计时器和任务队列就是在该进程中(该进程需要和主进程之间IPC相互通讯,告诉主进程需要执行那些任务)

03:网络进程
负责处理网络请求,同时产生的跨域问题也是在网络进程中被拦截的,一般浏览器中页面之间是共享一个网络进程的

04:GPU进程
负责处理与图形相关的操作,例如绘制网页内容、执行动画和视频解码。这可以减轻主进程和渲染进程的工作负担,提高了性能。一般浏览器中页面之间是也是共享一个GPU进程

05:插件进程+其他进程

总结:现代浏览器通常有一个主进程(浏览器进程)、多个渲染进程(用于运行页面,每个页面一个渲染进程)、一个共享的网络进程(处理网络请求),以及一个共享的GPU进程(处理图形渲染)。其他进程(如插件进程等)也可能存在。

执行调度优先级?(一个进程下有多个子线程)

由于渲染主线程主要分则解析js,css,html,布局,图层处理,计时器等等操作,非常繁忙!

这里就有一个调度问题?(以前端角度)

01: js执行一半的时候,用户有了交互,怎么处理?

02:js执行一半的时候,有个定时器时间到了,怎么处理?

03:js执行一半的时候,请求回来了,怎么处理?

04:......

过程: 渲染主线程开始时循环状态,每次都去任务队列查看是否有任务,有任务的话就进入主线程,没有进入休眠状态。
同时其他的线程的任务可以随时插入任务队列中(任务队列尾部);

有些操作(网络请求,绑定事件, 定时器。。。)无法立即执行的操作,不能让其一致占有主线程,导致其他的任务不能执行。于是渲染主线程分成了:同步任务和异步任务。

当渲染主线程发生计时任务,网络任务,事件监听时,会将任务交给对应的其他线程处理,并结束当前的该任务,继续后面的任务执行。

其他线程完成时,将对应的回调函数包装成任务加入消息队列尾部,等待执行

如图:渲染主线程执行同步任务,发现该任务是计时器任务,于是将该任务交给了对应的线程模块处理该任务,然后继续任务队列中的其他任务,然后计时线程结束后产生的任务,排列到任务对列尾部

任务队列: 消息队列组成(消息队列先进先出)

   微队列:   优先级   最高     promise MutationObserver

交互队列:   优先级    高        点击

延迟队列:   优先级   中         计时器
 

目前浏览器我们用到的(事件循环从最高 高 中 以此执行读取)

在执行过程中,一定是先把最高队列的完毕在一次后面的队列

  function addDelay() {console.log('延迟1');setTimeout(() => {console.log('延迟2');}, 100);delay(2000);};function addInteraction() {console.log('交互1');insectDOM.onclick = () => {console.log('交互2');};delay(2000);};startDOM.onclick = function () {addDelay();addInteraction();console.log("============");};// 延迟1 交互1 ============ 交互2 延迟2// console.log('主线程: start')// setTimeout(() => {//     console.log('===== 宏任务 => set1=====')// })// new Promise(function(onfull, onject) {//     onfull(1)//     setTimeout(() => {//         console.log('===== 宏任务 => set2=====')//     })// }).then(res => {//     console.log('+++++ 微任务 => Pro1 +++++')// })// // 异步: 宏任务 => 微任务// setTimeout(() => {//     console.log('===== 宏任务 => set3=====')//     new Promise(onfull => {//         onfull(1)//     }).then(res => {//         console.log('------------宏任务 => set3 : 嵌套 + 微任务-------------')//     })// })// // 异步: 微任务  => 宏任务// new Promise(function(onfull, onject) {//     onfull(1)// }).then(res => {//     setTimeout(() => {//         console.log('------------微任务 => Pro2 : 嵌套 + 宏任务-------------')//     })// })// console.log('主线程: end')

 

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

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

相关文章

【hibernate validator】(二)声明和验证Bean约束

首发博客地址 https://blog.zysicyj.top/ 一、声明bean约束 1. 字段级别约束 不支持静态类型字段 验证引擎直接访问实例变量,不会调用属性的访问器 在验证字节码增强的对象时,应适用属性级别约束,因为字节码增库无法通过反射确定字段访问 pac…

Qt——QPushButton控件的常见属性、方法和信号

Qt中QPushButton控件的常见属性、方法和信号 一、QPushButton控件常见属性 二、QPushButton控件常见方法 三、QPushButton控件常见信号 一、QPushButton控件常见属性(Properties) 1. text: 描述:按钮上显示的文本。 用法: butto…

Python3 字符串

Python3 字符串 字符串是 Python 中最常用的数据类型。我们可以使用引号( 或 " )来创建字符串。 创建字符串很简单,只要为变量分配一个值即可。例如: var1 Hello World! var2 "Runoob" Python 访问字符串中的值 Python 不支持单字…

树莓派4B上安装Gitlab

参考连接: 树莓派上使用 GitLab 搭建专业 Git 服务 | 树莓派实验室 gitlab reconfigure 卡住 ruby_block[wait for redis service socket] action run_芹菜学长的博客-CSDN博客 以及用到了讯飞星火 系统版本信息 1.进入 giblab安装页面gitlab/gitlab-ce - Instal…

2023java面试深入探析Nginx的处理流程

推荐阅读 AI文本 OCR识别最佳实践 AI Gamma一键生成PPT工具直达链接 玩转cloud Studio 在线编码神器 玩转 GPU AI绘画、AI讲话、翻译,GPU点亮AI想象空间 资源分享 史上最全文档AI绘画stablediffusion资料分享 「java、python面试题」来自UC网盘app分享,打开手…

【深入探索Docker】:开启容器化时代的技术奇迹

深入探索Docker 深入探索Docker:开启容器化时代的技术奇迹前言1. 容器化:实现快速部署和可移植性2. 虚拟化:提高安全性和可靠性3. 映像:打包应用及依赖项的模板4. 网络管理:连接容器和主机5. 持久化数据:保…

软考:中级软件设计师:无线网,网络接入技术,ipv6

软考:中级软件设计师:无线网 提示:系列被面试官问的问题,我自己当时不会,所以下来自己复盘一下,认真学习和总结,以应对未来更多的可能性 关于互联网大厂的笔试面试,都是需要细心准备的 &#x…

Vue:插槽,与自定义事件

1.插槽slot <!DOCTYPE html> <html lang"en"> <head><meta charset"UTF-8"><title>Title</title> </head> <body> <div id"app"><!-- <p>列表书籍</p>--> <!-- …

重新认识Android中的线程

线程的几种创建方式 new Thread&#xff1a;可复写Thread#run方法。也可以传递Runnable对象&#xff0c;更加灵活。缺点&#xff1a;缺乏统一管理&#xff0c;可能无限制新建线程&#xff0c;相互之间竞争&#xff0c;及可能占用过多系统的资源导致死机或oom。 new Thread(new…

什么是 API ?

一、API 的定义&#xff1a;数据共享模式定义 4 大种类 作为互联网从业人员&#xff0c;API 这个词我耳朵都听起茧子了&#xff0c;那么 API 究竟是什么呢&#xff1f; API 即应用程序接口&#xff08;API&#xff1a;Application Program Interface&#xff09;&#xff0c;…

Linux(基础IO、文件权限、Makefile)

目录 1、man 手册 1.1 汉化 1.2 具体使用 2、文件权限 2.1 权限理解 2.2 文件详细信息查询 2.3 权限更改 3、常用函数接口 3.1 open 3.2 read 3.3 write 3.4 close 3.5 函数使用示例 4、make与Makefile 4.1 make 与 Makefile区别 4.2 Makefile的编写 5、vim简…

阿里云服务器搭建FRP实现内网穿透-P2P

前言 在了解frp - p2p之前&#xff0c;请先了解阿里云服务器搭建FRP实现内网穿透-转发: 文章地址 1、什么是frp - p2p frp&#xff08;Fast Reverse Proxy&#xff09;是一个开源的反向代理工具&#xff0c;它提供了多种功能&#xff0c;包括端口映射、流量转发和内网穿透等。…

归并排序之从微观看递归

前言 这次&#xff0c;并不是具体讨论归并排序算法&#xff0c;而是利用归并排序算法&#xff0c;探讨一下递归。归并排序的特点在于连续使用了两次递归调用&#xff0c;这次我们将从微观上观察递归全过程&#xff0c;从本质上理解递归&#xff0c;如果能看完&#xff0c;你一…

Wlan——STA上线流程与802.11MAC帧讲解以及报文转发路径

目录 802.11MAC帧基本概念 802.11帧结构 802.11MAC帧的分类 管理帧 控制帧 数据帧 STA接入无线网络流程 信号扫描—管理帧 链路认证—管理帧 用户关联—管理帧 用户上线 不同802.11帧的转发路径 802.11MAC帧基本概念 802.11协议在802家族中的角色位置 其中802.3标…

搭建开发环境-Windows

写C# 的请出去。 然后&#xff0c;Windows 是最好的Linux发行版。搭建开发环境-WSLUbuntu

【Git Bash】简明从零教学

目录 Git 的作用官网介绍简明概要 Git 下载链接Git 的初始配置配置用户初始化本地库 Git 状态查询Git 工作机制本地工作机制远端工作机制 Git 的本地管理操作add 将修改添加至暂存区commit 将暂存区提交至本地仓库日志查询版本穿梭 Git 分支查看分支创建与切换分支跨分支修改与…

Redisi缓存的击穿、穿透、雪崩,介绍一下

缓存击穿 缓存击穿是指在高并发场景下&#xff0c;缓存中的某个 key 失效&#xff0c;此时大量请求同时涌入数据库查询该 key 的数据&#xff0c;导致数据库瞬间压力过大&#xff0c;甚至宕机。缓存击穿的最佳解决方案是使用互斥锁&#xff0c;令只有一个线程可以从数据库中查…

leetcode500. 键盘行

【简单题】 给你一个字符串数组 words &#xff0c;只返回可以使用在 美式键盘 同一行的字母打印出来的单词。键盘如下图所示。 美式键盘 中&#xff1a; 第一行由字符 "qwertyuiop" 组成。第二行由字符 "asdfghjkl" 组成。第三行由字符 "zxcvbnm&…

React 面试题集锦

目录 如果想要在组件第一次加载后获取该组件的dom元素&#xff0c;应当在以下哪个生命周期中进行 React支持的键盘事件是 使用严格模式&#xff08;Strict Mode&#xff09;优点 React 动态引入组件 当使用ReactDOM.unmountComponentAtNode从DOM中卸载组件时 说一下useS…

Nacos集群

需要与Nginx配合。 这是使用三个Nacos来搭建集群。 创建mysql数据库nacos。 配置Nacos 进入nacos的conf目录&#xff0c;修改配置文件cluster.conf.example&#xff0c;重命名为cluster.conf。 在cluster.conf文件的最后加上&#xff1a; #it is ip #example 127.0.0.1:8…