vue code split

vue code split

背景

最近开发的一个项目使用了 vue+ element-ui 的技术栈,当然,还有其他的一些工具库,比如 axios

说一下我的开发步骤,基础结构是通过 vue-cli@2.x 创建的,手动的加入了 axios vuex , vue-router 是脚手架自带的。

code split

1. 路由懒加载

使用 vue-router 的时候,如果按照默认配置,所有的路由都会被打包到一个 bundle.js 文件中去(bundle 文件名一般是 app.js)。

进入 router/index.js 文件中,只需要将所有类似 import Home from '@/components/home'; 替换为 const Home = () => import('@/components/home')

其余部分不需要变。就能以最简单的形式做到根据路由来划分 webpack 打包的模块。这个时候 执行 npm run build 是就能看到多了很多小的 js 文件, 并且app.js 文件的体积也减小了。

附上代码示例:

import Vue from 'vue'
import Router from 'vue-router'
const AdminIndex = () => import('@/components/admin-index')
const Home = () => import('@/components/home')

Vue.use(Router)

export default new Router({
  routes: [
    {
      path: '/',
      name: 'admin-index',
      component: AdminIndex
    },
    {
      path: '/home',
      name: 'home',
      component: Home
    }
  ]
})

2. 组件懒加载

跟路由懒加载的形式一样,也是使用 () => import('xxx') 的形式。
如果对于一个容器组件中,import 很多个组件进来,使用组件懒加载,能够继续减小首次加载的文件大小。示例代码:

<template>
  <div>
    <HomeHeader />
    <SearchContainer  />
    <HomeFooter />
  </div>
</template>

<script>
import HomeHeader from "./home-header";
import HomeFooter from "./home-footer";
import SearchContainer from "./containers/search-container";
import LoadingComponent from "@/components/common/loading";

export default {
  name: "home",
  components: {
    HomeHeader,
    HomeFooter,
    SearchContainer,
    LoadingComponent
  }
};
</script>

优化之前:


20181012235553709png

20181013002145418png

组件懒加载优化之后:

<template>
  <div>
    <HomeHeader />
    <SearchContainer  />
    <HomeFooter />
  </div>
</template>

<script>
const HomeHeader = () => import("./home-header");
const HomeFooter = () => import("./home-footer");
const SearchContainer = () => import("./containers/search-container");
export default {
  name: "home",
  components: {
    HomeHeader,
    HomeFooter,
    SearchContainer
  }
};
</script>
20181013002333147png

从文件的个数中,不知道有没有看出什么?

app.js 是属于 项目的公共部分的代码而声明一个 const HomeHeader = () => import("./home-header"); 类似的组件,就会创建一个 n.js 文件,达到了继续拆分比较大的 js 包的目的。

所以其实只要你愿意,可以一部分组件使用 const HomeHeader = () => import("./home-header"); 另一部分组件使用 import HomeHeader from "./home-header";

不过总的来说,除非一个组件过于庞大了,在我开发过程中,才会想着用组件拆分的形式。每一个小组件都这样拆分,最终得到很多很多个小的 js 文件,反而是因为网络请求的原因,拖慢加载速度的。

3. webpack-bundle-analyzer

在做一个项目的一开始,其实我都没有去考虑过性能优化、code split 的事情,只有当逻辑越来越多,开发的时候明显感觉到页面加载速度慢了,network 里看到 bundle.js 体积巨大了,才会想着去做优化的考虑。

emmm 所以到底应该怎么拆?拆哪些部分?这个需要webpack-bundle-analyzer 来帮忙,code split 也要有理有据。

安装和配置

如果你跟我一样,使用的是 vue-cli@2.9.x 的话,webpack-bundle-analyzer 插件是已经安装了的,webpack 也配置好了的。

反正你就全局搜索一下 webpack-bundle-analyzer 就好了,看看 package.json 中有没有依赖,webpack 配置中有没有,一般只在webpack.prod.conf.js 中,因为开发环境下也不会去看的。

如果实在没有,那就手动安装和配置好了。

npm intall webpack-bundle-analyzer –save-dev

在 build/webpack.prod.config.js 中添加配置:

if (config.build.bundleAnalyzerReport) {
  const BundleAnalyzerPlugin = require('webpack-bundle-analyzer').BundleAnalyzerPlugin
  webpackConfig.plugins.push(new BundleAnalyzerPlugin())
}

package.jsonscript 中添加:

“analyz”: “NODE_ENV=production npm_config_report=true npm run build”

如果你是 window 用户的话,应该是:

“analyz”: “set NODE_ENV=production npm_config_report=true npm run build”

执行: npm run analyz

等项目 build 完了之后,就会自动打开一个页面了,

20181013004902726png

4. element-ui 库的优化

重点终于来了(不是标题党。。。。)。从上面的图中我们可以看到,vendor.xxx.js 实在是有点大,webpack build 完了之后,也细心的为我们标注出了 big:

20181013005117948png

解决办法是对于 element-ui 这个 ui 库从 vendor.xx.js 文件中剥离出来,最简单的办法就是使用 公共的 cdn 了。这里再做一层更彻底的剥离,将vue, vuex, vue-router,axios 等依赖文件,全部使用 cdn。

20181013005418947png

看好这些依赖的版本,直接去 百度搜索相关的 cdn 文件。下面我直接贴我修改之后的代码:

index.html

...
<link rel="stylesheet" href="https://unpkg.com/element-ui/lib/theme-chalk/index.css">

...
<body>
  <div id="app"></div>
  <!-- cdn 加速,减小 vendor.js 体积 -->
  <script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.5.17-beta.0/vue.min.js"></script>
  <script src="https://cdnjs.cloudflare.com/ajax/libs/vuex/3.0.1/vuex.min.js"></script>
  <script src="https://cdnjs.cloudflare.com/ajax/libs/vue-router/3.0.1/vue-router.min.js"></script>
  <script src="https://cdnjs.cloudflare.com/ajax/libs/axios/0.18.0/axios.min.js"></script>
  <script src="https://unpkg.com/element-ui/lib/index.js"></script>
  <!-- built files will be auto injected -->
</body>

package.json

上面引入过 cdn 文件的依赖, 全都可以去掉了。

main.js

删除或者注释跟element 相关的代码:

import ElementUI from 'element-ui';
...
import 'element-ui/lib/theme-chalk/index.css';
...
Vue.use(ElementUI);
...

webpack.base.conf.js

在 webpack 配置中添加外部扩展:

module.exports = {
...
      // 外部扩展,通过 cdn 引入,不会被webpack打包
      externals: {
        'vue': 'Vue',
        'vue-router': 'VueRouter',
        'vuex': 'Vuex',
        'axios': 'axios'
      }
  }

这个时候已经好了,清除一下项目 node_modules 中的删除的不需要的依赖吧, uninstall 也行,直接删除整个 node_modules 文件夹,重新 npm install 也行。

处理完 node_modules 之后, npm start 再次看一下我们优化之后的结果:

20181013010649788png

开发状态下的 app.js 明显已经变小了,build 之后的文件也是。

这里需要注意的一点是,依赖库使用 cdn 文件来加载话,网络请求的速度与 cdn 的速度有关,如果不放心别人的 cdn ,将上述的 cdn 文件内容下载到本地放在 static 目录下当做静态文件即可。

建议使用 CDN 引入依赖的用户在链接地址上锁定版本,以免将来升级时受到非兼容性更新的影响。

vue 项目的 code split ,差不多就是这样了。感谢阅读, Happy Coding !

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

推荐阅读更多精彩内容