Babel-runtime 与 Core-js 的性能比较

阅读时长 7 分钟读完

在前端开发领域,为了兼容新旧浏览器,我们经常需要将 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.promisecore-js/modules/es.object.to-stringcore-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

纠错
反馈