@@ -18,7 +18,7 @@ tags: []
1818
1919说渲染进程之前可能有些人都不知道进程是什么!例如我,其实我们可以简单理解进程为:为「程序运行」分配的「内存空间」。打个比方,苹果手机的生产,生产出一部苹果手机的步骤就是程序,生产它需要的富士康工厂就是内存空间。那在游览器中程序工作也就需要为程序分配一个单独的空间,下面我们继续了解一下进程的特点,
2020- 每个程序(应用)至少有一个进程
21- - 进程可以有多个,进程之前相互独立 ,如果需要通信需要双方同意
21+ - 进程可以有多个,进程之间相互独立 ,如果需要通信需要双方同意
2222- 每个进程是隔离的,一个进程崩溃了,不会影响其他的进程
2323
2424那渲染进程其实就是进程的一个实例,它继承进程的所有特点,渲染进程是也就是游览器三大进程之一,下面我们看一下游览器中的三个重要进程:
@@ -27,9 +27,10 @@ tags: []
27273)渲染进程:开启一个渲染主线程,主线程负责执行 HTML、CSS、JS
2828
2929## 渲染主线程
30- 渲染进程默认就是生成一个渲染主线程。肯定有小伙伴会不知道什么是线程?那个人还是我,线程简单理解为:运行程序代码的「东西」就是「线程」。刚刚举例中苹果手机的生产,在富士康(进程)中有很多生产线,例如生产摄像头的,生产屏幕的,那这每一条生产线就是一个线程。一个进程至少会有一个线程(主线程,也就是跟随进程启动的时候产生的线程),这里是因为内存空间是宝贵的,如果没有线程,内存空间(也就是进程)就会被释放。
3130
32- 进程和线程的关系:一个进程可以有多个线程,线程运行在进程中,同一进程内的线程共享进程的内存空间和资源,对了,同一进程中的线程可以并发执行(这在后面有用)
31+ 渲染进程默认就是生成一个渲染主线程。肯定有小伙伴会不知道什么是线程?那个人还是我,线程简单理解为:运行程序代码的「东西」就是「线程」。继续说苹果手机的生产,在富士康(进程)中有很多生产线,例如生产摄像头的,生产屏幕的,那这每一条生产线就是一个线程。一个进程至少会有一个线程(主线程,也就是跟随进程启动的时候产生的线程),这里是因为内存空间是宝贵的,如果没有线程,内存空间(也就是进程)就会被释放。
32+
33+ 进程和线程的关系:一个进程可以有多个线程,线程运行在进程中,同一进程内的线程共享进程的内存空间和资源,哦对了,同一进程中的线程可以并发执行(这在后面有用)
3334
3435## 为什么渲染进程只有一个主线程 ? 渲染主线程要做哪些事情?
3536
@@ -45,19 +46,19 @@ tags: []
4546- 执行计时器的回调函数
4647- 。。。。
4748
48- 那为什么渲染进程不适用多个线程来处理这么多的事情?而是全部交给渲染主线程?其主要原因 :
49+ 那为什么渲染进程不适用多个线程来处理这么多的事情?而是全部交给渲染主线程?其主要原因是 :
49501 . JavaScript是单线程,如果开启多个线程,我们知道线程是可以并发执行的,那就需要处理复杂的线程同步问题
50- 2 . 还可能出现多个线程同时操作 DOM 导致的竞态条件
51+ 2 . 可能会出现多个线程同时操作 DOM 导致的竞态条件
51523 . 一致性问题,如:dom 操作循序性和原子性、JavaScript 代码执行顺序
5253
53- 那现在知道了为什么就使用一个渲染主线程来处理这么多任务。那为什么单线程在处理同步 ,异步非常复杂的程序时,页面依然不卡呢?是的,主角要登场了,也就是我们强大的事件循环机制,通过它,让我们游览器主线程永不阻塞
54+ 那现在知道了为什么使用一个渲染主线程来处理这么多任务。那为什么就一个单线程在处理同步 ,异步非常复杂的程序时,页面依然不卡呢?是的,主角要登场了,也就是我们强大的事件循环机制,通过它,让我们游览器主线程永不阻塞
5455
5556## 事件循环机制
5657下面我们来看一下渲染主线程是如何工作的,也就是事件循环机制到底是什么!
5758
5859最开始,渲染主线程会进入无限循环
5960每次循环都会去消息队列(message queue)查看是否有任务,有任务会执行任务,没有任务进入休眠
60- 其他线程可以随时向消息队列添加任务(加入到队列末尾),如果新任务加入时渲染主线程在休眠,就会被唤醒
61+ 其他线程可以随时向消息队列添加任务(加入到队列末尾),如果新任务加入时渲染主线程在休眠,就渲染主线程会被唤醒
6162在执行任务的时候,其实任务可能会产生新的任务,这里可能不太好理解,我举个例子:
6263``` js
6364setTimeout (function () {
@@ -68,15 +69,15 @@ setTimeout(function () {
6869}, 1000 );
6970console .log (1 )
7071```
71- 运行这段代码,发现是要创建定时器,那一个异步的任务 ,这时候它就会通知计时线程,把异步的任务交给其他线程来做,自己继续执行下面的代码打印一个 1 ,当 1 秒过后,计时线程会把计时器回调函数加入到消息队列中,然后游览器主线程会依次执行消息队列中的任务
72+ 运行这段代码,发现是要创建定时器,是一个异步的任务 ,这时候它就会通知计时线程,把异步的任务交给其他线程来做,自己继续执行下面的代码打印一个 1 ,当 1 秒过后,计时线程会把计时器回调函数加入到消息队列中,然后游览器主线程会依次执行消息队列中的任务
7273
73- 肯定有聪明的小伙伴会问,任务有优先级吗?任务是按照什么顺序执行的呢?其实任务是没有优先级的,但是每一个任务都有一个任务类型 ,同一种任务类型的任务都在一个队列,不同任务类型可以分属于不同的队列(潜台词:不同的任务类型,可以在同一个队列)这里的队列指的就是消息队列,每错就是渲染主线程获取任务的那个消息队列。不同的消息队列是有优先级的,在 W3C 的规范中规定,游览器必须有一个微队列(microtask queue)微队列任务优先于所有其他任务队列。
74+ 肯定有聪明的小伙伴会问,任务有优先级吗?任务是按照什么顺序执行的呢?其实 ** 任务是没有优先级 ** 的,但是每一个任务都有一个 ** 任务类型 ** ,同一种任务类型的任务都在一个队列,不同任务类型可以分属于不同的队列(潜台词:不同的任务类型,可以在同一个队列)这里的队列指的就是消息队列,每错就是渲染主线程获取任务的那个消息队列。** 不同的消息队列是有优先级的** ,在 W3C 的规范中规定,** 游览器必须有一个微队列(microtask queue)微队列任务优先于所有其他任务队列** 。
7475
7576我们所说的微任务就是在微队列中,宏任务现在就是在其他队列中
7677
7778渲染主线程通过异步的方式,实现了它自己永远都在执行同步任务,异步任务都交给其他线程来处理,其他线程处理好了再加入到消息队列中,渲染主进程通过不断执行消息队列的任务方式保证自己执行超多任务也不卡,给大家画一个渲染主线程工作图:
7879![ eventloop] ( https://blog-1304565468.cos.ap-shanghai.myqcloud.com/work/eventloop.png )
79- 我们看一下这段代码 ,来更加深入了解事件循环机制
80+ 我们看一下这段代码结合上面的图 ,来更加深入了解事件循环机制
8081``` js
8182function delay (ms ) {
8283 var start = Date .now ();
0 commit comments