从浏览器控制台看事件循环&渲染更新

413 阅读1分钟

从浏览器 performence面板下的 Main线程 看事件循环:

每一个 task 分隔开看, 从上向下看, 对应代码的从外到里

  • 其实看这个图, 只有宏任务(task)这一种东西
  • 你看宏任务(task)的线, 贯穿了 function call 调用栈run microtask 微任务 的整个周期
  • js调用栈和微任务, 都是宏任务下的子任务,先执行function call 调用栈, 再执行run microtask 微任务

wecom-temp-c9bf9d0f7eb5cf9785a626bd4b88426c.png

当事件循环遇到渲染更新:

  • task 之间不一定会有渲染(Composite Layers), 渲染有自己的调度, 不繁忙时,大约20ms, 忙的时候会延后
  • call Function 遇到第一个 setTimeout 时, 这个 setTimeout 一定会在浏览器渲染之后执行,
  • 当有多个 setTimeout
  • 当某个 setTimeout 的执行间隔(20ms)小于某一个值x时, 两个 setTimeouttask 中间无渲染
  • 当某个 setTimeout 的执行间隔(30ms)大于等于某一个值x时, 两个 setTimeouttask 中间有渲染
  fnaaa() {
    console.log('fn')
    this.buttonType = ''
    setTimeout(
      function setTimeout1() {
        console.log('setTimeout1', this)
        this.buttonType = 'success'
      }.bind(this),
      0
    )
    setTimeout(
      function setTimeout2() {
        console.log('setTimeout2', this)
        this.buttonType = 'info'
      }.bind(this),
      20
    )
  }

不繁忙时,大约20ms渲染一次 wecom-temp-6f82b67dbc91aa56cf8b196f210b06f3.png

繁忙时,延期

[965ms,1005ms] wecom-temp-c8c244c39dea1666b4541eaa77300185.png

当某个setTimeout的执行间隔(20ms)小于某一个值x时, 两个 setTimeout 的task 中间无渲染 image.png

当某个setTimeout的执行间隔(30ms)大于等于某一个值x时, 两个 setTimeout 的task 中间有渲染 image.png

x 是多少?

x 是屏幕的刷新间隔吗?

如果是, 那么我的屏幕刷新率是每秒 60 帧吗?

如果是, 1000 / 60 = 16.666...

那么 x = 20