本篇寫的是優化方案,查看基礎配置的話能夠前往這裏juejin.im/post/5e6e01…javascript
{
test:/\.js$/,
use:[
'babel-loader?cacheDirectory=true'
]
}複製代碼
下載包 cnpm install cache-loader --save
java
{
test:/\.js$/,
use:[
'cache-loader'
]
}複製代碼
下載包 cnpm install happypack os --save
node
happy啓用進程池,設置數量通常爲設備cup總數,在loader處指定id做爲一個實例,在plugin處進行單獨處理react
const HappyPack = require('happypack');
const os = require('os');
module.exports = {
module:{
rules:[{
test:/\.js$/,
use:['happypack/loader?id=js']
}]
},
plugins:[
new HappyPack({
id:'js',
//這裏loaders配置與以前的loader一致
loaders:['babel-loader'],
//構建共享進程池,進程池裏有多個子進程去處理任務
ThreadPool: HappyPack.ThreadPool({size: os.cups().length })
})
]
}複製代碼
下載包 cnpm install thread-loader --save
webpack
把這個loader放在其餘loader前面,放置在這個loader以後的loader就會在一個單獨的worker池中運行,儘可能只在耗時的loader上面使用,若是項目體積較小打包時間可能還會延長。es6
能夠經過預熱worker池將制定的loader模塊載入node模塊緩存裏防止啓動worker時的高延時。web
const ThreadLoader = require('thread-loader');
const os = require('os');
const JSWorkPool = {
//產生work數量
workers: os.cups().length,
//閒置時定時刪除worker進程
poolTimeout: 2000,
}
//預熱babel-loader模塊
ThreadLoader.warmup(JSWorkPool,['babel-loader']);
module.exports = {
module:{
rules:[
{
test:/\.js$/,
use:[
'thread-loader',
'babel-loader'
]
}
]
}
}複製代碼
在resolve裏使用路徑重定向、include、exclude和loader的匹配規則npm
const path = require('path');
module.export = {
module:{
rules:[
{
test:/\.js$/,
exclude: /node_modules/,
include: path.join(__dirname,'./src'),
use:['babel-loader']
}
]
},
resolve:{
modules:['node_modules'],
extensions:['js','jsx','json'],
alias:{
'@src': path.join(__dirname,'./src')
}
}
}複製代碼
使用官方推薦的terser-webpack-plugin插件,實際使用能極大提高打包速度json
const TerserWebpackPlugin = require('terser-webpack-plugin');
module.export = {
optimization:{
minimizer:[
new TerserWebpackPlugin({
parallel:true
})
]
}
}複製代碼
使用動態import()、React.lazy、React.Suspense加載路由緩存
在用lazy加載組件時,使用Suspense包裹加載組件,正在等待加載組件時能夠用Suspense的fallback返回一個Loading組件
//Loading組件
import React, { Component } from 'react';
import { Spin } from 'antd';
class Loading extends Component {
render() {
return (
<div style={{ width: '100%', height: '100vh', display: 'flex', alignItems: 'center', justifyContent: 'center' }}>
<Spin size='large' />
</div>
);
}
}
export default Loading;
//index.js
import React, {lazy,Suspense} from 'react';
import ReactDOM from 'react-dom';
import {Router,Route,Switch} from 'react-router-dom';
import Loading from './Loading'
const Page1 = lazy(()=>import('@src/page1'));
const Page2 = lazy(()=>import('@src/page2'));
const Page3 = lazy(()=>import('@src/page3'));
ReactDOM.render(
<Router>
<Suspense fallback = {<Loading/>}>
<Switch>
<Route path='/1' component={Page1} />
<Route path='/2' component={Page2} />
<Route path='/' component={Page3} />
</Switch>
</Suspense>
</Router>
)複製代碼
使用React.PureComponent代替shouldComponentUpdate做淺層對比避免重複渲染
使用shouldComponentUpdate狀況,對比父組件傳來的color值和當前組件的num值變化來判斷是否從新渲染組件。
class Child extends React.Component{
constructor(props){
super(props);
this.state={
num: 0
}
}
shouldComponentUpdate(nextProps,nextState){
if(this.props.color !== nextProps.color){
return true;
}
if(this.state.num !== nextState.num){
return true;
}
return false;
}
render(){
return(
<div>
{this.state.num}
<button
color={this.props.color}
onClick={()=>this.setState(state => {num: state.num + 1})}
>
點擊+1
</button>
</div>
)
}
}複製代碼
換用PureComponent淺層渲染,它會對比全部的prop和state的值來判斷是否更新組件,上面例子換做PureComponent來寫
class Child extends React.PureComponent{
constructor(props){
super(props);
this.state={
num: 0
}
}
render(){
return(
<div>
{this.state.num}
<button
color={this.props.color}
onClick={()=>this.setState(state => ({num: state.num + 1}))}
>
點擊+1
</button>
</div>
)
}
}複製代碼
但這只是淺層對比,上面例子裏state.num和props.color都是基本數據類型,舉個例子
1 === 1
、
’red‘ === ’red
‘結果都是true
[1,2,3] === [1,2,3]
、{a:1} === {a:1}
結果都是false
由於後面例子屬於引用數據類型裏的Array和Object,對比的是引用地址而不是值,因此遇到props或者state的值是引用數據類型時,PureComponent就會失去對比意義。
官方提出了一個解決方案就是使用淺拷貝,使用Array.concat、Array.slice、Object.assign來拷貝原數據
handleClick(n){
this.setState(state=>({
arr: state.arr.concat(['n'])
//使用es6擴展符
//arr: [state.arr, 'n']
}))
}
handleClick2(obj){
return Object.assign({},obj,{a:1})
//使用擴展符
return {...obj,{a:1}};
}複製代碼
www.webpackjs.com/ webpack官方文檔
react.docschina.org/ react官方文檔