11月22, 2018

TPAC 2018 主线程任务调度API

这是在TPAC2018,性能组的一个提案(slidesexplainer

概述

主线程上的任务调度。为Map scheduler或者react-scheduler这些自研的调度API提供一些主线程上的剩余时间的信息。或者由平台来实现scheduler的run-loop。

场景:

即时的输入与搜索

要求:

  1. 响应input要快
  2. 页面动画要流畅
  3. fetch搜索结果要快
  4. 准备搜索结果要快
  5. 更新页面要快

这些都是运行在主线程上的。如何同时保证响应速度,渲染动画和更新搜索结果的速度?

期望:

将主线程上的工作按照优先级有条理地安排好。

需要一个“小秘书”(scheduler)来安排不同优先级的任务。一个合格的“小秘书”需要满足以下条件:

  • 按照优先级安排任务

    应用交给小秘书去(异步)执行的任务。任务有指定的优先级,可以事先决定一些优先级

  • 将任务分组,放到“虚拟”任务队列。应用可以:

    • 对一个组动态更新优先级或者删除
    • 在用户跳转的时候可以同步运行任务队列中的任务(flush)
  • 提交任务的API(指定优先级)

  • 循环运行(run-loop)

    在合适的时间执行任务。问题来了,有效的循环运行需要什么东西?

    需要了解:

    • 渲染:下一帧的时机、当前帧还剩多少余量
    • 输入:有没有未处理的输入、距离输入被处理前还留有多少时间
    • 是否在加载、导航等(包括SPA的)

    需要跟主线程上的其他任务协作:

    • fetch、网络响应
    • 浏览器内置的回调:xhr的onreadystatechange、worker的post-message
    • 浏览器内部工作:GC
    • 渲染:要根据render的状态重新安排小秘书的任务的优先级
    • 开发者安排的其他回调:settimeout

方案:

A:浏览器实现run-loop。无法妥当地实现与其他任务协作。无法暴露优先级。

B:JS库实现run-loop。所以浏览器要暴露shouldYield。缺点:很难实现跟其他任务协作,比方案A更严重的互操作问题。

本文链接:http://imhxl.com/post/main-thread-scheduling-api.html

-- EOF --

Comments