编译阶段的优化
开发阶段构建更快
{
test: /.(j|t)sx?$/,
use: [
{
loader: "thread-loader",
},
{
loader: "babel-loader",
options: {
presets: [
["@babel/preset-env", { modules: false }], //es6->es5
"@babel/preset-react", // react->es5
"@babel/preset-typescript", //ts->es5
],
plugins: [
//按需加载
["import", { libraryName: "antd", style: "css" }],
],
},
},
],
include: path.resolve("src"),
exclude: /node_modules/,
},
resolve: {
modules: [path.resolve('node_modules')], //配置模块的查找范围
extensions: [".ts", ".tsx", ".js", ".json", ".jsx"],
alias: {
"@": resolvePath("./src"),
views: resolvePath("@/views"),
},
// webpack5之后不再有node模块的profill了,不配置也行
fallback: {
crypto: false, //不包含crypto的profill
buffer: false,//不包含crypto的profill
stream: false,//不包含crypto的profill
}
},
- 编译缓存
cache 会在开发 模式被设置成 type: ‘memory’ 而且在 生产 模式 中被禁用。 cache: true 与 cache: { type: ‘memory’ } 配置作用一致 开发模式下默认开启。
// webpack5新增的新功能,缓存
cache: {
type: "memory",
},
webpack4的话可以使用插件进行缓存
const HardSourceWebpackPlugin = require('hard-source-webpack-plugin')
{
plugins: [new HardSourceWebpackPlugin()]
}
第二次编译速度快80%,也是进行缓存。
- 开启多进程
thread-loader,会开启多进程来执行babel-loader。
{
test: /.(j|t)sx?$/,
use: [
{
loader: "thread-loader",
},
{
loader: "babel-loader",
options: {
presets: [
["@babel/preset-env", { modules: false }], //es6->es5
"@babel/preset-react", // react->es5
"@babel/preset-typescript", //ts->es5
],
plugins: [
//按需加载
["import", { libraryName: "antd", style: "css" }],
],
},
},
],
include: path.resolve("src"),
exclude: /node_modules/,
},
路由切换优化
懒加载实现
类似React.lazy的功能。当需要用到的时候才会去加载。原理类似jsonp。
const LoadHome: any = React.lazy(() => import("./Home"));
const LoadUser: any = React.lazy(() => import("./User"));
const App = () => {
useSetRem();
return (
<HashRouter>
<React.Suspense fallback={<div>loading....</div>}>
<ul>
<li>
<Link to="/">home</Link>
</li>
<li>
{" "}
<Link to="/user">user</Link>
</li>
</ul>
<Routes>
<Route path="/" element={<LoadHome />}></Route>
<Route path="/user" element={<LoadUser />}></Route>
</Routes>
</React.Suspense>
</HashRouter>
);
};
官方提供了React.lazy方法, 点home的时候再去加载。原理其实很容易。 实现:
const lazy = (loadComponent) => {
return class extends React.Component {
state = { Component: null };
componentDidMount() {
loadComponent().then((res) => {
this.setState({ Component: res.default });
});
}
render() {
const { Component } = this.state as any;
return Component && <Component />;
}
};
};
- 主要就是()=>import(‘xx’)返回的是一个Promise,
- 首先lazy返回一个什么都不渲染的组件,只有等组件开始渲染才会执行生命周期函数。
- 配合Route,当匹配到路径的时候,Route才会去渲染element,
- 所以当匹配到home的时候,页面开始渲染经过lazy包裹的类组件,
- 执行componentDidMount,执行promise,通过then获取到函数组件,然后通过setState改变状态,返回去渲染,从而达到懒加载的目的。
预先请求
浏览器首屏的时候不加载,空闲的时候再加载,如
const LoadHome: any = React.lazy(
() =>
import("./Home" /*webpackPrefetch: true */ /*webpackChunkName: 'home' */)
);
const LoadUser: any = React.lazy(
() =>
import("./User" /*webpackPrefetch: true */ /*webpackChunkName: 'user' */)
);
const LoadTest: any = React.lazy(
() =>
import("./Test" /*webpackPrefetch: true */ /*webpackChunkName: 'test' */)
);
使用魔法注释,效果: 会加入这一条link的标签。 当我们切换的时候会发现,已经预先请求好的。 除此之外还有预加载,preloader,与预请求的用法相似,但是他是将该资源的权重升级,首页就需要加载这个资源,就是预加载,用的不好会影响首页加载时间。
|