前端項目打包優化


前言

一個umijs項目,打包后發現體積過大,想優化, 看到各種博客上的優化手段是基於webpack的,於是我花了幾天把項目轉成webpack5的, 優化打包后比原來還大.... 最終還是在原來的umijs基礎上進行了優化.

打包分析

umi項目在package.json加一個腳本語句 "analyze": "cross-env ANALYZE=1 umi build", 執行yarn analyze 即可在ANALYZE server上得到依賴包分析圖

 "scripts": {
    "start": "cross-env UMI_ENV=dev umi dev",
    "build": "cross-env UMI_ENV=prod umi build",
    "analyze": "cross-env ANALYZE=1 umi build",
    "postinstall": "umi generate tmp",
    "prettier": "prettier --write '**/*.{js,jsx,tsx,ts,less,md,json}'",
    "test": "umi-test",
    "test:coverage": "umi-test --coverage"
  },

webpack需要安裝 webpack-bundle-analyzer 插件 並在配置文件中配置 new BundleAnalyzerPlugin().
此圖是優化后的

針對性優化(antd echart lodash momentjs)

經過分析發現, antd echart lodash momentjs四個依賴包占的體積最大

antd

umijs對antd組件庫有良好支持, 使用插件集@umijs/preset-react或@umijs/plugin-antd整合antds組件庫就自動是按需引入, 在webpack下需要使用bebel插件 babel-plugin-import 並在webpack.config.js(這個更靠譜)或babelrc配置

echart

echartc5的按需引入在官網有示例 實例

// 引入 echarts 核心模塊,核心模塊提供了 echarts 使用必須要的接口。 
import * as echarts from 'echarts/core';
// 引入柱狀圖圖表,圖表后綴都為 Chart
import { BarChart } from 'echarts/charts';
// 引入提示框,標題,直角坐標系,數據集,內置數據轉換器組件,組件后綴都為 Component
import {
  TitleComponent,
  TooltipComponent,
  GridComponent,
  DatasetComponent,
  DatasetComponentOption,
  TransformComponent
} from 'echarts/components';
// 標簽自動布局,全局過渡動畫等特性
import { LabelLayout, UniversalTransition } from 'echarts/features';
// 引入 Canvas 渲染器,注意引入 CanvasRenderer 或者 SVGRenderer 是必須的一步
import { CanvasRenderer } from 'echarts/renderers';

// 注冊必須的組件
echarts.use([
  TitleComponent,
  TooltipComponent,
  GridComponent,
  DatasetComponent,
  TransformComponent,
  BarChart,
  LabelLayout,
  UniversalTransition,
  CanvasRenderer
]);

// 接下來的使用就跟之前一樣,初始化圖表,設置配置項
var myChart = echarts.init(document.getElementById('main'));
myChart.setOption({
  // ...
});

實測對項目整體打包體積的優化用處不大, 采取了定制echarts.min.js的方式 定制地址
echarts4的體積比echart5小, 頁面生成echarts.min.js加入到項目的public文件夾
在document.ejs引入

<script src="<%= context.config.publicPath +'echarts.min.js'%>" > </script>

在.umirc.js添加配置

 externals: {
    echarts: 'echarts'
  },

使用示例: echart組件封裝

import React, { useEffect, useState, useRef } from 'react'
import echarts from 'echarts'

const Echarts = (props) => {
  const { option } = props
  const [chart, setChart] = useState()
  const domRef = useRef()

  useEffect(() => {
    const instance = echarts.init(domRef.current)
    const chartResize = () => {
      instance.resize()
    }
    setChart(instance)
    window.addEventListener('resize', chartResize)
    return () => {
      window.removeEventListener('resize', chartResize)
    }
  }, [])
  useEffect(() => {
    if (chart) {
      chart.setOption(option)
    }
  }, [option])
  return <div ref={domRef} style={{ height: '100%', width: '100%' }} />
}

export default Echarts

lodash

 代碼中的全部引入改為部分引入  
```
import _ from 'lodash'
改為
import { extend, omit, difference } from 'lodash'
```

devDependencies中安裝兩個插件 babel-plugin-lodash 和 lodash-webpack-plugin
.umirc.js中配置

const LodashModuleReplacementPlugin = require('lodash-webpack-plugin')
export default defineConfig({
 ...
  extraBabelPlugins: ['lodash'],
  chainWebpack: (config, { webpack }) => {
    if (process.env.NODE_ENV === 'production') {  // 生產模式開啟
      config.plugin('LodashModuleReplacementPlugin').use(
        new LodashModuleReplacementPlugin()
      ); // 壓縮lodash
    }
  },
 })

momentjs

moment的體積也是很大,使用webpack.IngorePlugin插件忽略其locale能很好的壓縮體積
.umirc.js中配置

const LodashModuleReplacementPlugin = require('lodash-webpack-plugin')
export default defineConfig({
 ...
  extraBabelPlugins: ['lodash'],
  chainWebpack: (config, { webpack }) => {
    if (process.env.NODE_ENV === 'production') {  // 生產模式開啟
      config.plugin('igncore').use(new webpack.IgnorePlugin(/^\.\/locale$/, /moment$/))
      config.plugin('LodashModuleReplacementPlugin').use(
        new LodashModuleReplacementPlugin()
      ); // 壓縮lodash
    }
  },
 })

也可以使用dayjs替換moment, dayjs體積非常小. antd組件庫有使用到moment,也需要進行替換 官方文檔操作說明


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM