contenthash纔是緩存的重要hash - webpack hash contenthash chunkhash你真的懂了嗎?

前言:

webpack已經成爲了目前最流行的打包工具,隨着它的關注度越高,咱們愈來愈關注它的性能優化,如何優化編譯速度,減少打包體積...,這篇文章將講述的是webpack編譯時產生的三種hashjavascript

hash -- 編譯產生

webpack在實例化的時候會在全局建立一個Tapable子類Compiler, 該實例掌握了初始化配置信息,運行編譯入口函數,註冊和調用插件等等。css

每次編譯的時候都會實例化一個對象compilation, 該對象掌控着從編譯開始到編譯結束文件,模塊的加載,封閉,優化,分塊,哈希,重建等等都是由其負責, 此時的hash是由compilation來建立的,也就是說每次編譯都會建立一個新的hash值, 而且全部文件的hash都是同樣的,由於是同一個compilation生成html

第一次構建:java

修改了app.jswebpack

第二次構建:web

咱們能夠看出,全部的文件都發生了變化,壞處:瀏覽器

  1. 編譯時,致使全部文件從新編譯了一次
  2. 沒法利用瀏覽器緩存策略,由於文件從新生成了

chunkhash -- 構建chunk生成

首先, 什麼是chunk?緩存

咱們知道,每一個入口文件都是一個chunk,每一個chunk是由入口文件與其依賴所構成,異步加載的文件也被視爲是一個chunk, chunkhash是由每次編譯模塊,根據模塊及其依賴模塊構成chunk生成對應的chunkhash, 這也就代表了每一個chunk的chunkhash值都不同, 也就是說每一個chunk都是獨立開來的,互不影響,每一個chunk的更新不會影響其餘chunk的編譯構建性能優化

第一次構建 bash

更改入口文件, 第二次構建

能夠看出 main.js發生變化後,0.xxx.js並無發生chunkhash變化,此時瀏覽器就能夠利用緩存機制,對於沒有更改的文件,瀏覽器會從緩存裏取,可有效減少服務器壓力與渲染速度等等

可是, 每一個chunk都是有css與js組成, 也就是說當其中一個文件發生變化,這個chunk都會從新編譯,此時contenthash就出來了。

contenthash

針對文件內容生成不一樣的hash, 只有當文件內容發生變化此hash纔會從新生成,此時須要利用mini-css-extract-plugin插件取提取出每一個chunk的css文件,將css與js隔離開,而後將css更改後

注意點

  1. 輸出js必須也是contenthash結尾, 若是是chunkhash,因爲css已經發生變化了,整個chunk在編譯時仍是會生成新的hash,即便打包出的js內容沒有發生變化
  2. 若是入口文件沒有依賴異步chunk,入口文件以contenthash輸出不會從新編譯,若是入口文件有依賴異步chunk, 那麼無論入口文件以哪一種hash形式輸出,都會從新編譯,由於css contenthash已經發生變化了, 經過異步插入的link標籤所指定的css文件也發生了變化,表明入口文件的內容就發生了變化, 因此無論哪一個hash都會從新編譯, 可是異步chunk不會發生變化

webpack.config.js

const MiniCssExtractPlugin = require('mini-css-extract-plugin')
    const HTMLWebpackPlugin = require('html-webpack-plugin')
    
    module.exports = {
      mode: 'development',
      entry: {
        main: './index.js'
      },
      output: {
        filename: 'js/[name].[chunkhash].js',
        chunkFilename: 'js/[name].[contenthash].js',
        publicPath: './'
      },
      module: {
        rules: [
          {
            test: /\.css$/,
            use: [{
              loader: MiniCssExtractPlugin.loader,
              options: {
                outputPath: 'css/'
              }
            },
            "css-loader"
          ]
          }
        ]
      },
      plugins: [
        new HTMLWebpackPlugin({
          template: 'index.html',
          filename: 'index.html',
        }),
        new MiniCssExtractPlugin({
          // Options similar to the same options in webpackOptions.output
          // both options are optional
          filename: "css/[name].[contenthash].css",
          chunkFilename: "css/[name].[contenthash].css"
        })
      ],
}
複製代碼

index.js

const asyncChunk = () => import('./asyncChunk')
    console.log(asyncChunk, 1);
    
    document.onclick = () => asyncChunk()
複製代碼

asyncChunk.js

import './common.css'

    export default 'asyncChunk'
複製代碼

第一次構建

更改css文件,第二次構建

從上看出,css發生變化後,入口文件與css一塊兒發生了變化,可是引入css的asyncChunk並無從新編譯,此時證實了contenthash緩存成功

總結

contenthash對於緩存更具備意義

相關文章
相關標籤/搜索