zoukankan      html  css  js  c++  java
  • 提高首屏页面加载速度,解决vue-cli打包后单个文件过大的问题

    本教程是针对vue-cli3以上的版本,其实原理都大同小异,这个demo为vue-cli直接创建的项目,并在main.js中引入了echartelement-uilodash

    首先看demo打包后生成的文件大小,这个demo里面什么业务都没写、仅仅引入了几个包,chunk-vendors.js就达到了1.6M之多,如果是写入了庞大的业务后没做任何优化处理,那么这个文件可能会达到10M之多,这发生在我真实的项目经历中

    借助webpack-bundle-analyzer帮助分析

    首先安装webpack-bundle-analyzer

    yarn add webpack-bundle-analyzer -D
    

    然后在项目根目录创建vue.config.js,然后在文件中写入以下代码

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

    然后执行yarn build 在浏览器会自动打开我们的使用包分析文件,大致如下图的样子

    我们可以看到生成的最大文件为chunk-vendors.js,这个文件主要又由echartselement-uilodashzrender组成,其中echartselement-uilodash为我们项目开发时必要引入的文件,所以我们如果把这写文件分离出来那么文件自然就会小了很多

    如何分离这些文件

    我们可以借助wepack配置项里面的externals来达到目的,在vue.config.js里面加入如下代码

    module.exports = {
    
        // ... other code
        
        configureWebpack: {
        
        // ... other code
        
            externals: {
                "lodash": '_',
                "vue": 'Vue',
                "echarts": 'echarts',
                "element-ui": 'ELEMENT',
            },
            
            // ... other code
            
        }
        
        // ... other code
        
    }
    

    externals 配置选项提供了「从输出的 bundle 中排除依赖」的方法。我们可以通过script标签引入这些资源,具体关于externals的介绍请点击这里
    然后我们再对应的public -> index.html文件加入以下代码,其中BASE_URL指的是public目录,你需要从官网下载对应的资源放在对应的目录下

    <!DOCTYPE html>
    <html lang="en">
      <head>
        <meta charset="utf-8">
        <meta http-equiv="X-UA-Compatible" content="IE=edge">
        <meta name="viewport" content="width=device-width,initial-scale=1.0">
        <link rel="icon" href="<%= BASE_URL %>favicon.ico">
        <title>optimize_vue</title>
      </head>
      <body>
        <noscript>
          <strong>We're sorry but optimize_vue doesn't work properly without JavaScript enabled. Please enable it to continue.</strong>
        </noscript>
        <div id="app"></div>
        <!-- built files will be auto injected -->
        <script src="<%= BASE_URL %>js/pace.min.js"></script>
        <script src="<%= BASE_URL + (process.env.NODE_ENV === 'development' ? 'js/vue-2.6.0.js' : 'js/vue-2.6.0.min.js') %>"></script>
        <script src="<%= BASE_URL %>js/element-ui-2.11.1.js"></script>
        <script src="<%= BASE_URL %>js/lodash.min.js"></script>
        <script src="<%= BASE_URL %>js/echarts.min-4.4.0.js"></script>
      </body>
    </html>
    

    然后我们再看一下效果, lodash、echarts、elementui已经成功从webpack bundle分离出去了,打包后的chunk-vendors.js也只有24kb的大小

    使用路由懒加载

    路由懒加载会只加载当前页面需要的资源,代码如下

    const Foo = () => Promise.resolve({ /* 组件定义对象 */ })
    // or
    const Foo = () => import(/* webpackChunkName: "group-foo" */ './Foo.vue')
    const Bar = () => import(/* webpackChunkName: "group-foo" */ './Bar.vue')
    const Baz = () => import(/* webpackChunkName: "group-foo" */ './Baz.vue')
    

    注意如果使用import方式的引入需要安装@babel/plugin-syntax-dynamic-import,然后在babel.config.js中加入下面代码即可

    module.exports = {
        
      // ... other code
      
      "plugins": ["@babel/plugin-syntax-dynamic-import"]
      
      // ... other code
      
    }
    

    关于process.env.NODE_ENV

    相信大家在开发的时候一定会有跟多个开发环境,比如development/feature/sandbox/production,因为这玩意我真是吃了大亏,刚开始没看文档, 直接在执行package.json的script命令的时候通过cross-env NODE_ENV=xxx 来修改环境变量,导致无法使用vue-cli工具为我们提供的代码优化功能

    注意: process.env_NODE_ENV的值只能为developmentproduction,不要修改为其他值,不然可能会出现其他问题,如果你真的想在不同的环境使用不同的接口地址或者、其他的内容我们可以用vue-cli为我们提供的--mode达到目的,比如

    "scripts": {
        "serve": "vue-cli-service serve",
        "build": "vue-cli-service build",
        "build:sanbox": "vue-cli-service build --mode sanbox",
        "build:feature": "vue-cli-service build --mode feature",
        "lint": "vue-cli-service lint",
        "precommit": "yarn lint"
    }
    

    这里vue-cli会读取项目根目录下的.env/.env./.env..local相关文件***指的是--mode的值,--mode会修改process.env.NODE_ENV的值,我们需要再对应的env里面把NODE_ENV改写回来,比如一个.env.sanbox环境代码如下

    NODE_ENV=production
    VUE_APP_ENV=sanbox
    

    当我们执行yarn build:sanbox的时候就会加载这个文件,我们可以通过process.env.VUE_APP_ENV来访问对应设置的值,注意只有VIE_APP_前缀的环境变量才会被webpack.DefinePlugin静态嵌入到客户端侧的包中。

    比如我们需要不同的构建命令构建不同的的publicPath的时候我们可以这样做

    const map = {
        production: '/',
        feature: '/feature',
        sanbox: '/sanbox',
        development: '/development',
    }
    const env = process.env.VUE_APP_ENV
    const publicPath =  map[env]
    const PATH = require('path')
    const WebpackBundleAnalyzerPlugin = require('webpack-bundle-analyzer').BundleAnalyzerPlugin
    
    module.exports = {
        publicPath,
        configureWebpack: {
            externals: {
                "lodash": '_',
                "qiniu": 'qiniu',
                "vue": 'Vue',
                "echarts": 'echarts',
                "element-ui": 'ELEMENT',
            },
            resolve: {
                extensions: ['.js', '.vue', '.json', '.ts', '.tsx'],
                alias: {
                    '$root': PATH.resolve(__dirname)
                }
            },
            plugins: [new WebpackBundleAnalyzerPlugin()]
        }
    }
    

    到这里就所有功能大功告成了,可以美滋滋的去喝一杯咖啡了。

  • 相关阅读:
    C语言I博客作业03
    C语言I博客作业06
    C语言I博客作业01
    C语言I博客作业04
    C语言I博客作业05
    How kNN algorithm works(kNN算法原理讲解)
    《机器学习笔记》环境配置(Windows64位)
    git 命令使用
    关于推荐系统中的冷启动问题探讨(Approaching the Cold Start Problem in Recommender Systems)
    WebForms UnobtrusiveValidationMode 需要“jquery”ScriptResourceMapping。请添加一个名为 jquery (区分大小写)的 ScriptResourceMapping。
  • 原文地址:https://www.cnblogs.com/songbw/p/11807460.html
Copyright © 2011-2022 走看看