оптимизация домашней страницы пакета webpack и маршрутизация ленивой загрузки

Webpack

предисловие

Недавно я сделал небольшой проект vue h5 и обнаружил, что при работе на мобильном телефоне первый раз, когда я заходил на домашнюю страницу, он был медленным, а затем мой коллега упомянул, что cdn можно использовать в производственной среде, поэтому я попробовал.

Открыть cdn в рабочей среде

1. вvue.congfig.jsдобавить внутрь

const isProduction = process.env.NODE_ENV == "production";
 configureWebpack: (config) => {
    if (isProduction) {
      config.externals = {
        vue: "Vue",
        "vue-router": "VueRouter",
        vant: "vant",
        _: "lodash",
      };

Внешние элементы предназначены для того, чтобы внутренняя библиотека не была упакована webapck, и это не влияет на внедрение через импорт (или другие AMD, CMD и т.

2. Вindex.htmlПредставить ресурсы CDN

  <link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/vant@2.8/lib/index.css" />
  <script src="https://cdn.jsdelivr.net/npm/vue@2.6.11"></script>
  <script src="https://unpkg.com/vue-router/dist/vue-router.js"></script>
  <script src="https://cdn.jsdelivr.net/npm/vant@2.8/lib/vant.min.js"></script>
  <script src="https://cdn.bootcdn.net/ajax/libs/lodash.js/4.17.15/lodash.core.min.js"></script> 

3. Оптимизируйте метод письма

// vue.config.js

const cdn = {
  css: ["https://cdn.jsdelivr.net/npm/vant@2.8/lib/index.css"],
  js: [
    "https://cdn.jsdelivr.net/npm/vue@2.6.11",
    "https://unpkg.com/vue-router/dist/vue-router.js",
    "https://cdn.jsdelivr.net/npm/vant@2.8/lib/vant.min.js",
    "https://cdn.bootcdn.net/ajax/libs/lodash.js/4.17.15/lodash.core.min.js",
  ],
};


chainWebpack: (config) => {
    if (isProduction) {
      config.plugin("html").tap((args) => {
        args[0].cdn = cdn;
        return args;
      });
    }
  }
 
 // index.html
   <% for(var i in htmlWebpackPlugin.options.cdn && htmlWebpackPlugin.options.cdn.css){%>
  <link src="<%= htmlWebpackPlugin.options.cdn.css[i] %>"></link>
  <%}%>
  <% for(var i in htmlWebpackPlugin.options.cdn && htmlWebpackPlugin.options.cdn.js){%>
  <script src="<%= htmlWebpackPlugin.options.cdn.js[i] %>"></script>
  <%}%>

До оптимизации

Оптимизировано

включить сжатие gzip


cnpm install compression-webpack-plugin --save-dev 

// vue.config.js
const CompressionPlugin = require("compression-webpack-plugin");

 configureWebpack: (config) => {
    if (isProduction) {
      config.externals = {
        vue: "Vue",
        "vue-router": "VueRouter",
        vant: "vant",
        _: "lodash",
      };
      config.plugins.push(
        new CompressionPlugin({
          algorithm: "gzip",
        })
      );
    }
  },

Отложенная загрузка маршрута

  {
    path: "/index",
    name: "index",
    component: () => import("../views/index.vue"),
    meta: {
      keepAlive: false,
    },
  },

Это часто пишется в обычное время, но вы можете не знать, что это маршрутизация отложенной загрузки.Официальный сайт, на официальном сайте упоминается, что это связано сАсинхронные компонентыРазделение кода с помощью webackcode-splittingфункция, каждый асинхронный маршрут будет упакован в разные фрагменты для обеспечения загрузки по требованию. кроме вышеперечисленногоES2015То, как написан модуль, также имеет

 {
    path: "/index",
    name: "index",
    component: (resolve) => require(["../views/index.vue"], resolve),
    meta: {
      keepAlive: false,
    },
  },

Согласно официальному сайту, сначала создайте возвратPromiseзаводская функция

const Index = () => Promise.resolve({ /* 组件定义对象 */ })

затем используйте动态 importСинтаксис определяет точки разделения для фрагментов кода.

import ('./Index')

Объединив их, вы можете автоматически разделить код

const Index = () => import('../views/index.vue')

Посмотри на это сначалаcode-split,

Затем я пошел посмотреть конкретную конфигурацию vue-cli, маршрут ужеDynamic Import, как указано во втором пункте выше. Следующее дляchunk-vendorsСегментация, как указано в третьем пункте рисунка выше, настраиваетсяsplitChunksдедупликация и сегментацияchunks

оптимизация (одинаковая как для разработки, так и для производства)

optimization:{
      splitChunks: {
        cacheGroups: {  // 缓存组,可以定义多个
          vendors: {     //创建一个 自定义的vendor的chunk
            name: "chunk-vendors",
            test: /[\\\/]node_modules[\\\/]/,  // 匹配node_modules
            priority: -10,  // 理解为缓存的级别
            chunks: "initial",
        },
          common: {
            name: "chunk-common",
            minChunks: 2,  // 分割之前必须共享模块的最小chunk数
            priority: -20,
            chunks: "initial",
            reuseExistingChunk: true,  // 是否复用存在的块
        },
      },
    } 
}
 
  • cacheGroups группу кеша, вы можете определить несколько
 cacheGroups: {
        defaultVendors: {
          test: /[\\/]node_modules[\\/]/,
          priority: -10
        },
        default: {
          minChunks: 2,
          priority: -20,
          reuseExistingChunk: true
        }
      }
  • уровень приоритетной группы кэша

A module can belong to multiple cache groups. The optimization will prefer the cache group with a higher priority. The default groups have a negative priority to allow custom groups to take higher priority (default value is 0 for custom groups)

Перевод, вероятно, в том, что модуль может иметь несколько групп кэша,optimizationБудет выбрана кассовая группа с более высоким приоритетом,default groupимеет отрицательный приоритет и может разрешитьcustom groupИмеет более высокий приоритет (по умолчанию 0). вкратце,custom groupможно сравнить по приоритетуdefault groupвысоко

  • reuseExistingChunk Повторное использование существующих блоков

outputКонфигурация немного другая

// 生产
  output: {
    path:"/dist",
    filename: "static/js/[name].[contenthash:8].js",
    publicPath: "/",
    chunkFilename: "static/js/[name].[contenthash:8].js",  // 生成一个8位的hash值
  }
  
 // 开发
   output: {
    path:"/dist",
    filename: "static/js/[name].js",
    publicPath: "/",
    chunkFilename: "static/js/[name].js",
  }

запустить упаковку

Производственный вывод css, но не среда разработки, считается, что это предложение настроено в продакшене

  // 生产
    new MiniCssExtractPlugin({
      filename: "static/css/[name].[contenthash:8].css",
      chunkFilename: "static/css/[name].[contenthash:8].css",
    })

Тогда вот проблема

  • Как ввести css файлов, упакованных в режиме разработки
  • Почему ссылка упакованного дистрибутива index.html отличается от файла, импортированного тегом script?
  • Разница между предварительной загрузкой и предварительной выборкой
// development
<!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="/favicon.ico">
  <title>南蓝</title>
 
  <link href="/static/js/0.js" rel="prefetch"><link href="/static/js/1.js" rel="prefetch"><link href="/static/js/2.js" rel="prefetch">
  <link href="/static/js/3.js" rel="prefetch">
  <link href="/static/js/app.js" rel="preload" as="script">
  <link href="/static/js/chunk-vendors.js" rel="preload" as="script">
</head>
<body>
  <noscript>
    <strong>We're sorry but f2e-client doesn't work properly without JavaScript enabled.
      Please enable it to continue.</strong>
  </noscript>
  <div id="app"></div>
<script type="text/javascript" src="/static/js/chunk-vendors.js"></script><script type="text/javascript" src="/static/js/app.js"></script></body>

</html>

Давайте взглянем на index.html(production), упакованный в production.

// production
<!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">
   <link rel=icon href=/favicon.ico>
   <title>鸭嘴兽</title>
   <script src=https://cdn.jsdelivr.net/npm/vant@2.8/lib/index.css></script>
   <script src=https://cdn.jsdelivr.net/npm/vue@2.6.11></script>
   <script src=https://unpkg.com/vue-router/dist/vue-router.js></script>
   <script src=https://cdn.jsdelivr.net/npm/vant@2.8/lib/vant.min.js></script>
   <script src=https://cdn.bootcdn.net/ajax/libs/lodash.js/4.17.15/lodash.core.min.js></script>
   <link href=/static/css/chunk-0c3564fc.b3594289.css rel=prefetch>
   <link href=/static/css/chunk-56255d30.c1e34d24.css rel=prefetch>
   <link href=/static/css/chunk-5ba5813d.a56f098f.css rel=prefetch>
   <link href=/static/css/chunk-9945b478.66fcd057.css rel=prefetch>
   <link href=/static/js/chunk-0c3564fc.9d02dfcc.js rel=prefetch>
   <link href=/static/js/chunk-56255d30.d0115acd.js rel=prefetch>
   <link href=/static/js/chunk-5ba5813d.10f75234.js rel=prefetch>
   <link href=/static/js/chunk-9945b478.dc8a4502.js rel=prefetch>
   <link href=/static/css/app.faa29057.css rel=preload as=style>
   <link href=/static/css/chunk-vendors.97c56160.css rel=preload as=style>
   <link href=/static/js/app.5deb2d45.js rel=preload as=script>
   <link href=/static/js/chunk-vendors.158e0179.js rel=preload as=script>
   <link href=/static/css/chunk-vendors.97c56160.css rel=stylesheet>
   <link href=/static/css/app.faa29057.css rel=stylesheet>
</head>

<body>
<noscript><strong>We're sorry but f2e-client doesn't work properly without JavaScript enabled. Please enable it to
           continue.</strong></noscript>
   <div id=app></div>
   <script src=/static/js/chunk-vendors.158e0179.js></script>
   <script src=/static/js/app.5deb2d45.js></script>
</body>

</html>
  • Почему некоторые js импортируются с тегами ссылок, а некоторые импортируются с тегами scipt
  • Почему атрибут as ссылки иногда недоступен?

Извлеките vue-cli, чтобы настроить параметры веб-пакета

开发换环境 npx vue-cli-service inspect --mode development  webpack.config.development.js
生产环境:npx vue-cli-service inspect --mode production  webpack.config.production.js

Как бы ни менялось переднее колесо, оно остается прежним, а значит,html,css,js,все вернусь к сути,те вопросы которые я поднял,надеюсь в следующей статье разберутся,есть ошибки или предложения можно поднять