webpack緩存

来源:https://www.cnblogs.com/pluslius/archive/2018/11/11/9941642.html
-Advertisement-
Play Games

緩存 緩存如何工作 web中的緩存 web緩存的優勢 web緩存的問題 webpack緩存原理 可以通過命中緩存,以降低網路流量,使網站載入速度更快,然而,如果我們在部署新版本時不更改資源的文件名,瀏覽器可能會認為它沒有被更新,就會使用它的緩存版本。由於緩存的存在,當你需要獲取新的代碼時,就會顯得很 ...


緩存

緩存如何工作

1.當緩存客戶端需要訪問數據時,它首先檢查緩存。當在緩存中找到所請求的數據時,它被稱為緩存命中。

2.如果在緩存中找不到請求的數據 , 稱為緩存未命中的情況,它將從主存儲器中提取並複製到緩存中。如何完成此操作以及從緩存中彈出哪些數據以便為新數據騰出空間取決於系統使用的緩存演算法或策略。

web中的緩存

1. 使用瀏覽器緩存來提高經常訪問的網頁的性能。當您訪問網頁時,請求的文件將存儲在瀏覽器緩存中的計算存儲中。

2. 單擊返回並返回上一頁使您的瀏覽器能夠從緩存中檢索所需的大多數文件,而不是從Web伺服器中重新發送它們。這種方法稱為讀緩存。瀏覽器可以比從網頁重新讀取文件更快地從瀏覽器緩存中讀取數據。

web緩存的優勢

Web內容可以緩存在客戶端、代理伺服器以及伺服器端。研究表明,緩存技術可以顯著地提高WWW性能,它可以帶來以下好處:
(1)減少網路流量,從而減輕擁塞。
(2)降低客戶訪問延遲,其主要原因有:①緩存在代理伺服器中的內容,客戶可以直接從代理獲取而不是從遠程伺服器獲取,從而減小了傳輸延遲②沒有被緩存的內容由於網路擁塞及伺服器負載的減輕而可以較快地被客戶獲取。
(3)由於客戶的部分請求內容可以從代理處獲取,從而減輕了遠程伺服器負載。
(4)如果由於遠程伺服器故障或者網路故障造成遠程伺服器無法響應客戶的請求,客戶可以從代理中獲取緩存的內容副本,使得WWW服務的魯棒性得到了加強。

web緩存的問題

Web緩存系統也會帶來以下問題:
(1)客戶通過代理獲取的可能是過時的內容。
(2)如果發生緩存失效,客戶的訪問延遲由於額外的代理處理開銷而增加。因此在設計Web緩存系統時,應力求做到Cache命中率最大化和失效代價最小化。
(3)代理可能成為瓶頸。因此應為一個代理設定一個服務客戶數量上限及一個服務效率下限,使得一個代理系統的效率至少同客戶直接和遠程伺服器相連的效率一樣。

webpack緩存原理

可以通過命中緩存,以降低網路流量,使網站載入速度更快,然而,如果我們在部署新版本時不更改資源的文件名,瀏覽器可能會認為它沒有被更新,就會使用它的緩存版本。由於緩存的存在,當你需要獲取新的代碼時,就會顯得很棘手。通過必要的配置,以確保 webpack 編譯生成的文件能夠被客戶端緩存,而在文件內容變化後,能夠請求到新的文件。

1.第一步output.filename確保瀏覽器能夠獲取到修改後的文件,原理是[chunkhash]演算法,這樣做是有問題的,這是由於webpack內部的chunk變化引起的

  const path = require('path');
  const CleanWebpackPlugin = require('clean-webpack-plugin');
  const HtmlWebpackPlugin = require('html-webpack-plugin');

  module.exports = {
    entry: './src/index.js',
    plugins: [
      new CleanWebpackPlugin(['dist']),
      new HtmlWebpackPlugin({
-       title: 'Output Management'
+       title: 'Caching'
      })
    ],
    output: {
-     filename: 'bundle.js',
+     filename: '[name].[chunkhash].js',
      path: path.resolve(__dirname, 'dist')
    }
  };

2.通過提取模版(Extracting Boilerplate)將 webpack 的樣板(boilerplate)和 manifest 提取出來。分離到單獨的文件中。這樣多次構建manifest文件都不會產生變化,以此來提高緩存命中率,我們還可以將vendor第三方包也打包到單獨的文件中來提高命中率,但是hash還是變化了,不著急

const path = require('path');
+ const webpack = require('webpack');
  const CleanWebpackPlugin = require('clean-webpack-plugin');
  const HtmlWebpackPlugin = require('html-webpack-plugin');

  module.exports = {
    entry: './src/index.js',
    plugins: [
      new CleanWebpackPlugin(['dist']),
      new HtmlWebpackPlugin({
        title: 'Caching'
-     })
+     }),
+     new webpack.optimize.CommonsChunkPlugin({
+       name: 'manifest'
+     })
    ],
    output: {
      filename: '[name].[chunkhash].js',
      path: path.resolve(__dirname, 'dist')
    }
  };
  
3.將第三方庫(library)(例如 lodash 或 react)提取到單獨的 vendor chunk 文件中,是比較推薦的做法,這是因為,它們很少像本地的源代碼那樣頻繁修改。因此通過實現以上步驟,利用客戶端的長效緩存機制,可以通過命中緩存來消除請求,並減少向伺服器獲取資源,同時還能保證客戶端代碼和伺服器端代碼版本一致。這可以通過使用新的 entry(入口) 起點,以及再額外配置一個 CommonsChunkPlugin 實例的組合方式來實現:

 var path = require('path');
  const webpack = require('webpack');
  const CleanWebpackPlugin = require('clean-webpack-plugin');
  const HtmlWebpackPlugin = require('html-webpack-plugin');

  module.exports = {
-   entry: './src/index.js',
+   entry: {
+     main: './src/index.js',
+     vendor: [
+       'lodash'
+     ]
+   },
    plugins: [
      new CleanWebpackPlugin(['dist']),
      new HtmlWebpackPlugin({
        title: 'Caching'
      }),
+     new webpack.optimize.CommonsChunkPlugin({
+       name: 'vendor'
+     }),
      new webpack.optimize.CommonsChunkPlugin({
        name: 'manifest'
      })
    ],
    output: {
      filename: '[name].[chunkhash].js',
      path: path.resolve(__dirname, 'dist')
    }
  };

模塊標識符(Module Identifiers)

每個 module.id 會基於預設的解析順序(resolve order)進行增量。也就是說,當解析順序發生變化,ID 也會隨之改變。

當前模塊的 ID。module.id === require.resolve("./file.js")

由於修改了module.id的值,vendor分配到的id也發生了變化

main bundle 會隨著自身的新增內容的修改,而發生變化。
vendor bundle 會隨著自身的 module.id 的修改,而發生變化。
manifest bundle 會因為當前包含一個新模塊的引用,而發生變化。

修改文件前id增量變化
   [1] ./src/index.js 336 bytes {1} [built]
   [2] (webpack)/buildin/global.js 509 bytes {0} [built]
   [3] (webpack)/buildin/module.js 517 bytes {0} [built]
  == [4] multi lodash 28 bytes {0} [built]==
修改文件後id增量變化,發現lodash解析順序變化了,4變成了5
   [1] ./src/index.js 421 bytes {1} [built]
   [2] (webpack)/buildin/global.js 509 bytes {0} [built]
   [3] (webpack)/buildin/module.js 517 bytes {0} [built]
   [4] ./src/print.js 62 bytes {1} [built]
   ==[5] multi lodash 28 bytes {0} [built]==
   


可以使用兩個插件來解決這個問題。第一個插件是 NamedModulesPlugin,將使用模塊的路徑,而不是數字標識符。雖然此插件有助於在開發過程中輸出結果的可讀性,然而執行時間會長一些。第二個選擇是使用 HashedModuleIdsPlugin,推薦用於生產環境構建:

 const path = require('path');
  const webpack = require('webpack');
  const CleanWebpackPlugin = require('clean-webpack-plugin');
  const HtmlWebpackPlugin = require('html-webpack-plugin');

  module.exports = {
    entry: {
      main: './src/index.js',
      vendor: [
        'lodash'
      ]
    },
    plugins: [
      new CleanWebpackPlugin(['dist']),
      new HtmlWebpackPlugin({
        title: 'Caching'
      }),
+     new webpack.HashedModuleIdsPlugin(),
      new webpack.optimize.CommonsChunkPlugin({
        name: 'vendor'
      }),
      new webpack.optimize.CommonsChunkPlugin({
        name: 'manifest'
      })
    ],
    output: {
      filename: '[name].[chunkhash].js',
      path: path.resolve(__dirname, 'dist')
    }
  };

修改前: 修改前,後完全保持一致
  [3Di9] ./src/print.js 62 bytes {1} [built]
  [3IRH] (webpack)/buildin/module.js 517 bytes {0} [built]
  [DuR2] (webpack)/buildin/global.js 509 bytes {0} [built]
   ==[0] multi lodash 28 bytes {0} [built]==
  [lVK7] ./src/index.js 421 bytes {1} [built]
  
修改後:
  [3IRH] (webpack)/buildin/module.js 517 bytes {0} [built]
  [DuR2] (webpack)/buildin/global.js 509 bytes {0} [built]
  == [0] multi lodash 28 bytes {0} [built]==
  [lVK7] ./src/index.js 427 bytes {1} [built]

您的分享是我們最大的動力!

-Advertisement-
Play Games
更多相關文章
  • 主要的信息都是來自於下方所示的網站 https://webpack.docschina.org/configuration 從 webpack 4.0.0 版本開始,可以不用通過引入一個配置文件打包項目。然而,webpack 仍然還是高度可配置的 ,並且能夠很好的滿足需求。 首先總結下個人理解的,w ...
  • 最近碰到的問題,有個數組,數組元素是對象,該對象的結構就如樹的parent表示法的節點一樣。形象點講就是該數組存放了樹的所有“葉子節點”,並且葉子節點記憶體有父節點,一直到根節點為止,就如存了一條從葉子節點到根節點路徑。 現在有要求是將這個數組轉成一個children表示法的對象,即從根節點開始,每個 ...
  • 標題標簽h1~h6 顧名思義,這些就是把字體設置為大字體的,就如博客園的這個編輯器里的格式: 不信的話我們自己設置看看:好的,從本篇文章開始,我們需要動手了 ...
  • 我們都知道在React中使用函數時,有兩種寫法,一是回調函數,二是直接調用,但需要在構造函數中綁定this,只有這樣,函數中的this才指向本組件 總結一下沒有綁定this的函數中的this指向 不管是在本組件的元素上調用的函數還是傳遞給子組件的函數,不管有沒有綁定this,它們調用的都是本組件里的 ...
  • 因為沒有學過其他編程語言,因此作為我的第一門編程“母語”我在這就不舉其他編程語言的例子了,JavaScript這個動態類型腳本語言的變數號稱是沒有類型的,那麼我們怎麼轉換他的變數呢?而且還要強行轉換。 JavaScript的變數的確是沒有類型的,就是說你用var聲明變數後,可以隨便給變數賦值,不會有 ...
  • 在React中,解耦了對DOM元素的操作,但有時我們確實需要對DOM操作,比如設置元素的滾動條,這時ref就滿足了我們的需求 在低版本的react中,ref可以是一個string類型的屬性,通過this.refs.[refString]來獲取相應的DOM元素,但在高版本的react中已被棄用 在高版 ...
  • 在IE6中對圖片格式png24支持度不高,如果使用的圖片格式是png24,則會導致透明效果無法正常顯示 解決方法: 1.可以使用png8來代替png24,即可解決問題,但是使用png8代替png24以後,圖片的清晰圖會有所下降 2.使用JavaScript來解決該問題,需要向頁面中引入一個外部的Ja ...
  • 本節內容簡單介紹下html都有哪些標簽 還是百度首頁,查看源代碼看看: 我把源代碼複製下來另存為html文件里: 註意:網頁文件的尾碼都是html或者htm 我這用的pycharm編輯器(Python編輯器,也可以編輯web頁面),編輯器有很多種,比如notepad... ...
一周排行
    -Advertisement-
    Play Games
  • 示例項目結構 在 Visual Studio 中創建一個 WinForms 應用程式後,項目結構如下所示: MyWinFormsApp/ │ ├───Properties/ │ └───Settings.settings │ ├───bin/ │ ├───Debug/ │ └───Release/ ...
  • [STAThread] 特性用於需要與 COM 組件交互的應用程式,尤其是依賴單線程模型(如 Windows Forms 應用程式)的組件。在 STA 模式下,線程擁有自己的消息迴圈,這對於處理用戶界面和某些 COM 組件是必要的。 [STAThread] static void Main(stri ...
  • 在WinForm中使用全局異常捕獲處理 在WinForm應用程式中,全局異常捕獲是確保程式穩定性的關鍵。通過在Program類的Main方法中設置全局異常處理,可以有效地捕獲並處理未預見的異常,從而避免程式崩潰。 註冊全局異常事件 [STAThread] static void Main() { / ...
  • 前言 給大家推薦一款開源的 Winform 控制項庫,可以幫助我們開發更加美觀、漂亮的 WinForm 界面。 項目介紹 SunnyUI.NET 是一個基於 .NET Framework 4.0+、.NET 6、.NET 7 和 .NET 8 的 WinForm 開源控制項庫,同時也提供了工具類庫、擴展 ...
  • 說明 該文章是屬於OverallAuth2.0系列文章,每周更新一篇該系列文章(從0到1完成系統開發)。 該系統文章,我會儘量說的非常詳細,做到不管新手、老手都能看懂。 說明:OverallAuth2.0 是一個簡單、易懂、功能強大的許可權+可視化流程管理系統。 有興趣的朋友,請關註我吧(*^▽^*) ...
  • 一、下載安裝 1.下載git 必須先下載並安裝git,再TortoiseGit下載安裝 git安裝參考教程:https://blog.csdn.net/mukes/article/details/115693833 2.TortoiseGit下載與安裝 TortoiseGit,Git客戶端,32/6 ...
  • 前言 在項目開發過程中,理解數據結構和演算法如同掌握蓋房子的秘訣。演算法不僅能幫助我們編寫高效、優質的代碼,還能解決項目中遇到的各種難題。 給大家推薦一個支持C#的開源免費、新手友好的數據結構與演算法入門教程:Hello演算法。 項目介紹 《Hello Algo》是一本開源免費、新手友好的數據結構與演算法入門 ...
  • 1.生成單個Proto.bat內容 @rem Copyright 2016, Google Inc. @rem All rights reserved. @rem @rem Redistribution and use in source and binary forms, with or with ...
  • 一:背景 1. 講故事 前段時間有位朋友找到我,說他的窗體程式在客戶這邊出現了卡死,讓我幫忙看下怎麼回事?dump也生成了,既然有dump了那就上 windbg 分析吧。 二:WinDbg 分析 1. 為什麼會卡死 窗體程式的卡死,入口門檻很低,後續往下分析就不一定了,不管怎麼說先用 !clrsta ...
  • 前言 人工智慧時代,人臉識別技術已成為安全驗證、身份識別和用戶交互的關鍵工具。 給大家推薦一款.NET 開源提供了強大的人臉識別 API,工具不僅易於集成,還具備高效處理能力。 本文將介紹一款如何利用這些API,為我們的項目添加智能識別的亮點。 項目介紹 GitHub 上擁有 1.2k 星標的 C# ...