打包优化

80 阅读5分钟

本文已参与「新人创作礼」活动, 一起开启掘金创作之路。

打包优化

vue cli:cli.vuejs.org/zh/guide/we…

分析打包结果

由于vue-cli是利用webpack进行打包,我们仅需加入一个webpack插件webpack-bundle-analyzer即可分析打包结果

下载包 npm i webpack-bundle-analyzer -D //安装的是开发环境依赖

为了避免在开发环境中启动webpack-bundle-analyzer,我们仅需使用以下代码即可

const BundleAnalyzerPlugin =
  require("webpack-bundle-analyzer").BundleAnalyzerPlugin;
// vue.config.js
module.exports = {
  // 通过 configureWebpack 选项,可对 webpack 进行额外的配置
  // 该配置最终会和 vue-cli 的默认配置进行合并(webpack-merge)
  configureWebpack: {
    plugins: [new BundleAnalyzerPlugin()],
  },
};

如果说我们只是这样加入了打包分析插件的话,就像下面这样

在我们运行指令serve就会直接显示打包分析页面,然而有些时候我们在开发过程中是不需要的

所以我们可以选择在不同的条件下输入不同的webpack 配置

经过上述配置过后运行打包命令就会跳转到打包分析页面

在终端中也会反馈一些提示、建议、警告等

vue2 本身不怎么支持树摇优化(tree shaking),树摇优化很依赖于具名导出,然而 vue2 基本都是默认导出

但是 vuex 可以进行树摇优化 以下是是优化前的代码

树摇优化后的代码

优化公共库打包体积

使用 CDN

CDN 全称为 Content Delivery Network,称之为内容分发网络

它的基本原理是:架设多台服务器,这些服务器定期从源站拿取资源保存本地,到让不同地域的用户能够通过访问最近的服务器获得资源

img

我们可以把项目中的所有静态资源都放到 CDN 上(收费),也可以利用现成免费的 CDN 获取公共库的资源(就是把一些公共库资源抽离出去,都用 CDN 来访问速度更快)

image-20210203140029967

首先,我们需要告诉webpack不要对公共库进行打包

配置externals

// vue.config.js
module.exports = {
  configureWebpack: {
    externals: {
      vue: "Vue",
      vuex: "Vuex",
      "vue-router": "VueRouter",
    },
  },
};

然后,在页面中手动加入cdn链接,这里使用bootcn

在这样的页面的模板代码中,我们可以写模板代码

对于vuexvue-router,使用这种传统的方式引入的话会自动成为Vue的插件,因此需要去掉Vue.use(xxx)

我们可以使用下面的代码来进行兼容

在我们使用上述引入 CDN 了之后,在开发环境(development)为了避免由于引入这些第三方库造成的全局污染,我们需要判断是否存在这个特殊的全局污染从而来判断是否需要安装这个插件(因为开发环境下是没有使用 CDN 的)

// store.js
import Vue from "vue";
import Vuex from "vuex";

if (!window.Vuex) {
  // 没有使用传统的方式引入Vuex
  Vue.use(Vuex);
}

// router.js
import VueRouter from "vue-router";
import Vue from "vue";

if (!window.VueRouter) {
  // 没有使用传统的方式引入VueRouter
  Vue.use(VueRouter);
}

启用现代模式

这个core.js就是处理兼容性的

为了兼容各种浏览器,vue-cli在内部使用了@babel/present-env对代码进行降级,你可以通过.browserlistrc配置来设置需要兼容的目标浏览器

这是一种比较偷懒的办法,因为对于那些使用现代浏览器的用户,它们也被迫使用了降级之后的代码,而降低的代码中包含了大量的polyfill,从而提升了包的体积

因此,我们希望提供两种打包结果:

也就是一个用了 babel 一个没有用 babel

  1. 降级后的包(大),提供给旧浏览器用户使用
  2. 未降级的包(小),提供给现代浏览器用户使用

除了应用webpack进行多次打包外,还可以利用vue-cli给我们提供的命令:

// 这个命令就会提供两个打包结果
vue-cli-service build --modern

由于打包分析插件只能查看一次打包结果分析,所以这样的话第二次打包就会报错(第一次打包是有关兼容性的打包

优化项目包体积

这里的项目包是指src目录中的打包结果

页面分包(路由懒加载的产物)

默认情况下,vue-cli会利用webpacksrc目录中的所有代码打包成一个bundle

这样就导致访问一个页面时,需要加载所有页面的js代码

然而实际上我们只在当前的一个页面,所以我们不需要所有页面的js代码

webpack 会把动态导入的模块,自动分包;动态导入返回的是 promise

我们可以利用webpack动态import的支持,从而达到把不同页面的代码打包到不同文件中

// routes
export default [
  {
    name: "Home",
    path: "/",
    // 路由懒加载,是一个函数
    component: () => import(/* webpackChunkName: "home" */ "@/views/Home"),
  },
  {
    name: "About",
    path: "/about",
    component: () => import(/* webpackChunkName: "about" */ "@/views/About"),
  },
];
优化首屏响应

首页白屏受很多因素的影响

vue页面需要通过js构建,因此在js下载到本地之前,页面上什么也没有

一个非常简单有效的办法,即在页面中先渲染一个小的加载中效果,等到js下载到本地并运行后,即会自动替换

把图片资源放到 public 目录里面 (这个目录的资源会被复制)

两种静态资源
  1. assets:嵌入式的静态资源,会参与打包过程
  2. static:纯静态资源,会原封不动的到输出目录
<div id="app">
  <img src="loading.gif" />
</div>