webpack優化

優化方向

在這里插入圖片描述

熱更新

概念

/**

  • hmr: hot module replacement 熱模塊替換 / 模塊熱更新
  • 作用: 一個模塊發生改變,只會重新打包這一個模塊(而不是打包所有模塊),極大的提升了構建速度
  • 樣式文件: 可以使用hmr功能: style-loader內部實現了熱更新功能
  • js文件:默認沒有這個功能(會全量刷新)—> 修改js代碼,只能處理非入口文件
  • html文件: 默認沒有這個功能(會全量刷新)因為項目中只有一個html文件,所以我們不需要做熱更新
    */

實現

因為我們在開發環境使用的是webpack-dev-server,所以不需要額外的添加代碼,hot默認值為true,自動會熱更新。但是對于js我們需要額外的處理。
// 在入口文件中寫如下代碼

if (module.hot) {// 一旦 module.hot為true, 說明開啟了熱更新功能,--》讓hmr功能代碼生效module.hot.accept('./print.js',function() {// 方法會監聽到print.js文件的變化,一旦發生變化,其他模塊不會重新打包構建// 會執行回調函數print();})
}

source-map

是一種提供源代碼到構建后代碼的一種映射技術(如果構建后代碼出錯了,通過映射關系,可以追蹤到源代碼的錯誤)。

  1. 配置
  /*** 是一種提供源代碼到構建后代碼的一種映射技術(如果構建后代碼出錯了,通過映射關系,可以追蹤到源代碼的錯誤)。* [inline-|hidden-|eval-][nosources-][cheap-[module-]]source-map* source-map: 外聯   錯誤代碼的準確信息和源代碼的錯誤位置* inline-source-map: 內聯 (只生成一個source-map)  錯誤代碼的準確信息和源代碼的錯誤位置* hidden-source-map: 外聯    錯誤代碼的原因,但沒有錯誤代碼的位置,不能追蹤源代碼的錯誤,只能提示構建代碼的位置 (防止代碼泄露)* eval-source-map: 內聯 (每個文件都生成一個source-map,都在eval中)   錯誤代碼的準確信息和源代碼的錯誤位置* nosources-source-map 外聯  錯誤代碼準確信息,但沒有任何源代碼信息 * cheap-source-map  外聯   錯誤代碼的準確信息和源代碼的錯誤位置 只能精確到行,不能精確到列* cheap-module-source-map 外聯  錯誤代碼的準確信息和源代碼的錯誤位置  module會將loader的source-map加入* * 內聯和外聯的區別:1. 外聯生成了文件,內聯沒有 2.內聯構建速度更快* * 使用:* 開發環境:* 速度快, (eval > inline > cheap) eval-cheap-source-map:速度最快 * 調試更友好 * source-map* cheap-module-source-map* cheap-source-map* *  ----> 開發環境使用:eval-source-map / eval-cheap-module-source-map* 生產環境:源代碼要不要隱藏,調試要不要更友好* 內聯會讓包的體積非常大,所以生產環境一般不用內聯* * 隱藏: * nosources-source-map (全部隱藏)*  hidden-source-map (部分隱藏)* 生產環境使用:source-map / cheap-module-source-map*  */  devtool: 'source-map'

oneOf

  • 使用
module:{rules:[{oneOf: [// loader ]}]
}

正常情況中我們每個文件都會被所有的loader“處理一下”,但是在oneOf中的loader,他匹配到之后就不會接著執行下面的loader了,所以oneOf,**可以提升構建速度 **,當一類文件,配置了多個的情況下,可以將其他的放到oneOf外面處理

緩存

  1. babel緩存

就是要在babel下,添加 cacheDirectory: true, 個人實驗沒啥效果(構建速度提升不明顯)

 {//  1. js兼容性處理: babel-loader @babel/core  @babel/preset-env//  問題:babel只能轉換基礎的語法,如promise則不能進行轉換//  2. 全部兼容  @babel/polyfill//  問題:可以解決兼容性問題,但是引入了所有的兼容性代碼,體積太大//  3. 需要做兼容性的處理就ok,按需加載---> core-jstest: /\.js$/,exclude: /node_modules/,loader: 'babel-loader',options: {// 預設: 指示babel做怎樣的兼容性處理presets: [['@babel/preset-env',{useBuiltIns: 'usage', //按需加載corejs: {version: 3, // 指定core-js版本},targets: {  // 指定兼容瀏覽器版本chrome: '60',firefox: '60',ie: '9',safari: '10',edge: '17'}}]],// 開啟babel緩存,第二次構建,會讀取之前的緩存cacheDirectory: true,}},
  1. 全局加cache ,構建速度顯著提升(從2778ms–>419ms)
module.export = {cache: {type: 'filesystem',allowCollectingMemory: true,},
}
  1. 文件資源緩存,提升線上訪問速度
// 通過修改文件名來實現緩存的效果,輸出文件全部加上[contenthash:10]/*** 緩存* babel緩存:cacheDirectory:true  --》讓代碼第二次構建打包速度更快*  文件資源緩存*  hash: 每次webpack構建時會生成一個唯一的hash值*   問題: js和css同時使用一個hash值*   如何重新打包,會導致所有的緩存失效*   chunkhash: 根據chunk生成的hansh值,如果打包來源于同一個chunk,那么hash值就一樣    chunkid modeid*   contenthash: 文件內容不變,hash值不變  ---》讓代碼線上運行緩存更好使用* */ 
例如:output: {filename: 'budle.[contenthash:10].js',path: resolve(__dirname,'build')},

tree sharking

去掉沒有用的代碼,只留下引用了的代碼,減小代碼體積。

/***  tree shaking 去除無用代碼*  前提: 1. 必須使用es6模塊化(使用import export 導入導出)  2. 開啟production環境*  在package.json中配置*   "sideEffects": false 所有代碼都沒有副作用(度可以進行tree shaking)*   問題: 可能會把css /  @babel/polyfill 文件干掉*   解決:"sideEffects": ["*.css"]*   在sideEffects配置不需要刪除的代碼* */ 

code split

  1. 多入口

適合多頁面開發

entry: {main: './src/index.js',test: './src/print.js'
}
output: {filename: '[name].[contenthash:10].js', // 這里的【name】,在入口文件中配置了, main test將成為文件名path: resolve(__dirname,'build');
}
  1. chunk
 // 將node_modules中代碼單獨打包成一個chunk最終輸出  //  自動分析多入口chunk中有沒有公共的文件,如果有會打包成單獨一個chunkoptimization: {splitChunks: {chunks: 'all'}}
  1. import

注意:!!! 如果你配置了eslint,可能會報錯,因為eslint不能夠解析import動態引入的語法,不報錯的話就不需要使用babel-eslint。

// 通過js代碼,讓某個文件單獨被打包成一個chunk
// import動態導入
import(/* webpackChunkName: 'test' */'./print').then(({print,mul}) => {console.log(3, 6);
}).catch(e) {console.log("文件加載失敗",e)
}

下載
npm i -D babel-eslint

在package.json文件中加入parser配置

 "eslintConfig": {"extends": "airbnb-base","parser": "babel-eslint","parserOptions": {"sourceType": "module", "allowImportExportEverywhere": true }},

懶加載

  1. 將import動態引入放入異步函數中
document.querySelector('#btn').onclick = function() {import(/*webpackChunkName: 'test'*/'./print').then(({mul}) => {console.log(mul(4, 5));}).catch((err) => {console.log(err)})
}

預加載

document.querySelector('#btn').onclick = function() {
// 懶加載: 當文件需要使用才加載
// prefetch: 預加載,提前加載js文件  等其他資源加載完畢,瀏覽器空閑了,在偷偷加載資源
// 正常加載:可以認為是并行加載(同一時間加載多個js文件)
import(/* webpackChunkName: 'test',webpackPrefetch: true */'./print')
.then(({ mul }) => {console.log(mul(3, 9));
})
.catch((e) => {console.log('文件加載失敗',e);
})
}

PWA

  1. 下載插件

npm i -D workbox-webpack-plugin

  1. 代碼 webpack.config.js中
/*** PWA: 漸進式網絡開發應用程序(離線可訪問)* workbox --> workbox-webpack-plugin*/
const WorkboxWebpackPlugin = require('workbox-webpack-plugin');
plugins: [// 生成一個serviceworker配置文件new WorkboxWebpackPlugin.GenerateSW({clientsClaim: true,  // 幫助serviceworker快速啟動skipWaiting: true, // 刪除舊的 serviceworker  })
]
  1. 入口文件
//  注冊serviceworker
//  處理兼容性問題
// eslint不認識window navigator全局變量
// 解決: 修改package.json中的eslintConfig配置
//  "env": {
//    "browser": true
//  }
// servicework代碼必須構建在服務器上
if ('serviceWorker' in navigator) {window.addEventListener('load',() => {navigator.serviceWorker.register('/service-worker.js').then(() => {console.log('serviceWorker注冊成功')}).catch(() => {console.log('serviceWorker注冊失敗~')})})
}
  1. package.json文件中
"eslintConfig": {..."env": {"browser": true}},

多進程開發

  1. 下載

npm i thread-loader -D

  1. 代碼
/*** 開啟多進程打包                         * 進程啟動大概600ms,進程通信也有開銷                           * 只有工作消耗時間比較長,才需要多進程打包 * 一般用來處理js文件消耗比較大的時候使用* */                          
{loader: 'thread-loader',options: {workers: 3,}
},

externals

讓一些額外的包,不打包到build.js中

externals: {jquery: '$', // 外部可以通過$直接訪問,不需要引入了
},

index.html中引入jquery文件

 <scriptsrc="https://code.jquery.com/jquery-3.1.0.js"integrity="sha256-slogkvB1K3VOkzAI8QITxV3VzpOnkeNVsKvtkYLMjfk="crossorigin="anonymous"></script>

dll

  1. 根目錄下創建webpack.dll.js文件
/*** 使用dll技術,對某些庫(第三方庫: jquery, react, vue...)進行單獨打包* 當運行webpack時默認查找webpack.config.js配置文件* 需求: 我們需要運行webpack.dll.js文件    webpack --config ./webpack.dll.js* */ 
const { resolve } = require('path');
const webapck = require('webpack');module.exports = {entry: {// 最終打包生成的[name] ---> jqueryjquery: ['jquery']},output: {filename: '[name].js',path: resolve(__dirname, 'dll'),library: '[name]_[hash:10]', //打包的庫里面向外暴露出去的內容名字},plugins: [// 打包生成一個 mainfest.json ---> 提供和jquery映射關系new webapck.DllPlugin({name: '[name]_[hash:10]', // 映射庫暴露的內容名稱path: resolve(__dirname, 'dll/mainfest.json') // 輸出文件路徑})],mode: 'production'
}
  1. 執行該文件

webpack -c ./webpack.dll.js -c是 --config縮寫

  1. 下載包

npm i -D add-asset-html-webpack-plugin

  1. 在webpack.config.js中加入如下代碼
plugins: [// 告訴webpack那些庫不參與打包,同時使用時的名稱也得改變new webpack.DllReferencePlugin({manifest: resolve(__dirname,'dll/mainfest.json')}),// 將某個文件打包輸出去,并在html中自動引入該資源new AddAssetHtmlWebpackPlugin({filepath: resolve(__dirname, 'dll/jquery.js'),outputPath: 'auto', // 生成的index.html文件中多了一層auto目錄}),
]

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/web/45991.shtml
繁體地址,請注明出處:http://hk.pswp.cn/web/45991.shtml
英文地址,請注明出處:http://en.pswp.cn/web/45991.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

Facebook:數字時代的社交瑰寶

在當今數字化飛速發展的時代&#xff0c;社交媒體已經成為人們日常生活中不可或缺的一部分&#xff0c;而Facebook作為其中的領軍者&#xff0c;不僅連接了全球數十億的用戶&#xff0c;更深刻地改變了人們的社交方式和生活方式。本文將探討Facebook如何成為數字時代的社交瑰寶…

python如何創建SQLite 數據庫連接,如何將數據庫存儲在內存中?

嗨&#xff0c;大家好&#xff0c;我是蘭若姐姐。今天給大家說下如何創建SQLite 數據庫連接,并將數據庫存儲在內存中,這是一種臨時的、私有的數據存儲空間&#xff0c;一般用于以下情形&#xff1a; 什么都不說&#xff0c;先上代碼&#xff1a; import sqlite3創建數據庫連接…

再談有關JVM中的四種引用

1.強引用 強引用就是我們平時使用最多的那種引用&#xff0c;就比如以下的代碼 //創建一個對象 Object obj new Object();//強引用 這個例子就是創建了一個對象并建立了強引用&#xff0c;強引用一般就是默認支持的當內存不足的時候&#xff0c;JVM開始垃圾回收&#xff0c…

防火墻的冗余基礎知識+實驗檢測

將之前先理清需要注意的知識點&#xff1a; 1、注意防火墻冗余時的會話表必須保持一致&#xff0c;這里HRP技術已經做到 2、vrrp是自動開啟搶占的&#xff0c;且是根據優先級進行搶占的 3、免費ARP的作用&#xff1a;告訴交換機的某個IP的mac地址變成了我的這個mac地址 4、HRP …

C++ | Leetcode C++題解之第231題2的冪

題目&#xff1a; 題解&#xff1a; class Solution { private:static constexpr int BIG 1 << 30;public:bool isPowerOfTwo(int n) {return n > 0 && BIG % n 0;} };

強化學習——多臂老虎機問題(MAB)【附python代碼】

文章目錄 一、問題描述1.1 問題定義1.2 形式化描述1.3 累積懊悔1.4 估計期望獎勵 二、解決方法2.1 ?-貪婪算法2.2 上置信界算法2.3 湯普森采樣算法2.4 小結 一、問題描述 1.1 問題定義 有一個用于 K 根拉桿的老虎機&#xff0c;每一根拉桿都對應一個關于獎勵的概率分布 R 。每…

【C++題解】1154. 數組元素的查找

問題&#xff1a;1154. 數組元素的查找 類型&#xff1a;數組找數 題目描述&#xff1a; 給你 m 個整數&#xff0c;查找其中有無值為 n 的數&#xff0c;有則輸出該數第一次出現的位置,沒有則輸出 ?1 。 輸入&#xff1a; 第一行一個整數 m 代表數的個數 ( 0≤m≤100 ) 。…

Qt基礎 | Qt全局定義 | qglobal頭文件中的數據類型、函數、宏定義

文章目錄 一、數據類型定義二、函數三、宏定義 QtGlobal頭文件包含了 Qt 類庫的一些全局定義 &#xff0c;包括基本數據類型、函數和宏&#xff0c;一般的Qt類的頭文件都會包含該文件。 詳細內容可參考&#xff1a;https://doc.qt.io/qt-5/qtglobal.html 一、數據類型定義 為了…

數據可視化在智慧醫療中的重要應用

在現代智慧醫療的推動下&#xff0c;數據可視化技術正日益成為醫療領域的重要工具。通過將復雜的醫療數據轉換為直觀的圖表和圖形&#xff0c;數據可視化不僅提升了醫療服務的效率&#xff0c;還極大地改善了患者的就醫體驗。 在智慧醫療中&#xff0c;數據可視化首先在電子病歷…

客流統計系統優化景區服務流程,增強游客滿意度

在當今旅游業蓬勃發展的時代&#xff0c;景區面臨著越來越多的挑戰和機遇。如何提供更優質、更高效的服務&#xff0c;滿足游客日益增長的需求&#xff0c;成為了景區管理者們關注的焦點。客流統計系統作為一種創新的技術手段&#xff0c;正逐漸成為優化景區服務流程、增強游客…

MySQL主從同步的原理與思考

摘要 分析主從同步出現的原因&#xff0c;MySQL實現主從同步的原理&#xff0c;思考實現原理的局限性和優點 背景 在實際應用中主從同步常用于實現備份、負載均衡和高可用。數據冗余的目的是提高數據的安全性&#xff0c;避免因磁盤損壞導致數據丟失的問題。讀寫分離的目的是…

ubuntu系統Docker常用命令

1.查看docker是否開機啟動 sudo systemctl list-unit-files | grep enable|grep docker 2.設置開機啟動 sudo systemctl enable docker 3.關閉docker開機啟動 sudo systemctl disable docker 4.開啟docker服務 sudo service docker start 5.關閉docker服務 sudo servi…

基于CNN的MINIST手寫數字識別項目代碼以及原理詳解

文章目錄 項目簡介項目下載地址項目開發軟件環境項目開發硬件環境前言一、數據加載的作用二、Pytorch進行數據加載所需工具2.1 Dataset2.2 Dataloader2.3 Torchvision2.4 Torchtext2.5 加載項目需要使用的庫 三、加載MINIST數據集3.1 數據集簡介3.2 數據預處理3.3 加載數據集 四…

2.10、matlab中字符、數字、矩陣、字符串和元胞合并為字符串并將字符串以不同格式寫入讀出excel

1、前言 在 MATLAB 中&#xff0c;可以使用不同的數據類型&#xff08;字符、數字、矩陣、字符串和元胞&#xff09;合并為字符串&#xff0c;然后將字符串以不同格式寫入 Excel 文件。 以下是一個示例代碼&#xff0c;展示如何將不同數據類型合并為字符串&#xff0c;并以不…

重生奇跡mu魔法師瞬間移動技能

瞬間移動是勇士大陸魔法師所擁有的一項技能。一開始&#xff0c;許多玩家對這種技能的用處感到困惑。實際上&#xff0c;這種技能只能在游戲中不同的位置間進行移動&#xff0c;不能隨機傳送到地圖的其他坐標位置。 一位重生奇跡mu魔法師在PK中不小心使用了一項技能&#xff0c…

【仿真建模-anylogic】數據源組件

Author&#xff1a;趙志乾 Date&#xff1a;2024-07-16 Declaration&#xff1a;All Right Reserved&#xff01;&#xff01;&#xff01; 1. 簡介 仿真模型依賴的數據源通常有Excel文件、MySQL數據庫兩種&#xff1b;針對小數量、大數據量以及是否允許外部依賴等場景設計了一…

labview使用斑馬打印機打印標簽

使用ZebraDesigner 3設計標簽樣式 設計完成后打印至文件&#xff0c;生成prn文件 用記事本打開prn文件 ^MMT 標簽撕下 ^MMP 標簽剝離 按照需求替換FD--------^FS中間內容

路由上傳一個ui_control參數(uint32類型)控制頁面UI顯隱

前言&#xff1a;傳一個uint32類型的值&#xff0c;通過 按位或操作符&#xff08;|&#xff09;來設置ui_control的值&#xff0c;通過按位與操作符&#xff08;&&#xff09;來檢測是否顯示或隱藏 簡單介紹一下兩個概念&#xff1a; 按位與操作符和按位或操作符都是二進…

etcd的備份與恢復

一 為什么使用etcd 與ZooKeeper相比&#xff0c;etcd更簡單&#xff0c;安裝、部署和使用更加容易&#xff0c;并且etcd的某些功能是ZooKeeper所沒有的。因此&#xff0c;在很多場景下&#xff0c;etcd 比ZooKeeper更受用戶的青&#xff0c;具體表現在如下幾個方面: 1 etcd更…

上海市計算機學會競賽平臺2022年10月月賽丙組門禁記錄

題目描述 小愛得到了某大樓一天內按時間順序記錄的&#x1d45b;n條門禁出入記錄&#xff0c;每條記錄由兩個字符串組成&#xff0c;第一個字符串為出入人員姓名&#xff0c;第二個字符串表示該人員進出狀態、為 enter 或 exit 中一項&#xff0c;其中 enter 為進入&#xff0…