Resumen de notas del paquete web (2)

En tercer lugar, el concepto avanzado de paquete web

1.Concepto de agitación de árboles

La agitación de árboles en el front-end puede entenderse como "agitar" nuestros archivos JS a través de herramientas y "sacudir" el código no utilizado, que es una categoría de optimización del rendimiento. Específicamente, en el proyecto de paquete web, hay un archivo de entrada, que es equivalente a la columna vertebral de un árbol, y el archivo de entrada tiene muchos módulos dependientes, que son equivalentes a ramas. En la situación real, aunque se confía en un determinado módulo, solo se utilizan determinadas funciones. A través de la agitación de árboles, se sacuden los módulos no utilizados, para lograr el propósito de eliminar el código inútil.

Tree Shaking solo es compatible con el módulo ES

¿Cómo configurar?

En entorno de desarrollo

// webpack.config.js
optimization: {
    
    
  usedExports: true
}
// package.json
"sideEffect": false,
// "sideEffect": ["*.css"] 不希望tree-shaking的配置在这里

En el entorno de producción, configure automáticamente la agitación de árboles

2. Diferenciación y empaquetado de los modos Dev y Prod

En el entorno de desarrollo y el entorno de generación, existen diferencias entre source-map, DevServer, HMR, compresión, etc.

Distinguir el funcionamiento de dos entornos.

package.json

{
    
    
  "scripts": {
    
    
    "dev": "webpack-dev-server --config webpack.dev.js",
    "build": "webpack --config webpack.prod.js"
  },
}

Cree dos nuevos archivos webpack.dev.js y webpack.prod.js

¡Pero hay mucho del mismo código!

Resolver extracción de piezas públicas

Extraiga la parte común a webpack.common.js

const path = require('path');
const HtmlWebpackPlugin = require('html-webpack-plugin');
const {
    
     CleanWebpackPlugin } = require('clean-webpack-plugin');
module.exports = {
    
    
  entry: {
    
    
    main: './src/index.js'
  },
  output: {
    
    
    publicPath: '/',
    filename: '[name].js',
    path: path.join(__dirname, 'dist')
  },
  module: {
    
    
    rules: [
      {
    
    
        test: /\.css$/,
        use: ['style-loader', 'css-loader']
      },
      {
    
    
        test: /\.js$/,
        exclude: /node_modules/,
        use: {
    
    
          loader: 'babel-loader',
          options: {
    
    
            presets: [
              [
                '@babel/preset-env',
                {
    
    
                  useBuiltIns: 'usage',
                  targets: {
    
    
                    edge: '17',
                    firefox: '60',
                    chrome: '67',
                    safari: '11.1'
                  }
                }
              ]
            ]
          }
        }
      }
    ]
  },
  plugins: [
    new HtmlWebpackPlugin({
    
    
      template: 'src/index.html'
    }),
    new CleanWebpackPlugin()
  ],
};

Instalar webpack-merge

npm install webpack-merge -D

Reescribe webpack.prod.js

const {
    
     merge } = require('webpack-merge');
const commonConfig = require('./webpack.common.js');

const prodConfig = {
    
    
  mode: 'production'
};

module.exports = merge(commonConfig, prodConfig);

Reescribe webpack.dev.js

const webpack = require('webpack');
const {
    
     merge } = require('webpack-merge');
const commonConfig = require('./webpack.common.js');

const devConfig = {
    
    
  mode: 'development',
  devtool: 'source-map',
  devServer: {
    
    
    contentBase: './dist'
    // hot: true,
    // hotOnly: true
  },
  plugins: [new webpack.HotModuleReplacementPlugin()],
  optimization: {
    
    
    usedExports: true
  }
};

module.exports = merge(commonConfig, devConfig);

3.Webpack 和 División de código

División de código

En el pasado, para reducir las solicitudes HTTP, generalmente empaquetamos todo el código en un solo archivo JS. Sin embargo, si el tamaño del archivo JS es muy grande, la ganancia no vale la pena perder.

En este momento, también podríamos dividir todo el código en una sola pieza y cargarlo cuando se necesite una determinada pieza de código; también puede usar el caché del navegador y, si lo usa la próxima vez, puede leerlo directamente desde el cache. Obviamente, este enfoque puede acelerar la velocidad de carga de nuestras páginas web.

Entonces, Code Splitting en realidad está dividiendo el código en muchos, muchos fragmentos .

Configuración

optimization: {
    
    
  splitChunks: {
    
    
    chunks: 'all'
  }
}

Luego generará main.js y vendors ~ main.js

Código asincrónico

function getComponent() {
    
    
  return import('lodash').then(({
    
     default: _ }) => {
    
    
    var element = document.createElement('div');
    element.innerHTML = _.join(['Dell', 'Lee'], '-');
    return element;
  });
}

getComponent().then(element => {
    
    
  document.body.appendChild(element);
});

La segmentación de código no tiene nada que ver con el paquete web. Hay dos formas de implementar la segmentación de código en el paquete web.

1. Código síncrono: solo es necesario realizar la configuración de optimización en webpack.common.js

2. Código asincrónico (importación): el código asincrónico, sin ninguna configuración, dividirá automáticamente el código

4. Detalles de configuración del parámetro SplitChunkPlugin de segmentación de código

Configuración de SplitChunkPlugin

Notas mágicas

return import(/* webpackChunkName: "lodash" */'lodash')

Esto generará el archivo vendor ~ lodash.js

El nombre del archivo generado por el paquete es el mismo que el nombre especificado

optimization: {
    
    
  splitChunks: {
    
    
    cacheGroups: {
    
    
      vendors: false,
      default: false
    }
  }
}

asignación predeterminada

module.exports = {
    
    
  //...
  optimization: {
    
    
    splitChunks: {
    
    
      // chunks:async只对异步代码进行代码分割,all会同步异步都分割
      // 我们打包一个同步代码块,会寻找vendors配置,如果在node_modules中,会进行分割
      chunks: 'async',
      // 大于30kb,进行代码分割
      minSize: 30000,
      maxSize: 0,
      // 至少用几次才会被分割
      minChunks: 1,
      maxAsyncRequests: 5,
      maxInitialRequests: 3,
      automaticNameDelimiter: '~',
      name: true,
      // =>缓存组
      cacheGroups: {
    
    
         // 不同的组
        vendors: {
    
    
          test: /[\\/]node_modules[\\/]/,
          // 优先级
          priority: -10
        },
        default: {
    
    
          minChunks: 2,
          priority: -20,
          // 重用现有模块
          reuseExistingChunk: true
        }
      }
    }
  }
};

Carga diferida Carga diferida, ¿qué es un fragmento?

Carga diferida: carga un módulo de forma asincrónica a través de import ()

import () devuelve un tipo de promesa

function getComponent() {
    
    
  return import(/* webpackChunkName: "lodash-dj" */ 'lodash').then(
    ({
    
     default: _ }) => {
    
    
      var element = document.createElement('div');
      element.innerHTML = _.join(['Dell', 'Lee'], '-');
      return element;
    }
  );
}

document.addEventListener('click', () => {
    
    
  getComponent().then(element => {
    
    
    document.body.appendChild(element);
  });
});

async aguardar reescribir

async function getComponent() {
    
    
  const {
    
     default: _ } = await import(
    /* webpackChunkName: "lodash-dj" */ 'lodash'
  );
  var element = document.createElement('div');
  element.innerHTML = _.join(['Dell', 'Lee'], '-');
  return element;
}

document.addEventListener('click', async () => {
    
    
  const element = await getComponent();
  document.body.appendChild(element);
})

pedazo

Cada archivo js generado por el empaquetado se llama fragmento

// 简易配置代码分割,交给webpack自动处理
optimization: {
    
    
  splitChunks: {
    
    
    chunks: 'all',
  }
}

6. Análisis de embalaje, precarga, precarga

Análisis de paquetes

paquete web github / analizar

# 输出打包信息到 stats.json
webpack --profile --json > stats.json --config webpack.dev.js

Uso de la herramienta Webpack-bundle-analyzer

Instalar en pc

npm install --save-dev webpack-bundle-analyzer

Uso (como complemento)

const BundleAnalyzerPlugin = require('webpack-bundle-analyzer')
plugins: [
  new BundleAnalyzerPlugin()
]

Una vez completado el empaque, abra automáticamente 127.0.0.1:8888 para ver el análisis

Precarga 和 Precarga

Referencia al texto original: hablar sobre la precarga y la precarga en el paquete web

Documento oficial: módulo de precarga / precarga

Presione en el navegador Ctrl + Shift + Pe ingrese en el cuadro de diálogo emergentecoverage

Desde el cuadro rojo, puede ver la utilización del archivo cargado actualmente en la página actual

A través de la carga asincrónica, mejore la utilización del código, al cargar la página actual, cargue de forma asincrónica código innecesario

Ahora vemos por qué webopack quiere usar chunks: 'async'una configuración predeterminada.

El enfoque de la optimización del paquete web es el uso del código en lugar del almacenamiento en caché. No tiene sentido usar el almacenamiento en caché para optimizar. Solo mejorando de forma asincrónica la utilización del código se puede mejorar en gran medida el rendimiento del sitio web.

Algunos amigos pueden preguntarse si pueden cargar estos archivos primero cuando la red está inactiva después de cargar la página . Es realmente inteligente. Esta es la precarga y la precarga de la que hablaré a continuación.

  • Precarga

    El uso es relativamente simple, es decir, delante del archivo que se va a cargar de forma asincrónica, además /* webpackPrefetch: true */del comentario mágico.

    Podemos escribir código que requiera interacción para ser utilizado en componentes asincrónicos.

    document.addEventListener('click', () => {
          
          
      import(/* webpackPrefetch: true */ './click.js').then(({
          
          default: func}) => {
          
          
        func();
      })
    });
    

    El 0.js generado es click.js después del empaquetado. Se puede ver que 0.js se ha cargado antes de que se haga clic en la página en el tiempo libre después de que se cargue la página. Cuando se hace clic en la página, se lee directamente 0.js de la caché, por lo que el tiempo es muy corto.

  • ¿Cuál es la diferencia entre precarga y precarga?

    La mayor diferencia entre los dos es que la precarga se carga cuando el ancho de banda está libre después de que se carga el código central, mientras que la precarga se carga junto con el archivo de código central.

Por lo tanto, es más apropiado utilizar Prefetching para cargar archivos asincrónicos.

7. Segmentación de código de archivos CSS

MiniCssExtractPlugin

8. Paquete web y caché de caché del navegador

entorno de producción

output: {
    
    
  filename: '[name].[contenthash].js',
  chunkFilename: '[name].[contenthash].js'
}

Mientras no necesitemos el código fuente, el valor del archivo no cambiará y el usuario utilizará la caché local para la segunda visita.

Cambios en el código fuente, cambios en el valor hash

Es propicio para la optimización de volver a poner el paquete en línea

9.

Libro corto: calce (calce) compatible con empaquetado webpack

10. Uso de variables ambientales

Supongo que te gusta

Origin blog.csdn.net/weixin_43792004/article/details/112759636
Recomendado
Clasificación