React + antd + webpack打包优化,首屏加载优化

4,367 阅读3分钟

1. 业务js按需加载

实现页面代码分割、按需加载 —— react-loadable 实现路由代码分割

具体使用:

npm install react-loadable --save

在.babelrc文件中配置:

{
    "plugins": [
        ...,
        "syntax-dynamic-import",
    ],
},

在路由文件中:

import Loadable from 'react-loadable';
import load from '../src/util/load'; // 页面加载需要的loading动画

组件引用由原来的

import Home from '../src/app/home';

变为

const Home = Loadable({  
    loader: () => import('../src/app/home'),  
    loading: load,  
    delay: 300,  // 延时毫秒数后加载渲染loading组件,默认值是200
});

util/load.js动画

import React from 'react';
import { Spin } from 'antd';

export default function Loading({ error, pastDelay }) {  
    if (error) {    
        return null;  
    }  
    if (pastDelay) {    
        return (      
            <div 
                className="loading-wrap"
                style={{          
                    position: 'absolute',          
                    left: 0,          
                    right: 0,          
                    top: 0,          
                    bottom: 0,          
                    display: 'flex',          
                    justifyContent: 'center',          
                    alignItems: 'center',
                  }}      
              >        
                  <Spin size="large" />      
               </div>    
        );  
    }  
    return null;
}

2. webpack-bundle-analyzer(可视化视图查看器)

查看 webpack 打包后所有组件与组件间的依赖关系,针对多余的包文件过大。

安装webpack-bundle-analyzer插件

npm install --save-dev webpack-bundle-analyzer

在需要查看webpack 打包后所有组件与组件间的依赖关系的webpack配置文件加上:

webpack.prod.js引入:

const BundleAnalyzerPlugin = require('webpack-bundle-analyzer').BundleAnalyzerPlugin;

webpack.prod.js配置:plugins中加上

plugins: [    ...,
    new BundleAnalyzerPlugin()
],

运行:

npm run build

最后输出:


发现 antd中的icon组件以及本地引入的moment打包出来过大。

3. 针对moment打包过大

百度一下,你就知道~~~

webpack中的externals属性-------具体了解

防止将某些import的包打包到bundle中,而是在运行时再去从外部获取这些。 

具体配置如下:

webpack.prod.js文件中:

externals: {    
    // 'react': 'React',    
    // 'mobx': 'mobx', // cdn引入umd版本,,否则报错    
    // 'mobx-react': 'mobxReact',    
    'moment': 'moment',    
    // 'react-dom': 'ReactDOM',    
    // 'react-router-dom': 'ReactRouterDOM'  
},

如果觉得被注释掉的import包有必要从外部获取则把注释去掉。

在打包的html模板文件中加上:

<!-- <script src="https://cdn.bootcss.com/react/16.8.1/umd/react.production.min.js"></script>  
<script src="https://cdn.bootcss.com/react-dom/16.8.1/umd/react-dom.production.min.js"></script>  
<script src="https://cdn.bootcss.com/react-router-dom/4.4.0-beta.6/react-router-dom.min.js"></script>  
<script src="https://cdn.bootcss.com/mobx/5.9.0/mobx.umd.min.js"></script>  <script src="https://cdn.bootcss.com/mobx-react/5.4.3/index.min.js"></script> -->  
<script src="https://cdn.bootcss.com/moment.js/2.24.0/moment.min.js"></script> 
<script src="https://cdn.bootcss.com/moment.js/2.24.0/locale/zh-cn.js"></script>

运行:

npm run build

最后输出:


发现打包文件体积变小,moment不在打包文件中。


4. 针对icon组件打包过大

我的工程中并没有单独用到icon图标,但是antd打包出来仍然有icon文件,为什么呢?

原因就是antd组件中的一些组件会默认引进一些icon,比如Select,DatePicker等等组件。只要工程中引入了这些含有内置icon的组件,antd都会打包icon组件。具体解决方法官方还未给出,但有暂时的解决方法。Svg icons make bunlde size too large #12011


5. 服务器端使用gzip

来自大神的解释:

GZIP最早由Jean-loup Gailly和Mark Adler创建,用于UNIX系统的文件压缩。我们在Linux中经常会用到后缀为.gz的文件,它们就是GZIP格式的。现今已经成为Internet 上使用非常普遍的一种数据压缩格式,或者说一种文件格式。HTTP协议上的GZIP编码是一种用来改进WEB应用程序性能的技术。大流量的WEB站点常常使用GZIP压缩技术来让用户感受更快的速度。这一般是指WWW服务器中安装的一个功能,当有人来访问这个服务器中的网站时,服务器中的这个功能就将网页内容压缩后传输到来访的电脑浏览器中显示出来.一般对纯文本内容可压缩到原大小的40%.这样传输就快了,效果就是你点击网址后会很快的显示出来.当然这也会增加服务器的负载. 一般服务器中都安装有这个功能模块的。

express启用gzip:

npm install compression

app.js中

var compression = require('compression');
app.use(compression()); // 使用在其它中间件前面

启用成功,没错,就是这么简单~~

总结:react的优化暂时就这样了,以后遇到了再来补充~~尤其要关注antd icon打包