BlinkOn9 - Layered APIs

作者在 4 月 18~19 期间和同事一起在湾区参加了为其两天的 BlinkOn 9 会议。每次 BlinkOn 都是了解当前 Blink & Chrome 和 Web 技术演进现状和发展方向的一个不错机会,两天的会议下来大概听了 6 ~ 7 场分享,有些主题是之前已经有所了解,这次又更新了最新的进展信息;有些主题则是完全陌生,在这次 BlinkOn 上才第一次知悉。作者接下来会撰写一系列文章,每篇文章针对一个特定的主题,尽可能把相关的信息回馈给读者。


对于 Layered APIs 作者事前并没有了解,不过听了BlinkOn9 的分享后觉得这个概念还挺有意思的,如果真的能够实现构建一个跨浏览器通用的标准库,覆盖 Web 开发的主要需求,对 Web 开发者而言当然是极大的利好。

Layerd APIs 提出的一些背景


提出 Layered APIs 这个概念的背景,跟可扩展的 Web 宣言有关,可扩展的 Web 宣言提出了可扩展的 Web 平台演进的一些设计准则 —— 更聚焦于提供 low level primitives API,更多暴露引擎底层的能力来赋能开发者,使得引擎的开发和维护成本更低,从而更聚焦于安全和性能,让 Web 技术的演进也更快。


SharedArrayBuffer and Atomics,还有 Houdini 项目里面的 CSS Paint API,CSS Layout API 就是遵循这些设计准则的很好例子。


如果把浏览器引擎类比于操作系统,这些所谓的 primitives API 差不多就类似于操作系统的基础 API,通常会比较难以学习和使用,所以它们更多是面向库或者框架的开发者,也意味着普通的 Web 开发者需要选择第三方提供良好封装,更容易使用的库或者框架。但是不同的库提供的 high level API 设计可能并不相同,使用上又各有其优缺点,性能,稳定性,兼容性表现上可能也有缺陷,Web 开发者不得不增加很多库的学习,使用,对比选择,甚至自己完善其实现的成本。

Layered APIs vs 第三方库


Layered APIs 与第三方库相同的地方在于:

  1. 它们都基于 JavaScript 实现;
  2. 都使用了同样的 primitives API,Layered APIs 不会使用特定的私有 API;
  3. 使用前需要显式加载到当前的运行环境,Layered APIs 不会做成默认内置;


起码 Chromium 目前的设计原则是这样的,但是其它 Browser Vendor 理论上并不受这个约束,它们可以自由选择是否使用 native 的实现。


Layered APIs 与第三方库不同的地方在于:

  1. Layered APIs 可能有很多不同的实现,但是在 API 层面上是一致的(包括签名和行为);
  2. Layered APIs 在 API 的制定上跟其它 Web API 一样,也需要经过相同的标准化流程,在各大 Browser Vendor 和参与讨论的 Web 开发者之间达成一致;
  3. 支持某个特定 Layered API 的浏览器引擎会提供内建的实现,也支持在没有内建实现的情况下 fallback 到外部的实现;
  4. 外部的实现开发者可以自由选择,包括 Browser Vendor 比如 Chromium 提供的开源实现,或者其它第三方的实现,甚至自己的实现;


所以 Layered APIs 的目标是成为 Web 开发的标准库,为主要的功能模块提供标准化的,易于使用的 high level API,跟引擎直接实现的 primitives API 一起构成完整的 Web API 集。它相对于第三方库保证了 API 的一致性,浏览器引擎内建的实现理论上也提供了更好的性能和稳定性,降低了 Web 开发者的学习,使用成本,和 Web 开发的整体成本。并且,如果使用内建实现也意味着减少了网络加载的时间,另外内建实现可以被预编译,也减少了 JavaScript 虚拟机编译的时间。

Layered APIs 的使用

<script type="module"
        src="std:virtual-list|https://some.cdn.com/virtual-list.js">
</script>

<infinite-list>...</infinite-list>

<script type="module">
import { storage } from
         "std:async-local-storage|https://other.cdn.com/als.mjs";

storage.get("key").then(...);
</script>


上面的代码显示如何使用 ES6 的模块加载语法来加载某个特定的 Layered API 模块,额外的语法支持让 fallback 到外部实现变得十分简单。


上述语法还没有最终定案,如果 Web 开发者有更好的建议,也欢迎去提。

Layered APIs 的现状

在 Chromium 内部,Layered API 还处于比较初期的概念验证的阶段。加载的语法大致已经确定,在 Chrome Canary 68 上已经可以使用。开发团队正在进行 virtual list(貌似改成了 virtual scroller) 和 async local storage 的开发,感兴趣的 Web 开发者已经可以尝试去体验。

编辑于 2018-05-18

文章被以下专栏收录