首先先了解一下什么是进程和线程
进程
进程简单来说就是,QQ,微信,王者荣耀三个软件,他们都会有独立的进程,有了进程之后就可以开始干活了,并且进程之间是互不干扰的,不会因为QQ崩溃了而导致微信无法使用,如果想要通信,需要双方同意才可以传递数据
线程
线程就好比,你的老板开了一家公司,把你招聘进来干活,那么老板就是进程,而你就是线程。每个进程都至少要有一个线程,不然的话没人干活呀,所以每次开辟一个进程都会自动生成一个对应的线程。如果程序比较多,比较复杂,进程也可以开辟多个线程同时执行代码
举个例子
- 你进入王者荣耀就会开辟一个内存空间,生成一个进程
- 进程会生成多个线程完成不同的工作
- 主线程负责一些比较复杂的逻辑,控制游戏逻辑和渲染
- 游戏线程比如移动方向,释放技能的一些监听
- 网络线程,你放技能,移动,双方都是同步看到的,这些就是网络线程去完成的
那么浏览器里面有什么进程和线程呢?
1. 浏览器进程
主要负责界⾯显示、⽤户交互、⼦进程管理等。浏览器进程内部会启动多个线程处理不同的任务。
2. ⽹络进程
负责加载⽹络资源。⽹络进程内部会启动多个线程来处理不同的⽹络任务。
3. 渲染进程
渲染进程启动后,会开启⼀个渲染主线程,主线程负责执⾏ HTML、CSS、JS 代码。默认情况下,浏览器会为每个标签⻚开启⼀个新的渲染进程,以保证不同的标签⻚之间不相互影响。
渲染主线程是怎么工作的呢?
渲染主线程就是浏览器中最重要且最繁忙的线程
- 渲染html
- 解析css
- 解析js
- 计算样式
- 布局
- 执行事件处理函数
- . . . . . .
浏览器渲染流程详解: juejin.cn/post/722551…
负责处理这么多任务,还出现了一个难题如何调度任务?
- 当浏览器在执行js代码的时候,用户点击了按钮,那么是继续执行js代码还是执行点击后的逻辑?
- 当计时器时间到了,恰巧用户又点了一下按钮,那么先执行定时器还是点击后的逻辑呢?
event loop (事件循环)
- 渲染主线程会开启一个无限循环,每次取出消息队列中第一个任务执行,直到消息队列为空
- 当有其他任务(定时器的回调,点击事件的函数)则追加到消息队列的末尾,依次执行
什么是异步呢?
我们平时在写代码中也会经常接触到一些无法立即执行的任务
- 定时器 (setTimeout, setInterval)
- 网络请求ajax (XHR, Fetch)
- 绑定点击事件 (onclick, addEventListener)
因为js是一门单线程语言,如果渲染主线程等这些代码执行完再执行下一个任务,渲染主线程长期阻塞,将会导致整个页面卡死,用户体验极差
无法立即执行代码浏览器如何处理的?
- 浏览器使用了异步来解决这个问题
- 当执行js时,渲染主线程遇到了一个定时器,那么会交给一个计时线程,当时间到了,会生成一个任务,追加到消息队列的末尾,等待渲染主线程的调用,如果有多个异步代码,也是使用相同的步骤去执行
- 使⽤异步的⽅式,渲染主线程永不阻塞
那么异步任务有优先级吗?
- 任务是没有优先级的,在消息队列中先进先出
- 但消息队列中是有优先级的
- 在chrome中至少包含以下队列
- 延时队列:⽤于存放计时器到达后的回调任务,优先级「中」
- 交互队列:⽤于存放⽤户操作后产⽣的事件处理任务,优先级「⾼」
- 微队列:⽤户存放需要最快执⾏的任务,优先级「最⾼」
微队列
// 立即把回调函数添加到微队列中
Promise.resolve.then(回调函数)
交互队列
跟用户交互的事件就会进入交互队列
- 鼠标点击事件
- 键盘事件
- 窗口大小改变
- . . . . . .
延迟队列
- setTimeout
- setInterval