发布于 2026-01-05 4 阅读
0

React 应用优化:硬核版

React 应用优化:硬核版

你听说过代码压缩,听说过懒加载,听说过摇树优化,你可能都用过这些优化方法。或者,你真的用过吗?这里有一些你可能从未听说过的优化技巧。直到现在!

启用“松散”转换@babel/preset-env

启用“宽松”转换可以显著缩小应用程序的大小。我的软件包大小减少了大约 230.9 KB,相当于 16.2% !

然而,这样做是有代价的:启用和禁用这些转换时,您的应用程序可能会出现故障。

就我而言,我唯一需要做的修复与遍历HTMLCollectiondocument.querySelectorAll(…)document.getElementsByTagName(…)HTMLFormControlsCollectionform.elements)有关。我不再能够执行例如[...form.elements],我必须将其替换为Array.from(form.elements)

loose仍然对大幅节省的费用心动不已?不妨在 Babel 配置中启用该标志来尝试一下:

babel.config.json

  "presets": [
-   "@babel/preset-env"
+   ["@babel/preset-env", {
+     "loose": true
+   }]
  ]
Enter fullscreen mode Exit fullscreen mode

从生产环境中移除 prop-types

PropTypes 在开发过程中非常有用,但对用户来说却毫无用处。你可以使用 ` babel-plugin-transform-react-remove-prop-typesremovePropTypes` 命令从你的 bundle 中移除 PropTypes。

安装方法:

npm install --save-dev babel-plugin-transform-react-remove-prop-types
Enter fullscreen mode Exit fullscreen mode

或者

yarn add -D babel-plugin-transform-react-remove-prop-types
Enter fullscreen mode Exit fullscreen mode

然后像这样将其添加到你的 Babel 配置中:

babel.config.json

  "env": {
    "production": {
      "plugins": [
+        "transform-react-remove-prop-types"
      ]
    }
  }
Enter fullscreen mode Exit fullscreen mode

节省的空间大小取决于应用的大小。就我而言,我节省了 16.5 KB,约占应用总大小的 1.2%。

考虑unsafe-wrap模式

unsafe-wrap顾名思义,该模式有点不安全,原因在插件文档中有详细说明

然而,就我而言,PropTypes 没有被从任何地方访问,但应用程序运行完美无瑕。

要启用此模式,您需要按如下方式更改 Babel 配置:

babel.config.json

  "env": {
    "production": {
      "plugins": [
-       "transform-react-remove-prop-types"
+       ["transform-react-remove-prop-types", {
+         "mode": "unsafe-wrap"
+       }]
      ]
    }
  }
Enter fullscreen mode Exit fullscreen mode

这样一来,我的软件包总共减少了 35.9 KB,约占 2.5% 。

启用新的 JSX 转换

启用新的 JSX 转换将改变 Babel React 预设将 JSX 转译为纯 JavaScript 的方式。

我在另一篇文章中解释了启用它的好处:如何在 React 17 中启用新的 JSX 转换

我强烈建议你阅读一下。如果觉得内容太长太复杂,那么为了快速见效,你只需要确保项目中的 `<version>` 和 `<version>` 都为最新版本@babel/core并按如下方式修改你的 Babel 配置:@babel/preset-env7.9.0

babel.config.json

  "presets": [
-   "@babel/preset-react"
+   ["@babel/preset-react", {
+     "runtime": "automatic"
+   }]
  ]
Enter fullscreen mode Exit fullscreen mode

砰!大约10.5 KB,也就是我文件包的 0.7% 就这么没了。

压缩你的 HTML

你的打包工具很可能足够智能,在生产模式下运行时默认会压缩 JavaScript。但你知道它也可以压缩 HTML 吗?甚至可以压缩HTML 中的JavaScript 代码?

你同意了?太好了!以下是你需要做的:

安装html-minifier-terser

npm install --save-dev html-minifier-terser
Enter fullscreen mode Exit fullscreen mode

或者

yarn add -D html-minifier-terser
Enter fullscreen mode Exit fullscreen mode

并修改你的 Webpack 配置以使用它。定义压缩器选项:

webpack.config.js

const minifyOptions = {
  // Defaults used by HtmlWebpackPlugin
  collapseWhitespace: true,
  removeComments: true,
  removeRedundantAttributes: true,
  removeScriptTypeAttributes: true,
  removeStyleLinkTypeAttributes: true,
  useShortDoctype: true,
  // Custom
  minifyCSS: true,
  minifyJS: true,
};
Enter fullscreen mode Exit fullscreen mode

并将它们用于HtmlWebpackPlugin……:

webpack.config.js

    new HtmlWebpackPlugin({
+     minify: minifyOptions,
      template: 'index.html',
    }),
Enter fullscreen mode Exit fullscreen mode

……以及在CopyWebpackPlugin

webpack.config.js

const { minify } = require('html-minifier-terser');
Enter fullscreen mode Exit fullscreen mode

webpack.config.js

  plugins: [
    new CopyWebpackPlugin({
      patterns: [
        {
          from: 'index.html',
          to: '',
+         transform(content) {
+           return minify(content.toString(), minifyOptions);
+         },
        },
      ]
    }),
  ],
Enter fullscreen mode Exit fullscreen mode

babel-plugin-styled-components仅限styled-components用户使用

如果你使用styled-components,务必同时使用他们的 Babel 插件。它不仅可以压缩样式,还支持服务器端渲染,并提供更友好的调试体验。

安装方法:

npm install --save-dev babel-plugin-styled-components
Enter fullscreen mode Exit fullscreen mode

或者

yarn add -D babel-plugin-styled-components
Enter fullscreen mode Exit fullscreen mode

然后像这样将其添加到你的 Babel 配置中:

babel.config.json

  "env": {
    "production": {
      "plugins": [
+        "styled-components"
      ]
    }
  }
Enter fullscreen mode Exit fullscreen mode

这本身就能节省几千字节,但由于添加了displayName其他功能,节省的空间暂时还不太明显。所以现在……

displayName在生产版本中禁用

babel.config.json

  "env": {
    "production": {
      "plugins": [
+       ["styled-components", {
+         "displayName": false,
+       }]
      ]
    }
  }
Enter fullscreen mode Exit fullscreen mode

在我的应用程序中这样做,让我节省了惊人的 50.4 KB 或 3.5% 的空间

createGlobalStyle将内容包裹在cssstyled-components仅限用户)中

显然,虽然babel-plugin-styled-components它可以压缩样式,但它不会压缩 `<head>` 标签内的任何内容createGlobalStyle。因此,你的应用很可能包含大量不必要的空白字符。

只需将createGlobalStyle内容物css也包裹起来即可移除它们,就像这样:

-const GlobalStyle = createGlobalStyle`
+const GlobalStyle = createGlobalStyle`${css`
   // Your global style goes here
-`;
+`}`;
Enter fullscreen mode Exit fullscreen mode

替换react-lifecycles-compat为空模拟

react-lifecycles-compat这是一个用于填充 React 16.3 中引入的生命周期方法的依赖项,以便被填充的组件能够与旧版本的 React 兼容。某些依赖项可能仍然使用此填充项,以避免破坏对旧版本 React 的支持。

如果您使用的是 React 16.3 或更高版本,则不需要 `<React> react-lifecycles-compat`。您可以像这样用模拟版本替换它:

__mocks__/reactLifecyclesCompatMock.js

module.exports = {
  polyfill: (Component) => Component,
};
Enter fullscreen mode Exit fullscreen mode

webpack.config.js

  resolve: {
    alias: {
+     'react-lifecycles-compat': path.resolve(__dirname, '__mocks__', 'reactLifecyclesCompatMock.js'),
    },
  },
Enter fullscreen mode Exit fullscreen mode

这样做可以节省 2.5 KB

替换classnamesclsx

classnames它并非大型依赖项,只有 729 字节,但与仅 516 字节的clsx完全兼容。因此,在您的应用程序中用替换将节省 213 字节classnamesclassnamesclsx

你的应用中很可能同时包含这两个文件 ,例如,因为依赖项可能需要其中一个。在这种情况下,你可以使用 Webpack 的 `requirements.txt` 功能从你的打包文件中移除它们classnamesclsxaliasclassnames

webpack.config.js

  resolve: {
    alias: {
+     classnames: 'clsx',
    },
  },
Enter fullscreen mode Exit fullscreen mode

这样做可以节省 729 字节

是不是漏掉了什么?

请在下方评论区分享您认为不太明显的优化方案!

文章来源:https://dev.to/wojtekmaj/optimizing-react-app-hardcore-edition-2h1