1. 程式人生 > >Webpack 4 Tree Shaking 終極優化指南

Webpack 4 Tree Shaking 終極優化指南

幾個月前,我的任務是將我們組的 Vue.js 專案構建配置升級到 Webpack 4。我們的主要目標之一是利用 tree-shaking 的優勢,即 Webpack 去掉了實際上並沒有使用的程式碼來減少包的大小。現在,tree-shaking 的好處將根據你的程式碼庫而有所不同。由於我們的幾個架構決策,我們從公司內部的其他庫中提取了大量程式碼,而我們只使用了其中的一小部分。

我寫這篇文章是因為恰當地優化 Webpack 並不簡單。一開始我以為這是一種簡單的魔法,但後來我花了一個月的時間在網上搜索我遇到的一系列問題的答案。我希望通過這篇文章,其他人會更容易地處理類似問題。

先說好處

在討論技術細節之前,讓我先總結一下好處。不同的應用程式將看到不同程度的好處。主要的決定因素是應用程式中死程式碼的數量。如果你沒有多少死程式碼,那麼你就看不到 tree-shaking 的多少好處。我們專案裡有很多死程式碼。

在我們部門,最大的問題是共享庫的數量。從簡單的自定義元件庫,到企業標準組件庫,再到莫名其妙地塞到一個庫中的大量程式碼。很多都是技術債務,但一個大問題是我們所有的應用程式都在匯入所有這些庫,而實際上每個應用程式都只需要其中的一小部分

總的來說,一旦實現了 tree-shaking,我們的應用程式就會根據應用程式的不同,縮減率從25%到75%。平均縮減率為52%,主要是由這些龐大的共享庫驅動的,它們是小型應用程式中的主要程式碼。

同樣,具體情況會有所不同,但是如果你覺得你打的包中可能有很多不需要的程式碼,這就是如何消除它們的方法。

沒有示例程式碼倉庫

對不住了各位老鐵,我做的專案是公司的財產,所以我不能分享程式碼到 GitHub 倉庫了。但是,我將在本文中提供簡化的程式碼示例來說明我的觀點。

因此,廢話少說,讓我們來看看如何編寫可實現 tree-shaking 的最佳 webpack 4 配置。

什麼是死程式碼

很簡單:就是 Webpack 沒看到你使用的程式碼。Webpack 跟蹤整個應用程式的 import/export 語句,因此,如果它看到匯入的東西最終沒有被使用,它會認為那是“死程式碼”,並會對其進行 tree-shaking 。

死程式碼並不總是那麼明確的。下面是一些死程式碼和“活”程式碼的例子,希望能讓你更明白。請記住,在某些情況下,Webpack 會將某些東西視為死程式碼,儘管它實際上並不是。請參閱《副作用》一節,瞭解如何處理。

// 匯入並賦值給 JavaScript 物件,然後在下面的程式碼中被用到
// 這會被看作“活”程式碼,不會做 tree-shaking
import Stuff from './stuff';
doSomething(Stuff);
// 匯入並賦值給 JavaScript 物件,但在接下來的程式碼裡沒有用到
// 這就會被當做“死”程式碼,會被 tree-shaking
import Stuff from './stuff';
doSomething();
// 匯入但沒有賦值給 JavaScript 物件,也沒有在程式碼裡用到
// 這會被當做“死”程式碼,會被 tree-shaking
import './stuff';
doSomething();
// 匯入整個庫,但是沒有賦值給 JavaScript 物件,也沒有在程式碼裡用到
// 非常奇怪,這竟然被當做“活”程式碼,因為 Webpack 對庫的匯入和原生代碼匯入的處理方式不同。
import 'my-lib';
doSomething();

用支援 tree-shaking 的方式寫 import

在編寫支援 tree-shaking 的程式碼時,匯入方式非常重要。你應該避免將整個庫匯入到單個 JavaScript 物件中。當你這樣做時,你是在告訴 Webpack 你需要整個庫, Webpack 就不會搖它。

以流行的庫 Lodash 為例。一次匯入整個庫是一個很大的錯誤,但是匯入單個的模組要好得多。當然,Lodash 還需要其他的步驟來做 tree-shaking,但這是個很好的起點。

// 全部匯入 (不支援 tree-shaking)
import _ from 'lodash';
// 具名匯入(支援 tree-shaking)
import { debounce } from 'lodash';
// 直接匯入具體的模組 (支援 tree-shaking)
import debounce from 'lodash/lib/debounce';

基本的 Webpack 配置

使用 Webpack 進行 tree-shaking 的第一步是編寫 Webpack 配置檔案。你可以對你的 webpack 做很多自定義配置,但是如果你想要對程式碼進行 tree-shaking,就需要以下幾項。

首先,你必須處於生產模式。Webpack 只有在壓縮程式碼的時候會 tree-shaking,而這隻會發生在生產模式中。

其次,必須將優化選項 “usedExports” 設定為true。這意味著 Webpack 將識別出它認為沒有被使用的程式碼,並在最初的打包步驟中給它做標記。

最後,你需要使用一個支援刪除死程式碼的壓縮器。這種壓縮器將識別出 Webpack 是如何標記它認為沒有被使用的程式碼,並將其剝離。TerserPlugin 支援這個功能,推薦使用。

下面是 Webpack 開啟 tree-shaking 的基本配置:

// Base Webpack Config for Tree Shaking
const config = {
 mode: 'production',
 optimization: {
  usedExports: true,
  minimizer: [
   new TerserPlugin({...})
  ]
 }
};

有什麼副作用

僅僅因為 Webpack 看不到一段正在使用的程式碼,並不意味著它可以安全地進行 tree-shaking。有些模組匯入,只要被引入,就會對應用程式產生重要的影響。一個很好的例子就是全域性樣式表,或者設定全域性配置的JavaScript 檔案。

Webpack 認為這樣的檔案有“副作用”。具有副作用的檔案不應該做 tree-shaking,因為這將破壞整個應用程式。Webpack 的設計者清楚地認識到不知道哪些檔案有副作用的情況下打包程式碼的風險,因此預設地將所有程式碼視為有副作用。這可以保護你免於刪除必要的檔案,但這意味著 Webpack 的預設行為實際上是不進行 tree-shaking。

幸運的是,我們可以配置我們的專案,告訴 Webpack 它是沒有副作用的,可以進行 tree-shaking。

如何告訴 Webpack 你的程式碼無副作用

package.json 有一個特殊的屬性 sideEffects,就是為此而存在的。它有三個可能的值:

true 是預設值,如果不指定其他值的話。這意味著所有的檔案都有副作用,也就是沒有一個檔案可以 tree-shaking。

false 告訴 Webpack 沒有檔案有副作用,所有檔案都可以 tree-shaking。

第三個值 […] 是檔案路徑陣列。它告訴 webpack,除了陣列中包含的檔案外,你的任何檔案都沒有副作用。因此,除了指定的檔案之外,其他檔案都可以安全地進行 tree-shaking。

每個專案都必須將 sideEffects 屬性設定為 false 或檔案路徑陣列。在我公司的工作中,我們的基本應用程式和我提到的所有共享庫都需要正確配置 sideEffects 標誌。

下面是 sideEffects 標誌的一些程式碼示例。儘管有 JavaScript 註釋,但這是 JSON 程式碼:

// 所有檔案都有副作用,全都不可 tree-shaking
{
 "sideEffects": true
}
// 沒有檔案有副作用,全都可以 tree-shaking
{
 "sideEffects": false
}
// 只有這些檔案有副作用,所有其他檔案都可以 tree-shaking,但會保留這些檔案
{
 "sideEffects": [
  "./src/file1.js",
  "./src/file2.js"
 ]
}

全域性 CSS 與副作用

首先,讓我們在這個上下文中定義全域性 CSS。全域性 CSS 是直接匯入到 JavaScript 檔案中的樣式表(可以是CSS、SCSS等)。它沒有被轉換成 CSS 模組或任何類似的東西。基本上,import 語句是這樣的:

// 匯入全域性 CSS
import './MyStylesheet.css';

因此,如果你做了上面提到的副作用更改,那麼在執行 webpack 構建時,你將立即注意到一個棘手的問題。以上述方式匯入的任何樣式表現在都將從輸出中刪除。這是因為這樣的匯入被 webpack 視為死程式碼,並被刪除。

幸運的是,有一個簡單的解決方案可以解決這個問題。Webpack 使用它的模組規則系統來控制各種型別檔案的載入。每種檔案型別的每個規則都有自己的 sideEffects 標誌。這會覆蓋之前為匹配規則的檔案設定的所有 sideEffects 標誌。

所以,為了保留全域性 CSS 檔案,我們只需要設定這個特殊的 sideEffects 標誌為 true,就像這樣:

// 全域性 CSS 副作用規則相關的 Webpack 配置
const config = {
 module: {
  rules: [
   {
    test: /regex/,
    use: [loaders],
    sideEffects: true
   }
  ]
 } 
};

Webpack 的所有模組規則上都有這個屬性。處理全域性樣式表的規則必須用上它,包括但不限於 CSS/SCSS/LESS/等等。

什麼是模組,模組為什麼重要

現在我們開始進入祕境。表面上看,編譯出正確的模組型別似乎是一個簡單的步驟,但是正如下面幾節將要解釋的,這是一個會導致許多複雜問題的領域。這是我花了很長時間才弄明白的部分。

首先,我們需要了解一下模組。多年來,JavaScript 已經發展出了在檔案之間以“模組”的形式有效匯入/匯出程式碼的能力。有許多不同的 JavaScript 模組標準已經存在了多年,但是為了本文的目的,我們將重點關注兩個標準。一個是 “commonjs”,另一個是 “es2015”。下面是它們的程式碼形式:

// Commonjs
const stuff = require('./stuff');
module.exports = stuff;

// es2015 
import stuff from './stuff';
export default stuff;

預設情況下,Babel 假定我們使用 es2015 模組編寫程式碼,並轉換 JavaScript 程式碼以使用 commonjs 模組。這樣做是為了與伺服器端 JavaScript 庫的廣泛相容性,這些 JavaScript 庫通常構建在 NodeJS 之上(NodeJS 只支援 commonjs 模組)。但是,Webpack 不支援使用 commonjs 模組來完成 tree-shaking。

現在,有一些外掛(如 common-shake-plugin)聲稱可以讓 Webpack 有能力對 commonjs 模組進行 tree-shaking,但根據我的經驗,這些外掛要麼不起作用,要麼在 es2015 模組上執行時,對 tree-shaking 的影響微乎其微。我不推薦這些外掛。

因此,為了進行 tree-shaking,我們需要將程式碼編譯到 es2015 模組。

es2015 模組 Babel 配置

據我所知,Babel 不支援將其他模組系統編譯成 es2015 模組。但是,如果你是前端開發人員,那麼你可能已經在使用 es2015 模組編寫程式碼了,因為這是全面推薦的方法。

因此,為了讓我們編譯的程式碼使用 es2015 模組,我們需要做的就是告訴 babel 不要管它們。為了實現這一點,我們只需將以下內容新增到我們的 babel.config.js 中(在本文中,你會看到我更喜歡JavaScript 配置而不是 JSON 配置):

// es2015 模組的基本 Babel 配置
const config = {
 presets: [
  [
   '[@babel/preset-env](http://twitter.com/babel/preset-env)',
   {
    modules: false
   }
  ]
 ]
};

modules 設定為 false,就是告訴 babel 不要編譯模組程式碼。這會讓 Babel 保留我們現有的 es2015 import/export 語句。

劃重點:所有可需要 tree-shaking 的程式碼必須以這種方式編譯。因此,如果你有要匯入的庫,則必須將這些庫編譯為 es2015 模組以便進行 tree-shaking 。如果它們被編譯為 commonjs,那麼它們就不能做 tree-shaking ,並且將會被打包進你的應用程式中。許多庫支援部分匯入,lodash 就是一個很好的例子,它本身是 commonjs 模組,但是它有一個 lodash-es 版本,用的是 es2015模組。

此外,如果你在應用程式中使用內部庫,也必須使用 es2015 模組編譯。為了減少應用程式包的大小,必須將所有這些內部庫修改為以這種方式編譯。

不好意思, Jest 罷工了

其他測試框架情況類似,我們用的是 Jest。

不管怎麼樣,如果你走到了這一步,你會發現 Jest 測試開始失敗了。你會像我當時一樣,看到日誌裡出現各種奇怪的錯誤,慌的一批。別慌,我會帶你一步一步解決。

出現這個結果的原因很簡單:NodeJS。Jest 是基於 NodeJS 開發的,而 NodeJS 不支援 es2015 模組。為此有一些方法可以配置 Node,但是在 jest 上行不通。因此,我們卡在這裡了:Webpack 需要 es2015 進行 tree shaking,但是 Jest 無法在這些模組上執行測試。

就是為什麼我說進入了模組系統的“祕境”。這是整個過程中耗費我最多時間來搞清楚的部分。建議你仔細閱讀這一節和後面幾節,因為我會給出解決方案。

解決方案有兩個主要部分。第一部分針對專案本身的程式碼,也就是跑測試的程式碼。這部分比較容易。第二部分針對庫程式碼,也就是來自其他專案,被編譯成 es2015 模組並引入到當前專案的程式碼。這部分比較複雜。

解決專案本地 Jest 程式碼

針對我們的問題,babel 有一個很有用的特性:環境選項。通過配置可以執行在不同環境。在這裡,開發和生產環境我們需要 es2015 模組,而測試環境需要 commonjs 模組。還好,Babel 配置起來非常容易:

// 分環境配置Babel 
const config = {
 env: {
  development: {
   presets: [
    [
     '[@babel/preset-env](http://twitter.com/babel/preset-env)',
     {
      modules: false
     }
    ]
   ]
  },
  production: {
   presets: [
    [
     '[@babel/preset-env](http://twitter.com/babel/preset-env)',
     {
      modules: false
     }
    ]
   ]
  },
  test: {
   presets: [
    [
     '[@babel/preset-env](http://twitter.com/babel/preset-env)',
     {
      modules: 'commonjs'
     }
    ]
   ],
   plugins: [
    'transform-es2015-modules-commonjs' // Not sure this is required, but I had added it anyway
   ]
  }
 }
};

設定好之後,所有的專案原生代碼能夠正常編譯,Jest 測試能運行了。但是,使用 es2015 模組的第三方庫程式碼依然不能執行。

解決 Jest 中的庫程式碼

庫程式碼執行出錯的原因非常明顯,看一眼node_modules 目錄就明白了。這裡的庫程式碼用的是 es2015 模組語法,為了進行 tree-shaking。這些庫已經採用這種方式編譯過了,因此當 Jest 在單元測試中試圖讀取這些程式碼時,就炸了。注意到沒有,我們已經讓 Babel 在測試環境中啟用 commonjs 模組了呀,為什麼對這些庫不起作用呢?這是因為,Jest (尤其是 babel-jest) 在跑測試之前編譯程式碼的時候,預設忽略任何來自node_modules 的程式碼。

這實際上是件好事。如果 Jest 需要重新編譯所有庫的話,將會大大增加測試處理時間。然而,雖然我們不想讓它重新編譯所有程式碼,但我們希望它重新編譯使用 es2015 模組的庫,這樣才能在單元測試裡使用。

幸好,Jest 在它的配置中為我們提供瞭解決方案。我想說,這部分確實讓我想了很久,並且我感覺沒必要搞得這麼複雜,但這是我能想到的唯一解決方案。

配置 Jest 重新編譯庫程式碼

// 重新編譯庫程式碼的 Jest 配置 
const path = require('path');
const librariesToRecompile = [
 'Library1',
 'Library2'
].join('|');
const config = {
 transformIgnorePatterns: [
  `[\\\/]node_modules[\\\/](?!(${librariesToRecompile})).*$`
 ],
 transform: {
  '^.+\.jsx?$': path.resolve(__dirname, 'transformer.js')
 }
};

以上配置是 Jest 重新編譯你的庫所需要的。有兩個主要部分,我會一一解釋。

transformIgnorePatterns 是 Jest 配置的一個功能,它是一個正則字串陣列。任何匹配這些正則表示式的程式碼,都不會被 babel-jest 重新編譯。預設是一個字串“node_modules”。這就是為什麼Jest 不會重新編譯任何庫程式碼。

當我們提供了自定義配置,就是告訴 Jest 重新編譯的時候如何忽略程式碼。也就是為什麼你剛才看到的變態的正則表示式有一個負向先行斷言在裡面,目的是為了匹配除了庫以外的所有程式碼。換句話說,我們告訴 Jest 忽略 node_modules 中除了指定庫之外的所有程式碼。

這又一次證明了 JavaScript 配置比 JSON 配置要好,因為我可以輕鬆地通過字串操作,往正則表示式裡插入庫名字的陣列拼接。

第二個是 transform 配置,他指向一個自定義的 babel-jest 轉換器。我不敢100%確定這個是必須的,但我還是加上了。設定它用於在重新編譯所有程式碼時載入我們的 Babel 配置。

// Babel-Jest 轉換器
const babelJest = require('babel-jest');
const path = require('path');
const cwd = process.cwd();
const babelConfig = require(path.resolve(cwd, 'babel.config'));
module.exports = babelJest.createTransformer(babelConfig);

這些都配置好後,你在測試程式碼應該又能跑了。記住了,任何使用庫的 es2015 模組都需要這樣配置,不然測試程式碼跑不動。

接下來輪到另一個痛點了:連結庫。使用 npm/yarn 連結的過程就是建立一個指向本地專案目錄的符號連結。結果表明,Babel 在重新編譯通過這種方式連結的庫時,會丟擲很多錯誤。我之所以花了這麼長時間才弄清楚 Jest 這檔子事兒,原因之一就是我一直通過這種方式連結我的庫,出現了一堆錯誤。

解決辦法就是:不要使用 npm/yarn link。用類似 “yalc” 這樣的工具,它可以連線本地專案,同時能模擬正常的 npm 安裝過程。它不但沒有 Babel 重編譯的問題,還能更好地處理傳遞性依賴。

針對特定庫的優化。

如果完成了以上所有步驟,你的應用基本上實現了比較健壯的 tree shaking。不過,為了進一步減少檔案包大小,你還可以做一些事情。我會列舉一些特定庫的優化方法,但這絕對不是全部。它尤其能為我們提供靈感,做出一些更酷的事情。

MomentJS 是出了名的大體積庫。幸好它可以剔除多語言包來減少體積。在下面的程式碼示例中,我排除了 momentjs 所有的多語言包,只保留了基本部分,體積明顯小了很多。

// 用 IgnorePlugin 移除多語言包
const { IgnorePlugin } from 'webpack';
const config = {
 plugins: [
  new IgnorePlugin(/^\.\/locale$/, /moment/)
 ]
};

Moment-Timezone 是 MomentJS 的老表,也是個大塊頭。它的體積基本上是一個帶有時區資訊的超大 JSON 檔案導致的。我發現只要保留本世紀的年份資料,就可以將體積縮小90%。這種情況需要用到一個特殊的 Webpack 外掛。

// MomentTimezone Webpack Plugin
const MomentTimezoneDataPlugin = require('moment-timezone-data-webpack-plugin');
const config = {
 plugins: [
  new MomentTimezoneDataPlugin({
   startYear: 2018,
   endYear: 2100
  })
 ]
};

Lodash 是另一個導致檔案包膨脹的大塊頭。幸好有一個替代包 Lodash-es,它被編譯成 es2015 模組,並帶有 sideEffects 標誌。用它替換 Lodash 可以進一步縮減包的大小。

另外,Lodash-es,react-bootstrap 以及其他庫可以在 Babel transform imports 外掛的幫助下實現瘦身。該外掛從庫的 index.js 檔案讀取 import 語句,並使其指向庫中特定檔案。這樣就使 webpack 在解析模組樹時更容易對庫做 tree shaking。下面的例子演示了它是如何工作的。

// Babel Transform Imports
// Babel config
const config = {
 plugins: [
  [
   'transform-imports',
   {
    'lodash-es': {
     transform: 'lodash/${member}',
     preventFullImport: true
    },
    'react-bootstrap': {
     transform: 'react-bootstrap/es/${member}', // The es folder contains es2015 module versions of the files
     preventFullImport: true
    }
   }
  ]
 ]
};
// 這些庫不再支援全量匯入,否則會報錯
import _ from 'lodash-es';
// 具名匯入依然支援
import { debounce } from 'loash-es';
// 不過這些具名匯入會被babel編譯成這樣子
// import debounce from 'lodash-es/debounce';

總結

全文到此結束。這樣的優化可以極大地縮減打包後的大小。隨著前端架構開始有了新的方向(比如微前端),保持包大小最優化變得比以往更加重要。希望本文能給那些正在給應用程式做tree shaking的同學帶來一些幫助。

交流

歡迎掃碼關注微信公眾號“1024譯站”,為你奉上更多技術乾貨。

相關推薦

Webpack 4 Tree Shaking 終極優化指南

幾個月前,我的任務是將我們組的 Vue.js 專案構建配置升級到 Webpack 4。我們的主要目標之一是利用 tree-shaking 的優勢,即 Webpack 去掉了實際上並沒有使用的程式碼來減少包的大小。現在,tree-shaking 的好處將根據你的程式碼庫而有所不同。由於我們的幾個架構決策,我們從

WebpackTree Shaking

set use conf arm mon reset 文件 為什麽 load 為什麽要使用 Tree Shaking? 當從某文件模塊中導出(某一個或幾個變量、函數、對象等),然而這個文件模塊還有許多其它(我們這次並不需要)的導出,webpack會不管三七二十一簡單粗暴的

webpack 如何優雅的使用tree-shaking(搖樹優化

webpack 如何優雅的使用tree-shaking 1.什麼是tree-shaking webpack 2 的到來帶來的最棒的新特性之一就是tree-shaking 。tree-shaking源自於rollup.js,先如今,webpack 2也有類

【javascript】webpack code split && tree shaking

webpack打包vue專案之後的檔案太大,本身我們專案的體量也比較大,首次載入太慢。 所以嘗試程式碼分割,對打包之後的app.js進行拆分。 1,動態載入 -(路由懶載入) -(按需載入)     現在vue專案裡面,有很多路由,一個路由對應著或者多個路由對應著

釋放webpack tree-shaking潛力之webpack-deep-scope-analysis-plugin

在上週末廣州舉辦的 feday 中, webpack 的核心開發者 Sean 在介紹 webpack 外掛系統原理時, 隆重介紹了一箇中國學生於 Google 夏令營, 在導師 Tobias 帶領下寫的一個 webpack 外掛, https://github.com/vin

MyEclipse x.x各版本終極優化配置指南

先說優化:隨著myeclipse版本不斷更新,其功能不斷強大,更加智慧及人性化,為開發人員提供了很多便利、提高了開發速度,但是也犧牲了效能,讓很多機器配置稍差的開發人員頭疼不已。其實我們平時常用的功能只用20%,所以我們可以選擇關閉一些不常用功能讓不斷臃腫的myeclips

【javascript】webpack code split && tree shaking

webpack打包vue專案之後的檔案太大,本身我們專案的體量也比較大,首次載入太慢。所以嘗試程式碼分割,對打包之後的app.js進行拆分。1,動態載入 -(路由懶載入) -(按需載入)    現在vue專案裡面,有很多路由,一個路由對應著或者多個路由對應著一個元件,如果不進

Webpack 4教程:為什麼要優化程式碼

浪費了“黃金五年”的Java程式設計師,還有救嗎? >>>   

高性能mysql 4,5,6章優化總結

重復 自適應 數據存儲 復雜 insert reat order 是我 條目 針對數據庫的優化,我們不能單純的說從哪一個方面,需要結合數據表的建立,數據類型的選擇,索引的設計和sql語句來考慮,我就針對怎麽建表,怎麽選擇數據類型,如何應用B-tree索引,hash索引和覆蓋

移動H5前端性能優化指南

例如 coo forms 指南 touchend meta 大於 動畫 節點 移動H5前端性能優化指南 概述 1. PC優化手段在Mobile側同樣適用2. 在Mobile側我們提出三秒種渲染完成首屏指標3. 基於第二點,首屏加載3秒完成或使用Loading4. 基於聯通

【轉載】 Spark性能優化指南——基礎篇

否則 內存占用 是否 進行 優先 邏輯 我們 流式 字節數組 前言 開發調優 調優概述 原則一:避免創建重復的RDD 原則二:盡可能復用同一個RDD 原則三:對多次使用的RDD進行持久化 原則四:盡量避免使用shuffle類算子 原則五:使用map-side預聚

Spark性能優化指南——高級篇

stat 參數調優 5% 每一個 寫性能 nes fix 單獨 png Spark性能優化指南——高級篇 [TOC] 前言 繼基礎篇講解了每個Spark開發人員都必須熟知的開發調優與資源調優之後,本文作為《Spark性能優化指南》的高級篇,將深入分析數據傾斜調

Spark性能優化指南——基礎篇(轉載)

cores 寫入 所在 src 做了 一次函數 種類 推薦 var 前言 在大數據計算領域,Spark已經成為了越來越流行、越來越受歡迎的計算平臺之一。Spark的功能涵蓋了大數據領域的離線批處理、SQL類處理、流式/實時計算、機器學習、圖計算等各種不同類型的計算操

webpack配置之代碼優化

import ont name splitting lB jquer fault 內聯 javascrip 前面的話   前面介紹了webpack的基本配置,本文將詳細介紹webpack中關於代碼優化的配置 打包公共代碼   CommonsChunkPlugin

webpack 4.0 配置方法以及錯誤解決

文件目錄 pts 版本 創建目錄 efault ebp 大堆 添加 安裝 選取一個空目錄來試驗 全局安裝webpack4.1之後 創建目錄 mkdir webpacktest && cd webpacktes 初始化package.json npm init

Resin 4.0.15配置優化

resin早先說過線上Resin的配置文件中要增加線程池大小、各種timeout參數(resin 4.0.15的默認配置文件肯定沒有這些參數,需要另行增加)。 在resin 4.0.10裏,有這麽一個bug,thread-max的數量設置沒有起作用 但後面到了resin 4.0.15應該就修復了。 下面內容會

webpack 4.0嘗鮮

.com size cti webp 添加 出口 執行 解釋 速度 發布不久得webpack 4.0據說速度快了68% - 98%,然後還支持沒配置文件,所以看起來很牛逼得樣子 所以嘗試一發 webpack和webpack-cli分離 現在執行webpack命令 必須要we

Spark性能優化指南——基礎篇

數據緩存 較差 計算平臺 entry col 機器 輸入數據 使用 持久化數據 前言 在大數據計算領域,Spark已經成為了越來越流行、越來越受歡迎的計算平臺之一。Spark的功能涵蓋了大數據領域的離線批處理、SQL類處理、流式/實時計算、機器學習、圖計算等各種不同類型的計

性能優化指南:性能優化的一般性原則與方法

ase disk 測試 RM mongodb baby 並發 shard 操作系統   作為一個程序員,性能優化是常有的事情,不管是桌面應用還是web應用,不管是前端還是後端,不管是單點應用還是分布式系統。本文從以下幾個方面來思考這個問題:性能優化的一般性原則,性能優化的層

Spark性能優化指南——基礎篇(轉載

action 註冊 tex 開發者 ons apache ring 占用內存 完整 前言 在大數據計算領域,Spark已經成為了越來越流行、越來越受歡迎的計算平臺之一。Spark的功能涵蓋了大數據領域的離線批處理、SQL類處理、流式/實時計算、機器學習、圖計算等各種不同類