在前端开发领域,为了兼容新旧浏览器,我们经常需要将 ES6+ 的语法转换为 ES5 可执行代码。而 Babel 是当前最流行的 JavaScript 编译工具之一,它提供了一个 runtime 库和插件系统来实现这个目标。在 Babel 的插件系统中,我们经常会用到两个库: Babel-runtime 和 Core-js。本篇文章将对这两个库进行性能比较,分析它们的优劣和应用场景。
Babel-runtime
Babel-runtime 是 Babel 官方推荐使用的 runtime 库。它是一个低级别的库,提供了对一些新的语法的实现,例如 Generator 和 Promise,在转换的代码中会直接引用这些实现库。
-- ------------ ----- -------- ------ - ----- --- --------------- -- ------------------- ------- ------------------- --------- - -------
经过 Babel 转译后,代码如下所示:
-- ------------ --- --------------- - ----------------------------------------------------- --- ----------------- - ------------------------------------------------------- --- -------- - ---------------------------------------------- -------- ------ - ------ ----------------- ----------- - -------- ------- - ----- - -------------------- --------- ---------------------------------- --------- - ------ -------------------------------- ------------------ - ----- --- - ------ -------------- - -------------- - ---- -- ------------- - -- ------ --- -------- --------- --------- - ------ ------------------- ------ --- ---- -- ------------------- --------- ---- -- ---- ------ ------ ---------------- - - -- --------- ---- ------ ----------------- ----------- - -------
可以看到,在 Babel 转换后的代码中,我们引用了一些 Babel-runtime 的模块,例如 @babel/runtime/helpers/esm/classCallCheck
、@babel/runtime/helpers/esm/asyncToGenerator
和 @babel/runtime/helpers/esm/promise
。
Babel-runtime 与 Babel 一起使用时,它可以优化编译出的 ECMAScript 代码,但它会在你的项目引入一些额外的运行时依赖。因为 Babel-runtime 中包含了 ES6+ 语法的小部分实现,所以相应的实现函数将运行时注入到你的代码中。这样一来,就必须将 Babel-runtime 添加到应用程序的依赖链中。
然而,对于一些旧浏览器来说,Babel-runtime 会增加代码包的大小,并导致运行速度变慢。而且,每次运行时调用都会产生额外开销。
Core-js
Core-js 与 Babel-runtime 不同,它不是为特定的编译器设计的,它只存储了各种 JavaScript 语法的 polyfill,它与运行环境无关,因此更灵活,可以跨多个浏览器和环境使用,也可以在任意 Web 应用或命令行下使用。
Core-js 提供了大量的 polyfill,涵盖了从 ES3 到 ES2021 的所有 JS 标准,几乎覆盖了所有你用到的 JavaScript 语法。你的项目只需要添加需要的 polyfill 就可以了,从而减少包的大小。
使用 Core-js,我们可以将上面的例子改成这样:
-- ------------ ------ ----------------------------- ------ -------------------------------------- ------ ------------------------------------- ----- -------- ------ - ----- --- --------------- -- ------------------- ------- ------------------- --------- - -------
这样,在运行时调用时,必须首先加载系统的 polyfill,然后引入了自己的应用程序代码,再次运行时就允许该代码使用自己的 polyfill 运行。
在上面的示例中,我们只添加了 core-js/modules/es.promise
、core-js/modules/es.object.to-string
和 core-js/modules/es.promise.finally
这三个 polyfill。它们都是 Promise 相关的 polyfill ,只是添加了最基本的支持实现。
通过这种方式,我们可以很方便地自定义项目所需的 polyfill,并且可以更好地控制依赖和打包大小。
性能比较
下面是一个简单的性能基准测试,我们通过命令行分别构建 Babel-runtime 和 Core-js,然后跑一遍基准测试。
-- ------------ -------- ------ - ----- --- - ------------------------------- ------ --------- -- - - ---------------- ----- -- ---- - ------ - ------------------------------ ------- --------------------------------- ------------------------ ------- ---------------------------
运行上面的代码后,终端输出的结果如下:
-------------- ------- -------- -------
可以看到,Babel-runtime 的执行速度更快。这是因为 Babel-runtime 相对于 Core-js 有更多的 JIT 优化,如果使用了多个不同的 ES6+ 语言特性,则使用 Babel-runtime 可以更加快速地执行。
但是,在实际应用中,我们应该考虑到使用 Babel-runtime 会增加 bundle 大小,而使用 Core-js 可以大幅度减少 bundle 大小。因此,如果我们的应用程序已经占用了大量的代码空间,或者已经使用了许多 polyfill,那么使用 Core-js 是一个明智的选择。
此外,如果你需要更精细的控制,可以使用 @babel/preset-env 对你的代码进行优化。例如,你可以在 @babel/preset-env 中指定需要支持的版本号,并根据需要在代码中引入对应的 polyfill。
结论
总而言之,Babel-runtime 适合规模较小的项目和偏重性能的项目。在大型项目中,使用 Core-js 可以减少打包大小,提高首屏加载速度。根据项目的特点和需求,选择合适的方案可以使您的应用程序更加高效。
来源:JavaScript中文网 ,转载请注明来源 本文地址:https://www.javascriptcn.com/post/671c4ae09babaf620fb014d2