likes
comments
collection
share

正确使用externals,vue工程构建性能提升67%

作者站长头像
站长
· 阅读数 16

正确使用externals,vue工程构建性能提升67%

一、 externals的使用场景

官方解释:防止将某些 import 的包(package)打包到bundle中,而是在运行时(runtime)再去从外部获取这些扩展依赖

换句话说externals配置项用来告诉Webpack要构建的代码中使用了哪些不用被打包的模块,也就是说这些模版是外部环境提供的,Webpack在打包时可以忽略它们

使用场景:所以说只要是用webpack构建的工程,当工程规模达到一定程度时,都有必要将体积较大的、基本无变动的第三方包处理为externals,以减小入口js文件的大小缩短首屏加载时长减小依赖包体积

具体使用:很简单,两步(webpack配置声明externals,html cdn引入),如下图,更多可见官方文档

正确使用externals,vue工程构建性能提升67%

二、 为什么要使用externals

1、 前提

  • 使用到的webpack分析工具
    • webpack-bundle-analyzer:使用交互式可缩放树形图可视化网页包输出文件的大小,可视化分析工具
    • vue uivuecli3 自带的webpack分析工具(使用vuecli3搭建的项目可使用)
  • 可使用的cdn服务商

两个工具用一个就行,都是webpack分析工具,这里介绍两种工具的用法

2、真实业务工程举例分析

本文的相关数据是我工作中的一个实际业务工程,用vuecli3搭建的

(1)vue ui分析

在业务工程的命令行执行vue ui,在浏览器会打开一个http://localhost:8000/,点击任务>build>执行,执行结束后 可以看到npm run build执行时间36s,资源体积10.5M,其中依赖项体积8.3M,资源占比72+%,仔细看下方的依赖项可以看到其中echartselement-ui体积超过1M,gojs体积也不小 正确使用externals,vue工程构建性能提升67%

(2)webpack-bundle-analyzer分析
// 安装
npm install --save-dev webpack-bundle-analyzer
// 引用
// vue.config.js
const BundleAnalyzerPlugin = require('webpack-bundle-analyzer').BundleAnalyzerPlugin;

module.exports = {
  configureWebpack: {
       // BundleAnalyzerPlugin只在开发环境使用
      plugins: [
            ...[
                new ...// 其他插件
            ],
            ...(process.env.NODE_ENV !== "production"
                ? [new BundleAnalyzerPlugin()]
                : [])
      ],
  }
}

启动项目,在浏览器打开http://127.0.0.1:8888/,如下,可以看到依赖包情况跟vue ui一致,echartselement-uigojs体积较大;且app.js体积大,增长首屏时长 正确使用externals,vue工程构建性能提升67%

三、 如何使用externals

将体积较大的第三方包抽离为externals,我们这里选择处理axioselement-uiechartsvuegojs

// vue.config.js
module.exports = {
    publicPath,
    configureWebpack: {
        externals: {
            axios: "axios",
            "element-ui": "ELEMENT",
            echarts: "echarts",
            vue: "Vue",
            gojs: "go"
        },
    },
}

如何得知第三方包对应的keyvalue是啥,keypackage.json中安装的包名,value时包真实注册或者说暴露的全局变量的值,比如element-uivalueELEMENT,打开elememt-ui的源码,格式化可以看到如下,注册的值是ELEMENT,且依赖了vue;其他包同样思路

正确使用externals,vue工程构建性能提升67%

第三方包不直接直接使用cdn,在node_modules下或者cdn上找到相关版本的包,拷贝放在public/js目录下,入下图

正确使用externals,vue工程构建性能提升67% 入口html中CDN通过html-webpack-plugin注入的方式引入,而非以下手动直接在html中手动注入

<html>
  <body id="<%= VUE_APP_NAME %>">
    <div id="app"></div>
    <script
        type="text/javascript"
        src="<%=BASE_URL%>js/vue.@2.5.21.min.js"
    ></script>
    <script
        type="text/javascript"
        src="<%=BASE_URL%>js/element-ui@2.4.0.js"
    ></script>
    ...
  </body>
</html>

首先将cdn相关地址信息挂在htmlWebpackPlugin.options.cdn

我们这里是vuecli3的写法,直接用webpack写法可看htmlWebpackPlugin插件

// vue.config.js
const appName = process.env.VUE_APP_NAME;
const publicPath = `/${appName}/`;

const cdn = {
    js: [
        `${publicPath}js/vue.@2.5.21.min.js`,
        `${publicPath}js/element-ui@2.4.0.js`,
        `${publicPath}js/axios@0.18.0.min.js`,
        `${publicPath}js/echarts@4.1.0.min.js`,
        `${publicPath}js/gojs@2.0.15.js`
    ]
};

module.exports = {
    publicPath,
    chainWebpack: config => {
        config.plugin("html").tap(args => {
            args[0].cdn = cdn;
            return args;
        });
    }
}

然后在html中如下引入,需注意vue需要在element-ui之前引入,否则会报错

<html>
  <body id="<%= VUE_APP_NAME %>">
    <div id="app"></div>
    <% for (var i in htmlWebpackPlugin.options.cdn &&
    htmlWebpackPlugin.options.cdn.js) { %>
    <script
        type="text/javascript"
        src="<%= htmlWebpackPlugin.options.cdn.js[i] %>"
    ></script>
    <% } %>
  </body>
</html>

四、externals使用效果验证

再次执行vue ui,可以看到npm run build执行时间降低为12s,缩短了24s,资源体积9M,其中依赖项体积3.8M,减少了8.3-3.8=4.5M,占比54+%,仔细看下方的依赖项可以看到其中echartselement-ui体积超过1M,gojs体积也不小

正确使用externals,vue工程构建性能提升67%

webpack-bundle-analyzer分析结果,可以看到相关包大小同vue ui效果一致,开发环境下,app.js体积也减小了 正确使用externals,vue工程构建性能提升67% 部署到生产环境后,可以看到下图,chunk-vendors.js的体积有246kb降低到41kb,网络请求时长由3.73s减少到185ms

  • 使用externals之前 正确使用externals,vue工程构建性能提升67%
  • 使用externals之后 正确使用externals,vue工程构建性能提升67%
转载自:https://juejin.cn/post/7001138300178137118
评论
请登录