摘要:是對的轉譯結果進行緩存,之后的進行構建時,都會去嘗試讀取緩存來避免高耗能的重新轉譯過程,可以指定一個緩存目錄或者指定為,為時將使用默認的緩存目錄。這篇文章如果有錯誤或不嚴謹的地方,歡迎批評指正,如果喜歡,歡迎點贊收藏
由于前端的快速發展,相關工具的發展速度也是相當迅猛,各大框架例如vue,react都有自己優秀的腳手架工具來幫助我們快速啟動一個新項目,也正式因為這個原因,我們對于腳手架中最關鍵的一環webpack相關的優化知之甚少,腳手架基本上已經為我們做好了相關的開發準備,但是當我們想要做一些定制化的優化操作時,對webpack的優化也需要有一定的了解,否則無從下手,接下來就讓我們進入webpack的優化世界
構建速度提升 loader提升loader是webpack中最重要的特性,由于webpack自身只支持JavaScript,因此需要一系列的loader來處理那些非JavaScript模塊,因此在我們用webpack建項目的時候一定會使用一系列的loader,例如:vue-loader、sass-loader、babel-loader等等,就以babel-loader為例,來看具體配置:
module: { rules: [{ test: /.js$/, exclude: /node_modules/, loader: "babel-loader?cacheDirectory=true", options: { presets: ["@babel/preset-env"], plugins: ["@babel/transform-runtime"] } }] }
對于loader來說最常用的就是exclude屬性,用來避免不必要的轉譯,上面通過exclude來避免對node_modules中js中進行轉譯來提升構建速度,但是這樣帶來的提升效果有限。
cacheDirectory是對babel-loader的轉譯結果進行緩存,之后的webpack進行構建時,都會去嘗試讀取緩存來避免高耗能的babel重新轉譯過程,cacheDirectory可以指定一個緩存目錄或者指定為true,為true時將使用默認的緩存目錄node_modules/.cache/babel-loader。
babel對一些公共方法使用了非常小的輔助代碼,默認會注入到每一個需要的文件,這樣就造成重復引入,這時候就需要像上面那樣引入transform-runtime來告訴babel引入runtime來代替注入
第三方庫優化 externalsexternals提高構建速度的方法就是在構建時不會將指定的依賴包打包到bundle中,而是在運行時再從外部獲取依賴,具體是怎么用的呢?來看個例子:
externals : { vue : "Vue", vueRouter : "VueRouter", vueResource : "VueResource", vuex : "Vuex" },
上面的例子的將vue全家桶都配置在externals中,然后將壓縮包合成一個js文件放在cdn上面,這樣就不會在構建時將文件打包到bundle中,提升打包速度,同時cdn又可以做緩存,提高訪問速度,美滋滋
DllPluginDllPlugin是用來干什么的呢?DllPlugin會將第三方包到一個多帶帶文件,并且生成一個映射的json文件,打包的生成的文件就是一個依賴庫,這個依賴不會隨著你的業務代碼改變而被重新打包,只有當它自身依賴的包發生變化時才會需要重新打包依賴庫,接下來來看具體配置吧:
module.exports = { entry: { vendor: ["vue", "vue-router", "vue-resource", "vuex"] }, output: { path: path.join(__dirname, "dist"), filename: "[name].js", library: "[name]_hash", }, plugins: [ new webpack.DllPlugin({ name: "[name]_[hash]", path: path.join(__dirname, "dist", "[name]-manifest.json"), context: __dirname }) ] }
首先我們需要一個如上面例子那樣的dll配置文件,然后編譯這個配置文件,生成一個vendor.js和一個映射文件vendor-manifest.json,然后再在我們的webpack配置文件中對進行配置:
plugins: [ new webpack.DllReferencePlugin({ context: __dirname, manifest: require("./dist/vendor-manifest.json") }) ]
這樣就完成配置了,是不是很簡單呢?趕緊動手試試吧
happypackhappypack這是個什么呢?我們都知道webpack是個單線程處理任務的,當又多個任務需要處理的時候,需要排隊,那happypack就是用多線程來處理任務,通過并發處理來提高任務處理速度,那么這個需要怎么配置呢?來看具體例子:
const happypack = require("happypack") // 創建并發池 const threadPool = happypack.ThreadPool({size: os.cpus().length}) module: { rules: [{ test: /.js$/, exclude: /node_modules/, loader: "happypack/loader?id=happyBabel" // id對應happypack插件id }] }, plugins: [ new happypack({ id: "happyBabel", threadPool: threadPool, loaders: ["babel-loader?cacheDirectory"] }) ],減小構建體積 webpack-bundle-analyzer
這個相信大家都很熟悉,就是一個可視化工具,用來查看各個包的大小以及相互之間的依賴關系,配置方法也很簡單,就和插件的配置一樣,來看具體例子:
const bundleAnalyzerPlugin = require("webpack-bundle-analyzer").BundleAnalyzerPlugin plugins: [ new bundleAnalyzerPlugin() ],tree shaking
tree shaking指的是什么呢?通常指的是JavaScript上下文中未引用的代碼,怎么理解呢?比如你引用了lodash包,里面有許多和JavaScript相關的便利方法,但你實際只用了其中的一兩個,此時打包時如果把所有的方法都打進去了,是不是很浪費呢?tree shaking的概念就是去除多余代碼。來看一個簡單的例子:
import {plus} from "./count" console.log(plus(1, 2))
function plus(x, y) { return x + y } function minus(x, y) { return x - y } export { plus, minus }
const path = require("path") module.exports = { entry: { main: "./src/index.js", }, output: { path: path.join(__dirname, "dist"), filename: "[name].js", }, mode: "development" }
如上例所示,在入口文件中我們引入count.js中plus方法,我們期望的當然是只會引入plus方法,而不是都引入,但往往不隨人愿,來看結果:
你會發現編譯后的代碼中,整個count.js都被編譯進去了,這時候你就需要tree shaking了,接下來看做tree shaking的具體方法
UglifyJsPlugin這個插件大家一定都用過,使用UglifyJsPlugin就可以在構建的過程中對冗余的代碼進行刪除,在webpack4中只需要將上面mode的值改為production,就會啟用UglifyJsPlugin,是不是很簡單,或許你想知道webpack4中怎么自己配置UglifyJsPlugin,那就來看具體配置吧:
const UglifyJsPlugin = require("uglifyjs-webpack-plugin") optimization: { minimizer: [ new UglifyJsPlugin({ parallel: true, cache: true, uglifyOptions: { compress: { drop_console: true, reduce_vars: true }, output: { comments: false, beautify: false } } }) ] }
是的在webpack4中的UglifyJsPlugin是配置在optimization中的minimizer中的,配置是不很簡單呢?趕緊動手嘗試吧
按需加載(import)這里的import是指webpack中的動態加載,它的語法和ES6中的動態加載語法一摸一樣,這是官方推薦的按需加載的方式,還是上面tree shaking的例子,我們只想引入plus方法,我們來看具體怎么使用:
import("./count.js").then((count) => { console.log(count.plus(1, 2)) })
我們只需要將入口文件改成上面的形式,其他的都不要變就可以實現按需引入,是不是很簡單呢?在vue中路由的按需加載也可以這么用,來看一個簡單的例子:
function view (name) { return new Promise((resolve, reject) => { import("../views/" + name + ".vue") .then((res) => { resolve(res) }).catch(e => { reject("網絡異常,請稍后再試") }) }).catch(err => { throw new Error("err,組件加載失敗") }) }
傳入一個名字,動態引入對應目錄的下的視圖文件,這只是一個簡單的例子,具體的使用形式還是依據具體的場景
總結這篇文章簡單的從構建速度和代碼體積兩個方面簡單的介紹了webpack優化相關的方法,希望大家都能自己動手去寫一寫,畢竟只有實踐出真知,更何況是編程。
這篇文章如果有錯誤或不嚴謹的地方,歡迎批評指正,如果喜歡,歡迎點贊收藏
文章版權歸作者所有,未經允許請勿轉載,若此文章存在違規行為,您可以聯系管理員刪除。
轉載請注明本文地址:http://specialneedsforspecialkids.com/yun/99648.html
摘要:性能優化是前端開發必不可少的一環,而圖片優化又是性能優化中必不可少的一環,但不知道有多少開發者在網頁的開發過程中會注意圖片的使用,圖片使用不當可能會導致網頁加載卡頓網頁加載速度慢等問題,這篇文章將會將我以往對圖片的處理做個總結。 性能優化是前端開發必不可少的一環,而圖片優化又是性能優化中必不可少的一環,但不知道有多少開發者在網頁的開發過程中會注意圖片的使用,圖片使用不當可能會導致網頁加...
摘要:接下來就讓我們更細致的探究中的深淺拷貝。總結以上對深拷貝和淺拷貝做了簡單的介紹,在深拷貝的實現上也只介紹了最簡單的實現形式,并未考慮復雜情況以及相應優化,想要對深拷貝有更深入的了解,需要大家花時間去深入研究,或者可以關注我后續文章的動態。 對象和數組的拷貝對我來說一直都是一個比較模糊的概念,一直有點一知半解,但是在實際工作中又偶爾會涉及到,有時候還會一不小心掉坑里,不知道大家有沒有同樣...
摘要:中在性能優化所做的努力,也大抵圍繞著這兩個大方向展開。因此,將依賴模塊從業務代碼中分離是性能優化重要的一環。大型庫是否可以通過定制功能的方式減少體積。這又違背了性能優化的基礎。接下來可以抓住一些細節做更細的優化。中,為默認啟動這一優化。 前言:在現實項目中,我們可能很少需要從頭開始去配置一個webpack 項目,特別是webpack4.0發布以后,零配置啟動一個項目成為一種標配。正因為...
閱讀 1176·2021-11-23 10:10
閱讀 1499·2021-09-30 09:47
閱讀 887·2021-09-27 14:02
閱讀 2967·2019-08-30 15:45
閱讀 3020·2019-08-30 14:11
閱讀 3610·2019-08-29 14:05
閱讀 1820·2019-08-29 13:51
閱讀 2206·2019-08-29 11:33