前端性能优化 —— 项目瘦身

在我们的日常开发中,我们经常需要引入各种各样的第三方模块来帮助我们提升开发速度。但是有时候这些模块里面又包含了许多我们用不到的模块,在打包的时候又一并打包进去了,这就造成了没必要的带宽浪费。这里以Vue项目为例。

一、准备工作

1. 使用 Vue Cli 3

这时我们就要掏出我们的Vue项目利器 —— Vue cli 3

在 CLI 服务中的 vue-cli-service build的文档中可以看到:

--report 和 --report-json 会根据构建统计生成报告,它会帮助你分析包中包含的模块们的大小。

在一个 Vue CLI 项目中,@vue/cli-service 安装了一个名为 vue-cli-service 的命令。你可以在 npm scripts 中以 vue-cli-service、或者从终端中以 ./node_modules/.bin/vue-cli-service 访问这个命令。

因此我们在build项目的时候就可以这么做:

vue-cli-service build --report
./node_modules/.bin/vue-cli-service build --report

这两种方式都可以帮我们生成报告,运行其中一个命令(第一个命令不行的小伙伴可以直接运行第二个命令)后我们可以看到dist目录下多出了一个report.html文件:

dist目录

这样,我们只要直接在浏览器中打开report.html就能看到模块分析了,如下图:

analyzers

2. Angular 项目

Angular项目的ng-cli同样有类似的功能,我们只需要在编译时加上--stats-json选项即可。然后再通过https://webpack.github.io/analyse/对生成的json文件进行分析,或者使用webpack-bundle-analyzer插件。

3. 其它方式

如果是其它用户,则需要安装webpack-bundle-analyzer

# NPM 
npm install --save-dev webpack-bundle-analyzer
# Yarn 
yarn add -D webpack-bundle-analyzer

webpack 配置:

const BundleAnalyzerPlugin = require('webpack-bundle-analyzer').BundleAnalyzerPlugin;
 
module.exports = {
  plugins: [
    new BundleAnalyzerPlugin()
  ]
}

编译完成后同样可以生成分析报告。

二、echarts 按需加载

1. 新建按需引入配置文件

在项目中,我们可能不会用到所有的 echart 模块,只会用到个别图表或组件,这样我们就可以只引入用到的,能有效减少资源的加载时间。

我们先新建一个专门的 echart 配置文件来引入相关代码:

// 路径:@/lib/echarts.js

// 引入主模块
const echarts = require('echarts/lib/echarts');

// 引入柱状图
require('echarts/lib/chart/bar');

// 引入相关组件
require("echarts/lib/component/dataZoom");

export default echarts

当然也可以使用import

// 路径:@/lib/echarts.js

// 引入主模块
import echarts from 'echarts/lib/echarts'
 
// 引入柱状图
import 'echarts/lib/chart/bar'

// 引入相关组件
import 'echarts/lib/component/dataZoom'

export default echarts

具体有哪些选项,可以直接查看node_modules目录下的echarts/index.js

2. 在用到的组件中引入 echarts

import echarts from '@/lib/echarts'

如果这个图表仅仅针对这个组件,或者说用户使用到频率很低,我们可以使用懒加载的方式进一步优化,等到用户使用到这个组件的时候才去加载echart图表:

methods: {
  init() {
    import("../../lib/echarts").then(Echarts => {
      // ...
    }
  }
}

这时我们再通过vue-cli工具来重新build项目,打开report.html分析对比优化前后的echart大小:

echart优化前
echart优化后

结果一目了然。

三、crypto-js 按需加载

除了echart可以使用这种方式,别的第三方库也能使用这些方法来加载。

我们经常会这样使用:

import crypto from 'crypto-js'

// ...
crypto.HmacSHA1()
// ...

上面这种方式会引入整个crypto-js

显然除了HmacSHA1方法之外,我们不会使用到别的方法,那样就非常得不偿失了,因此我们可以像下面这样做:

import HmacSHA1 from 'crypto-js/hmac-sha1'

// 如果要引入 Base64
import Base64 from 'crypto-js/enc-base64'

具体有哪些可以单独引入的,可以直接查看node_modules目录下的crypto-js目录

现在,我们再build来看看优化后的对比:

crypto优化前
crypto优化后

简直天差地别。

四、UI库 按需加载

如果我们为了快速开发一些公司内部的后台项目,或者是自己想做点东西来玩玩,但是不想写一些重复的样式,我们就会采用一些UI库。一些知名的UI库都是十分完善的,几乎包含所有日常所需的组件,因此它们的体积也是十分庞大的。如果我们只用到部分组件,但引入了所有组件,这样就不值得了。

Element-ui为例,UI框架通过借助babel-plugin-component来按需引入组件。这里我就不再如何进行按需引入了,官方文档已经写得十分详细了,Element-ui官方文档

五、懒加载

上面echarts优化中就已经使用过懒加载了,相信各位熟悉Vue的小伙伴都知道这种加载方式,我们可以在使用到该组件的时候再把组件下载下来。依我的经验来说,一般不常用的、单独的模块可以使用这种方式,通过import引入。注意,这实际上是由webpack提供的方法,而非Vue自身提供的方法。

Vue Router路由懒加载:

import Vue from 'vue'
import Router from 'vue-router'

Vue.use(Router)

const AsyncComponent = () => import('components/async-component/async-component')

export default new Router({
  routes: [
    {
      path: '/',
      component: 'AsyncComponent'
    },
  ]
})

异步组件:

components: {
  AsyncComponent: () => import('./async-component')
}

六、Moment.js 和 IgnorePlugin

常用的日期处理类库Moment.js居然有540.76kb,真是让人难以置信。见下图:

moment优化前

它如此巨大的原因是因为有很多语言资源文件,用于转化能成多国时间格式,见GitHub issue。大多数情况下,我们并不需要用到这么多的格式,但是我们不能像上面的echartcrypto那样按需加载,因此我们需要借助IgnorePlugin

在Vue根目录下新建vue.config.js文件,然后在里面添加配置:

const webpack = require('webpack')

module.exports = {
  configureWebpack: {
    plugins: [
      new webpack.IgnorePlugin(/^\.\/locale$/, /moment$/)
    ]
  }
}

这时我们就可以按需引入语言包:

const moment = require('moment');
require('moment/locale/zh-cn');
 
moment.locale('zh-cn');

这时我们再来看看它的大小:

moment优化后

七、总结

通过上面的例子,我想大家也能感受到许多第三方库因为要照顾到绝大部分情况,因此会比较大,但是我们可以通过一些方式只获取我们需要的部分。上面的对比图也显而易见了,减肥的效果是非常明显的,通过上面的方式,能够较大的提升用户体验,减少项目加载时间。

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 194,491评论 5 459
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 81,856评论 2 371
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 141,745评论 0 319
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 52,196评论 1 263
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 61,073评论 4 355
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 46,112评论 1 272
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 36,531评论 3 381
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 35,215评论 0 253
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 39,485评论 1 290
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 34,578评论 2 309
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 36,356评论 1 326
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 32,215评论 3 312
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 37,583评论 3 299
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 28,898评论 0 17
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 30,174评论 1 250
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 41,497评论 2 341
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 40,697评论 2 335