浏览器工作原理与实践
李兵
前盛大创新院高级研究员
立即订阅
6207 人已学习
课程目录
已完结 42 讲
0/4登录后,你可以任选4讲全文学习。
开篇词 (1讲)
开篇词 | 参透了浏览器的工作原理,你就能解决80%的前端难题
免费
宏观视角下的浏览器 (6讲)
01 | Chrome架构:仅仅打开了1个页面,为什么有4个进程?
02 | TCP协议:如何保证页面文件能被完整送达浏览器?
03 | HTTP请求流程:为什么很多站点第二次打开速度会很快?
04 | 导航流程:从输入URL到页面展示,这中间发生了什么?
05 | 渲染流程(上):HTML、CSS和JavaScript,是如何变成页面的?
06 | 渲染流程(下):HTML、CSS和JavaScript,是如何变成页面的?
浏览器中的JavaScript执行机制 (5讲)
07 | 变量提升:JavaScript代码是按顺序执行的吗?
08 | 调用栈:为什么JavaScript代码会出现栈溢出?
09 | 块级作用域:var缺陷以及为什么要引入let和const?
10 | 作用域链和闭包 :代码中出现相同的变量,JavaScript引擎是如何选择的?
11 | this:从JavaScript执行上下文的视角讲清楚this
V8工作原理 (3讲)
12 | 栈空间和堆空间:数据是如何存储的?
13 | 垃圾回收:垃圾数据是如何自动回收的?
14 | 编译器和解释器:V8是如何执行一段JavaScript代码的?
浏览器中的页面循环系统 (6讲)
15 | 消息队列和事件循环:页面是怎么“活”起来的?
16 | WebAPI:setTimeout是如何实现的?
17 | WebAPI:XMLHttpRequest是怎么实现的?
18 | 宏任务和微任务:不是所有任务都是一个待遇
19 | Promise:使用Promise,告别回调函数
20 | async/await:使用同步的方式去写异步代码
浏览器中的页面 (8讲)
21 | Chrome开发者工具:利用网络面板做性能分析
22 | DOM树:JavaScript是如何影响DOM树构建的?
23 | 渲染流水线:CSS如何影响首次加载时的白屏时间?
24 | 分层和合成机制:为什么CSS动画比JavaScript高效?
25 | 页面性能:如何系统地优化页面?
26 | 虚拟DOM:虚拟DOM和实际的DOM有何不同?
27 | 渐进式网页应用(PWA):它究竟解决了Web应用的哪些问题?
28 | WebComponent:像搭积木一样构建Web应用
浏览器中的网络 (3讲)
29 | HTTP/1:HTTP性能优化
30|HTTP/2:如何提升网络速度?
31|HTTP/3:甩掉TCP、TLS 的包袱,构建高效网络
浏览器安全 (5讲)
32 | 同源策略:为什么XMLHttpRequest不能跨域请求资源?
33 | 跨站脚本攻击(XSS):为什么Cookie中有HttpOnly属性?
34 | CSRF攻击:陌生链接不要随便点
35 | 安全沙箱:页面和系统之间的隔离墙
36 | HTTPS:让数据传输更安全
结束语 (1讲)
结束语 | 大道至简
课外加餐 (4讲)
加餐一|浏览上下文组:如何计算Chrome中渲染进程的个数?
加餐二|任务调度:有了setTimeOut,为什么还要使用rAF?
加餐三|加载阶段性能:使用Audits来优化Web性能
加餐四|页面性能工具:如何使用Performance?
浏览器工作原理与实践
登录|注册

加餐二|任务调度:有了setTimeOut,为什么还要使用rAF?

李兵 2019-11-26
你好,我是李兵。
我们都知道,要想利用 JavaScript 实现高性能的动画,那就得使用 requestAnimationFrame 这个 API,我们简称 rAF,那么为什么都推荐使用 rAF 而不是 setTimeOut 呢?
要解释清楚这个问题,就要从渲染进程的任务调度系统讲起,理解了渲染进程任务调度系统,你自然就明白了 rAF 和 setTimeOut 的区别。其次,如果你理解任务调度系统,那么你就能将渲染流水线和浏览器系统架构等知识串起来,理解了这些概念也有助于你理解 Performance 标签是如何工作的。
要想了解最新 Chrome 的任务调度系统是怎么工作的,我们得先来回顾下之前介绍的消息循环系统,我们知道了渲染进程内部的大多数任务都是在主线程上执行的,诸如 JavaScript 执行、DOM、CSS、计算布局、V8 的垃圾回收等任务。要让这些任务能够在主线程上有条不紊地运行,就需要引入消息队列。
在前面的《16 | WebAPI:setTimeout 是如何实现的?》这篇文章中,我们还介绍了,主线程维护了一个普通的消息队列和一个延迟消息队列,调度模块会按照规则依次取出这两个消息队列中的任务,并在主线程上执行。为了下文讲述方便,在这里我把普通的消息队列和延迟队列都当成一个消息队列。
取消
完成
0/1000字
划线
笔记
复制
© 版权归极客邦科技所有,未经许可不得传播售卖。 页面已增加防盗追踪,如有侵权极客邦将依法追究其法律责任。
该试读文章来自付费专栏《浏览器工作原理与实践》,如需阅读全部文章,
请订阅文章所属专栏。
立即订阅
登录 后留言

精选留言(6)

  • 木瓜777
    window.requestAnimationFrame 应该是在每一帧的开始就执行吧?

    作者回复: 应该说raf的回调任务会在每一帧的开始执行

    2019-11-29
    2
  • 猫叔
    老师,通过window.postMessage 发送的消息执行回调也是在空闲时间内执行的吗。因为我看到react框架为了模拟兼容requestIdleCallback。使用了postMessage
    2019-12-04
    1
  • Geek_0d3179
    老师您好~ 在网上搜了一大圈之后还是存在疑惑,非常希望您的解惑~十分感谢!
    1、我了解到event loop的流程是:一个macrotask >> UI 渲染 >> 任务队列取下一个macrotask
    疑问:每执行一个macrotask后面一定会UI 渲染吗?如果此时DOM和样式并没有改变,根本不需要重新渲染呢?也就是根本不需要回流、重绘和合成。
    2、听了老师的讲解后,得知渲染进程在每一帧时间里都会重新绘制,合成一帧图片推到后缓冲区,就算UI没有变化也会执行吗?那这个执行的时机是?是得到VSync信号的时候吗?那这是作为一个宏任务执行的吗?
    3、我并没有搞清楚上面1和2的关系。也就是event loop 和 一帧时间的关系。我的理解:在一帧的时间里会不断的从任务队列中取出任务执行,那如果任务队列有太多任务,“重新绘制一帧推到后缓冲区”这个操作会被延迟吗?
    2019-12-03
    1
  • gigot
    老师,我想问下在 primose.then 中执行宏任务(setTimeout或 ajax),其中该宏任务应该加入哪个事件队列。
    是说微任务队列都是按顺序执行,其中每个微任务又有新的事件循环(包括宏任务和微任务),类似于新得全局环境,这样理解对吗

    作者回复: 不管在哪里请求setTimeout,它的回调函数都是在宏任务中执行的。

    不过在微任务中产生了新的微任务,新的微任务还是在当前的微任务队列中,所以如果在微任务中不停产生新的微任务,是会阻塞页面的!

    2019-11-29
    1
    1
  • Geek_0d3179
    如果raf的回调任务会在每一帧的开始执行,如果它执行时间很长(超过一帧),那就会阻碍后面所有任务的执行么?比如说用户的交互事件等高优先级任务也会受到影响导致卡顿么?
    我在网上看到的资料:为啥是先执行用户的交互任务,在执行raf的回调???

    作者回复: 会啊,一个任务在执行的时候是不会被中断的,即使有再高优先级的任务,都需要等到当前dr任务执行结束,所以如果raf回调函数中的代码过于耗时的话,那么会影响渲染帧率!

    等当前任务执行结束循环系统才会挑下个选优先级高的任务执行,因为用户输入的有限级高于raf的回调,所以会优先执行用户输入!


    2019-12-03
  • 王博
    觉得老师的绘图工具挺好的,老师可以推荐一下吗?谢谢

    作者回复: keynote啊

    2019-11-26
    1
收起评论
6
返回
顶部