React 应用优化:硬核版
你听说过代码压缩,听说过懒加载,听说过摇树优化,你可能都用过这些优化方法。或者,你真的用过吗?这里有一些你可能从未听说过的优化技巧。直到现在!
启用“松散”转换@babel/preset-env
启用“宽松”转换可以显著缩小应用程序的大小。我的软件包大小减少了大约 230.9 KB,相当于 16.2% !
然而,这样做是有代价的:启用和禁用这些转换时,您的应用程序可能会出现故障。
就我而言,我唯一需要做的修复与遍历HTMLCollection(document.querySelectorAll(…),document.getElementsByTagName(…)和HTMLFormControlsCollection(form.elements)有关。我不再能够执行例如[...form.elements],我必须将其替换为Array.from(form.elements)。
loose仍然对大幅节省的费用心动不已?不妨在 Babel 配置中启用该标志来尝试一下:
babel.config.json
"presets": [
- "@babel/preset-env"
+ ["@babel/preset-env", {
+ "loose": true
+ }]
]
从生产环境中移除 prop-types
PropTypes 在开发过程中非常有用,但对用户来说却毫无用处。你可以使用 ` babel-plugin-transform-react-remove-prop-typesremovePropTypes` 命令从你的 bundle 中移除 PropTypes。
安装方法:
npm install --save-dev babel-plugin-transform-react-remove-prop-types
或者
yarn add -D babel-plugin-transform-react-remove-prop-types
然后像这样将其添加到你的 Babel 配置中:
babel.config.json
"env": {
"production": {
"plugins": [
+ "transform-react-remove-prop-types"
]
}
}
节省的空间大小取决于应用的大小。就我而言,我节省了 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"
+ }]
]
}
}
这样一来,我的软件包总共减少了 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"
+ }]
]
砰!大约10.5 KB,也就是我文件包的 0.7% 就这么没了。
压缩你的 HTML
你的打包工具很可能足够智能,在生产模式下运行时默认会压缩 JavaScript。但你知道它也可以压缩 HTML 吗?甚至可以压缩HTML 中的JavaScript 代码?
你同意了?太好了!以下是你需要做的:
安装html-minifier-terser:
npm install --save-dev html-minifier-terser
或者
yarn add -D html-minifier-terser
并修改你的 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,
};
并将它们用于HtmlWebpackPlugin……:
webpack.config.js
new HtmlWebpackPlugin({
+ minify: minifyOptions,
template: 'index.html',
}),
……以及在CopyWebpackPlugin:
webpack.config.js
const { minify } = require('html-minifier-terser');
webpack.config.js
plugins: [
new CopyWebpackPlugin({
patterns: [
{
from: 'index.html',
to: '',
+ transform(content) {
+ return minify(content.toString(), minifyOptions);
+ },
},
]
}),
],
babel-plugin-styled-components仅限styled-components用户使用
如果你使用styled-components,务必同时使用他们的 Babel 插件。它不仅可以压缩样式,还支持服务器端渲染,并提供更友好的调试体验。
安装方法:
npm install --save-dev babel-plugin-styled-components
或者
yarn add -D babel-plugin-styled-components
然后像这样将其添加到你的 Babel 配置中:
babel.config.json
"env": {
"production": {
"plugins": [
+ "styled-components"
]
}
}
这本身就能节省几千字节,但由于添加了displayName其他功能,节省的空间暂时还不太明显。所以现在……
displayName在生产版本中禁用
babel.config.json
"env": {
"production": {
"plugins": [
+ ["styled-components", {
+ "displayName": false,
+ }]
]
}
}
在我的应用程序中这样做,让我节省了惊人的 50.4 KB 或 3.5% 的空间。
createGlobalStyle将内容包裹在css(styled-components仅限用户)中
显然,虽然babel-plugin-styled-components它可以压缩样式,但它不会压缩 `<head>` 标签内的任何内容createGlobalStyle。因此,你的应用很可能包含大量不必要的空白字符。
只需将createGlobalStyle内容物css也包裹起来即可移除它们,就像这样:
-const GlobalStyle = createGlobalStyle`
+const GlobalStyle = createGlobalStyle`${css`
// Your global style goes here
-`;
+`}`;
替换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,
};
webpack.config.js
resolve: {
alias: {
+ 'react-lifecycles-compat': path.resolve(__dirname, '__mocks__', 'reactLifecyclesCompatMock.js'),
},
},
这样做可以节省 2.5 KB。
替换classnames为clsx
classnames它并非大型依赖项,只有 729 字节,但与仅 516 字节的clsx完全兼容。因此,在您的应用程序中用替换将节省 213 字节。classnamesclassnamesclsx
你的应用中很可能同时包含这两个文件 ,例如,因为依赖项可能需要其中一个。在这种情况下,你可以使用 Webpack 的 `requirements.txt` 功能从你的打包文件中移除它们:classnamesclsxaliasclassnames
webpack.config.js
resolve: {
alias: {
+ classnames: 'clsx',
},
},
这样做可以节省 729 字节。
是不是漏掉了什么?
请在下方评论区分享您认为不太明显的优化方案!
文章来源:https://dev.to/wojtekmaj/optimizing-react-app-hardcore-edition-2h1