浏览器原理
学习浏览器原理对于我们开发是很有必要的 我们可以了解到浏览器内部工作原理对自己的代码进行优化
进程线程
首先了解进程和线程
 进程就就是内存在正在进行的应用程序 在内存中独占一个内存空间 并且进程之间是隔离的 可以看到每个应用都有一个进程 占用空间内存 那这块空间内存就可以理解为进程
 
 线程
 线程是进程最小的执行单位 一个进程至少有一个线程 进程开启后会创建一个线程运行代码 如果程序同时执行多块代码 主线程就会启动更多线程执行代码
 一个进程可以有多个线程 进程大于线程
 打开浏览器之后最少开启了四个进程
 1 浏览器主进程 主要显示 页面展示 用户交互 子进程管理 提供储存等等
 2 渲染进程 核心任务是将html css javascript变成用户可以交互的网页
 Chrome为每个tab页创建了一个渲染进程
 3 网络 负责网络资源请求
 4 插件进程 负责插件运行 因为插件容易崩溃
事件循环
知道了线程进程的概念 下面我们可以看一下事件循环
1 会开启一个渲染进程
执行html css js 代码 保证页签不受影响
2 浏览器内部任务是排队的
1 最开始的时候 渲染主线程的时候会开启一个无限循环
 2 每次循环的时候会检查消息队列中是否有任务 有的话就取出第一个任务 取出第一个任务执行 执行完一个后进入下一次循环 如果没有则进入休眠状态
 3 其他所有线程(包括其他进程的线程)可以随时向消息队列中添加任务 任务会加到消息队列的末尾 添加新任务的时候 如果主线程是休眠状态 则会继续唤醒循环拿取任务
异步
什么是异步任务 ? 代码执行无法立即处理的任务
 
 如果定时器是同步的
 
 则会阻塞线程 所以解决方案是 当计时结束的时候将回调函数放到消息队列的队尾
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
</head>
<body>
    <h1>哈哈哈</h1>
    <button>点击我</button>
    <script>
        var h1=document.querySelector('h1')
        var btn=document.querySelector('button')
        function delay(duration){
            var star=Date.now();
            while(Date.now()-star<duration){}
        }
        btn.onclick=function(){
            h1.textContent="666"
            //3m后重新绘制
            delay(3000)
        }
    </script>
</body>
</html>
 
任务的优先级
刚刚说了任务是在线程中排队的 其中异步任务是结束的时候回调将任务放到队尾排队
 任务是没有优先级的 但消息队列中优先级 同一个类型任务必须在一个任务队列 在一次事件循环中可以取出不同的队列执行任务
 览器必须有个微队列 优先于其他所有任务执行
 
 
 例子
 同时等待一秒钟 然后执行2在执行1
 例子
 先执行全局的3 然后执行微队列中的2 在执行延时队列中的1
<script>
         setTimeout(()=>{
            console.log(1);
         },0)
         Promise.resolve().then((function(){
            console.log(2);
         }))
         console.log(3);
         //3 2 1
    </script>
 
例子
 先执行3 在执行2 然后继续执行微队列中的12888 在执行1
<script>
         setTimeout(()=>{
            console.log(1);
         },0)
         Promise.resolve()
         .then((function(){
            console.log(2);
         }))
         .then(()=>{
            console.log(12888);
         })
         console.log(3);
         //3 2 1288 1
    </script>
 
例子
 执行全局的5 在执行微任务4 在执行3 将a推入微任务队列 执行1 继续将function推入微任务队列 2
<script>
       function a(){
        console.log(1);
        Promise.resolve().then(function(){
            console.log(2);
        })
       }
       setTimeout(()=>{
        console.log(3);
        Promise.resolve().then((a))
       },0)
       Promise.resolve().then(()=>{
        console.log(4);
       })
       console.log(5);
       //5 4  3 1 2 
    </script>
 
问答
面试题:如何理解 JS 的异步?
 参考答案:
 JS是一门单线程的语言,这是因为它运行在浏览器的渲染主线程中,而渲染主线程只有一个。
 而渲染主线程承担着诸多的工作,渲染页面、执行 JS 都在其中运行。
 如果使用同步的方式,就极有可能导致主线程产生阻塞,从而导致消息队列中的很多其他任务无法得到执行。
 这样一来,一方面会导致繁忙的主线程白白的消耗时间,另一方面导致页面无法及时更新给用户造成本死现象。
 所以浏览器采用异步的方式来避免。具体做法是当某些任务发生时,比如计时器、网络、事件监听,主线程将任务交给其他线程去处理,自身立即结束任务的执行,转而执行后续代码。当其他线程完成时,将事先传递的回调函数包装成任务,加入到消息队列的末尾排队,等待主线程调度执行。
 在这种异步模式下,浏览器永不阻塞,从而最大限度的保证了单线程的流畅运行。
 阐述一下 JS 的事件循环
 参考答案:
 事件循环又叫做消息循环,是浏览器渲染主线程的工作方式。
 在 Chrome 的源码中,它开启一个不会结束的 for 循环,每次循环从消息队列中取出第一个任务执行,而其他线程只需要在合适的时候将任务加入到队列末尾即可。
 过去把消息队列简单分为宏队列和微队列,这种说法目前已无法满足复杂的浏览器环境,取而代之的是一种更加灵活多变的处理方式。
 根据 W3C 官方的解释,每个任务有不同的类型,同类型的任务必须在同一个队列,不同的任务可以属于不同的队列。不同任务队列有不同的优先级,在一次事件循环中,由浏览器自行决定取哪一个队列的任务。但浏览器必须有一个微队列,微队列的任务一定具有最高的优先级,必须优先调度执行。
总结
之前是说宏任务微任务 但最新版改成了微任务队列 更加好理解了
 下周还是把剩余的知识点学完准备收拾收拾写项目了

















