欧美一区二区三区老妇人-欧美做爰猛烈大尺度电-99久久夜色精品国产亚洲a-亚洲福利视频一区二区

如何使用Webpack分離數(shù)據(jù)

這篇文章主要為大家展示了“如何使用Webpack分離數(shù)據(jù)”,內(nèi)容簡而易懂,條理清晰,希望能夠幫助大家解決疑惑,下面讓小編帶領(lǐng)大家一起研究并學(xué)習(xí)一下“如何使用Webpack分離數(shù)據(jù)”這篇文章吧。

成都創(chuàng)新互聯(lián)10多年企業(yè)網(wǎng)站制作服務(wù);為您提供網(wǎng)站建設(shè),網(wǎng)站制作,網(wǎng)頁設(shè)計及高端網(wǎng)站定制服務(wù),企業(yè)網(wǎng)站制作及推廣,對成都樓梯護(hù)欄等多個行業(yè)擁有多年的網(wǎng)站維護(hù)經(jīng)驗(yàn)的網(wǎng)站建設(shè)公司。

制定向用戶提供文件的***方式可能是一項棘手的工作。 有很多不同的場景,不同的技術(shù),不同的術(shù)語。

在這篇文章中,我希望給你所有你需要的東西,這樣你就可以:

  1. 鴻蒙官方戰(zhàn)略合作共建——HarmonyOS技術(shù)社區(qū)

  2.  了解哪種文件分割策略最適合你的網(wǎng)站和用戶

  3.  知道怎么做

根據(jù) Webpack glossary,有兩種不同類型的文件分割。 這些術(shù)語聽起來可以互換,但顯然不是。

Webpack 文件分離包括兩個部分,一個是 Bundle splitting,一個是 Code splitting:

  •  Bundle splitting: 創(chuàng)建更多更小的文件,并行加載,以獲得更好的緩存效果,主要作用就是使瀏覽器并行下載,提高下載速度。并且運(yùn)用瀏覽器緩存,只有代碼被修改,文件名中的哈希值改變了才會去再次加載。

  •  Code splitting:只加載用戶最需要的部分,其余的代碼都遵從懶加載的策略,主要的作用就是加快頁面的加載速度,不加載不必要的代碼。

第二個聽起來更吸引人,不是嗎?事實(shí)上,關(guān)于這個問題的許多文章似乎都假設(shè)這是制作更小的JavaScript 文件的惟一值得的情況。

但我在這里要告訴你的是,***個在很多網(wǎng)站上都更有價值,應(yīng)該是你為所有網(wǎng)站做的***件事。

就讓我們一探究竟吧。

Bundle splitting

bundle splitting 背后的思想非常簡單,如果你有一個巨大的文件,并且更改了一行代碼,那么用戶必須再次下載整個文件。但是如果將其分成兩個文件,那么用戶只需要下載更改的文件,瀏覽器將從緩存中提供另一個文件。

值得注意的是,由于 bundle splitting 都是關(guān)于緩存的,所以對于***次訪問來說沒有什么區(qū)別。

(我認(rèn)為太多關(guān)于性能的討論都是關(guān)于***次訪問一個站點(diǎn),或許部分原因是“***印象很重要”,部分原因是它很好、很容易衡量。

對于經(jīng)常訪問的用戶來說,量化性能增強(qiáng)所帶來的影響可能比較棘手,但是我們必須進(jìn)行量化!

這將需要一個電子表格,因此我們需要鎖定一組非常特定的環(huán)境,我們可以針對這些環(huán)境測試每個緩存策略。

這是我在前一段中提到的情況:

  •  Alice 每周訪問我們的網(wǎng)站一次,持續(xù) 10 周

  •  我們每周更新一次網(wǎng)站

  •  我們每周都會更新我們的“產(chǎn)品列表”頁面

  •  我們也有一個“產(chǎn)品詳細(xì)信息”頁面,但我們目前還沒有開發(fā)

  •  在第 5 周,我們向站點(diǎn)添加了一個新的 npm 包

  •  在第 8 周,我們更新了一個現(xiàn)有的 npm 包

某些類型的人(比如我)會嘗試讓這個場景盡可能的真實(shí)。不要這樣做。實(shí)際情況并不重要,稍后我們將找出原因。

基線

假設(shè)我們的 JavaScript 包的總?cè)萘渴?00 KB,目前我們將它作為一個名為 main.js 的文件加載。

我們有一個 Webpack 配置如下(我省略了一些無關(guān)的配置):

// webpack.config.js   const path = require('path')  module.exports = {    entry: path.resolve(__dirame, 'src/index.js')    output: {      path: path.resolve(__dirname, 'dist'),      filename: '[name].[contenthash].js'    }  }

對于那些新的緩存破壞:任何時候我說 main.js,我實(shí)際上是指 main.xMePWxHo.js,其中里面的字符串是文件內(nèi)容的散列。這意味著不同的文件名 當(dāng)應(yīng)用程序中的代碼發(fā)生更改時,從而強(qiáng)制瀏覽器下載新文件。

每周當(dāng)我們對站點(diǎn)進(jìn)行一些新的更改時,這個包的 contenthash 都會發(fā)生變化。因此,Alice 每周都要訪問我們的站點(diǎn)并下載一個新的 400kb 文件。

如果我們把這些事件做成一張表格,它會是這樣的。

如何使用Webpack分離數(shù)據(jù)

也就是10周內(nèi), 4.12 MB, 我們可以做得更好。

分解 vendor 包

讓我們將包分成 main.js 和 vendor.js 文件。

 // webpack.config.js   const path = require('path')  module.exports = {    entry: path.resolve(__dirname, 'src/index.js'),    output: {      path: path.resolve(__dirname, 'dist'),      filename: '[name].[contenthash].js',    },    optimization: {      splitChunks: {        chunks: 'all'      }    }  }

Webpack4 為你做***的事情,而沒有告訴你想要如何拆分包。這導(dǎo)致我們對 webpack 是如何分包的知之甚少,結(jié)果有人會問 “你到底在對我的包裹做什么?”

添加 optimization.splitChunks.chunks ='all'的一種說法是 “將 node_modules 中的所有內(nèi)容放入名為 vendors~main.js 的文件中”。

有了這個基本的 bundle splitting,Alice 每次訪問時仍然下載一個新的 200kb 的 main.js,但是在***周、第8周和第5周只下載 200kb 的 vendor.js (不是按此順序)。

如何使用Webpack分離數(shù)據(jù)

總共:2.64 MB。

減少36%。 在我們的配置中添加五行代碼并不錯。 在進(jìn)一步閱讀之前,先去做。 如果你需要從 Webpack 3 升級到 4,請不要擔(dān)心,它非常簡單。

我認(rèn)為這種性能改進(jìn)似乎更抽象,因?yàn)樗窃?0周內(nèi)進(jìn)行的,但是它確實(shí)為忠實(shí)用戶減少了36%的字節(jié),我們應(yīng)該為自己感到自豪。

但我們可以做得更好。

分離每個 npm 包

我們的 vendor.js 遇到了與我們的 main.js 文件相同的問題——對其中一部分的更改意味著重新下載它的所有部分。

那么為什么不為每 個npm 包創(chuàng)建一個單獨(dú)的文件呢?這很容易做到。

所以把 react、lodash、redux、moment 等拆分成不同的文件:

const path = require('path');  const webpack = require('webpack');  module.exports = {    entry: path.resolve(__dirname, 'src/index.js'),    plugins: [      new webpack.HashedModuleIdsPlugin(), // so that file hashes don't change unexpectedly    ],    output: {      path: path.resolve(__dirname, 'dist'),      filename: '[name].[contenthash].js',    },    optimization: {      runtimeChunk: 'single',      splitChunks: {        chunks: 'all',        maxInitialRequests: Infinity,        minSize: 0,        cacheGroups: {          vendor: {            test: /[\\/]node_modules[\\/]/,            name(module) {              // get the name. E.g. node_modules/packageName/not/this/part.js              // or node_modules/packageName              const packageName = module.context.match(/[\\/]node_modules[\\/](.*?)([\\/]|$)/)[1];              // npm package names are URL-safe, but some servers don't like @ symbols              return `npm.${packageName.replace('@', '')}`;            },          },        },      },    },  };

文檔將很好地解釋這里的大部分內(nèi)容,但是我將稍微解釋一下需要注意的部分,因?yàn)樗鼈兓宋姨嗟臅r間。

  •  Webpack 有一些不太聰明的默認(rèn)設(shè)置,比如分割輸出文件時最多3個文件,最小文件大小為30 KB(所有較小的文件將連接在一起),所以我重寫了這些。

  •  cacheGroups 是我們定義 Webpack 應(yīng)該如何將數(shù)據(jù)塊分組到輸出文件中的規(guī)則的地方。這里有一個名為 “vendor” 的模塊,它將用于從 node_modules 加載的任何模塊。通常,你只需將輸出文件的名稱定義為字符串。但是我將 name 定義為一個函數(shù)(將為每個解析的文件調(diào)用這個函數(shù))。然后從模塊的路徑返回包的名稱。因此,我們將為每個包獲得一個文件,例如 npm.react-dom.899sadfhj4.js。

  •  NPM 包名稱必須是 URL 安全的才能發(fā)布,因此我們不需要 encodeURI 的 packageName。 但是,我遇到一個.NET服務(wù)器不能提供名稱中帶有 @(來自一個限定范圍的包)的文件,所以我在這個代碼片段中替換了 @。

  •  整個設(shè)置很棒,因?yàn)樗且怀刹蛔兊摹?無需維護(hù) - 不需要按名稱引用任何包。

Alice 仍然會每周重新下載 200 KB 的 main.js 文件,并且在***次訪問時仍會下載 200 KB 的npm包,但她絕不會兩次下載相同的包。

如何使用Webpack分離數(shù)據(jù)

總共: 2.24 MB.

與基線相比減少了44%,這對于一些可以從博客文章中復(fù)制/粘貼的代碼來說非常酷。

我想知道是否有可能超過 50% ? 這完全沒有問題。

分離應(yīng)用程序代碼的區(qū)域

讓我們轉(zhuǎn)到 main.js 文件,可憐的 Alice 一次又一次地下載這個文件。

我之前提到過,我們在此站點(diǎn)上有兩個不同的部分:產(chǎn)品列表和產(chǎn)品詳細(xì)信息頁面。 每個區(qū)域中的唯一代碼為25 KB(共享代碼為150 KB)。

我們的產(chǎn)品詳情頁面現(xiàn)在變化不大,因?yàn)槲覀冏龅锰?**了。 因此,如果我們將其做為單獨(dú)的文件,則可以在大多數(shù)時間從緩存中獲取到它。

另外,我們網(wǎng)站有一個較大的內(nèi)聯(lián)SVG文件用于渲染圖標(biāo),重量只有25 KB,而這個也是很少變化的, 我們也需要優(yōu)化它。

我們只需手動添加一些入口點(diǎn),告訴 Webpack 為每個項創(chuàng)建一個文件。

module.exports = {    entry: {      main: path.resolve(__dirname, 'src/index.js'),      ProductList: path.resolve(__dirname, 'src/ProductList/ProductList.js'),      ProductPage: path.resolve(__dirname, 'src/ProductPage/ProductPage.js'),      Icon: path.resolve(__dirname, 'src/Icon/Icon.js'),    },    output: {      path: path.resolve(__dirname, 'dist'),      filename: '[name].[contenthash:8].js',    },    plugins: [      new webpack.HashedModuleIdsPlugin(), // so that file hashes don't change unexpectedly    ],    optimization: {      runtimeChunk: 'single',      splitChunks: {        chunks: 'all',        maxInitialRequests: Infinity,        minSize: 0,        cacheGroups: {          vendor: {            test: /[\\/]node_modules[\\/]/,            name(module) {              // get the name. E.g. node_modules/packageName/not/this/part.js              // or node_modules/packageName              const packageName = module.context.match(/[\\/]node_modules[\\/](.*?)([\\/]|$)/)[1];              // npm package names are URL-safe, but some servers don't like @ symbols              return `npm.${packageName.replace('@', '')}`;            },          },        },      },    },  };

Webpack 還會為 ProductList 和 ProductPage 之間共享的內(nèi)容創(chuàng)建文件,這樣我們就不會得到重復(fù)的代碼。

這將為 Alice 在大多數(shù)情況下節(jié)省 50 KB 的下載。

如何使用Webpack分離數(shù)據(jù)

只有 1.815 MB!

我們已經(jīng)為 Alice 節(jié)省了高達(dá)56%的下載量,這種節(jié)省將(在我們的理論場景中)持續(xù)到時間結(jié)束。

所有這些都只在Webpack配置中進(jìn)行了更改——我們沒有對應(yīng)用程序代碼進(jìn)行任何更改。

我在前面提到過,測試中的確切場景并不重要。這是因?yàn)椋瑹o論你提出什么場景,結(jié)論都是一樣的:將應(yīng)用程序分割成合理的小文件,以便用戶下載更少的代碼。

很快,=將討論“code splitting”——另一種類型的文件分割——但首先我想解決你現(xiàn)在正在考慮的三個問題。

#1:大量的網(wǎng)絡(luò)請求不是更慢嗎?

答案當(dāng)然是不會。

在 HTTP/1.1 時代,這曾經(jīng)是一種情況,但在 HTTP/2 時代就不是這樣了。

盡管如此,這篇2016年的文章 和 Khan Academy 2015年的文章都得出結(jié)論,即使使用 HTTP/2,下載太多的文件還是比較慢。但在這兩篇文章中,“太多”的意思都是“幾百個”。所以請記住,如果你有數(shù)百個文件,你可能一開始就會遇到并發(fā)限制。

如果您想知道,對 HTTP/2 的支持可以追溯到 Windows 10 上的 ie11。我做了一個詳盡的調(diào)查,每個人都使用比那更舊的設(shè)置,他們一致向我保證,他們不在乎網(wǎng)站加載有多快。

#2:每個webpack包中沒有 開銷/引用 代碼嗎?

是的,這也是真的。

好吧,狗屎:

  •  more files = 更多 Webpack 引用

  •  more files = 不壓縮

讓我們量化一下,這樣我們就能確切地知道需要擔(dān)心多少。

好的,我剛做了一個測試,一個 190 KB 的站點(diǎn)拆分成 19 個文件,增加了大約 2%發(fā)送到瀏覽器的總字節(jié)數(shù)。

因此......在***次訪問時增加 2%,在每次訪問之前減少60%直到網(wǎng)站下架。

正確的擔(dān)憂是:完全沒有。

當(dāng)我測試1個文件對19個時,我想我會在一些不同的網(wǎng)絡(luò)上試一試,包括HTTP / 1.1

如何使用Webpack分離數(shù)據(jù)

在 3G 和4G上,這個站點(diǎn)在有19個文件的情況下加載時間減少了30%。

這是非常雜亂的數(shù)據(jù)。 例如,在運(yùn)行2號 的 4G 上,站點(diǎn)加載時間為 646ms,然后運(yùn)行兩次之后,加載時間為1116ms,比之前長73%,沒有變化。因此,聲稱 HTTP/2 “快30%” 似乎有點(diǎn)鬼鬼祟祟。

我創(chuàng)建這個表是為了嘗試量化 HTTP/2 所帶來的差異,但實(shí)際上我唯一能說的是“它可能沒有顯著的差異”。

真正令人吃驚的是***兩行。那是舊的 Windows 和 HTTP/1.1,我打賭會慢得多,我想我需把網(wǎng)速調(diào)慢一點(diǎn)。

我從微軟的網(wǎng)站上下載了一個Windows 7 虛擬機(jī)來測試這些東西。它是 IE8 自帶的,我想把它升級到IE9,所以我轉(zhuǎn)到微軟的IE9下載頁面…

如何使用Webpack分離數(shù)據(jù)

關(guān)于HTTP/2 的***一個問題,你知道它現(xiàn)在已經(jīng)內(nèi)置到 Node中了嗎?如果你想體驗(yàn)一下,我編寫了一個帶有g(shù)zip、brotli和響應(yīng)緩存的小型100行HTTP/2服務(wù)器

,以滿足你的測試樂趣。

這就是我要講的關(guān)于 bundle splitting 的所有內(nèi)容。我認(rèn)為這種方法唯一的缺點(diǎn)是必須不斷地說服人們加載大量的小文件是可以的。

Code splitting (加載你需要的代碼)

我說,這種特殊的方法只有在某些網(wǎng)站上才有意義。

我喜歡應(yīng)用我剛剛編造的 20/20 規(guī)則:如果你的站點(diǎn)的某個部分只有 20% 的用戶訪問,并且它大于站點(diǎn)的 JavaScript 的 20%,那么你應(yīng)該按需加載該代碼。

如何決定?

假設(shè)你有一個購物網(wǎng)站,想知道是否應(yīng)該將“checkout”的代碼分開,因?yàn)橹挥?0%的訪問者才會訪問那里。

首先要做的是賣更好的東西。

第二件事是弄清楚多少代碼對于結(jié)賬功能是完全獨(dú)立的。 由于在執(zhí)行“code splitting” 之前應(yīng)始終先“bundle splitting’ ”,因此你可能已經(jīng)知道代碼的這一部分有多大。

它可能比你想象的要小,所以在你太興奮之前做一下加法。例如,如果你有一個 React 站點(diǎn),那么你的 store、reducer、routing、actions 等都將在整個站點(diǎn)上共享。唯一的部分將主要是組件和它們的幫助類。

因此,你注意到你的結(jié)帳頁面完全獨(dú)特的代碼是 7KB。 該網(wǎng)站的其余部分是 300 KB。 我會看著這個,然后說,我不打算把它拆分,原因如下:

  •  提前加載不會變慢。記住,你是在并行加載所有這些文件。查看是否可以記錄 300KB 和 307KB 之間的加載時間差異。

* 如果你稍后加載此代碼,則用戶必須在單擊“TAKE MY MONEY”之后等待該文件 - 你希望延遲的最小的時間。

  •  Code splitting 需要更改應(yīng)用程序代碼。 它引入了異步邏輯,以前只有同步邏輯。 這不是火箭科學(xué),但我認(rèn)為應(yīng)該通過可感知的用戶體驗(yàn)改進(jìn)來證明其復(fù)雜性。

讓我們看兩個 code splitting 的例子。

Polyfills

我將從這個開始,因?yàn)樗m用于大多數(shù)站點(diǎn),并且是一個很好的簡單介紹。

我在我的網(wǎng)站上使用了一些奇特的功能,所以我有一個文件可以導(dǎo)入我需要的所有polyfill, 它包括以下八行:

// polyfills.js   require('whatwg-fetch');  require('intl');  require('url-polyfill');  require('core-js/web/dom-collections');  require('core-js/es6/map');  require('core-js/es6/string');  require('core-js/es6/array');  require('core-js/es6/object');

在 index.js 中導(dǎo)入這個文件。

// index-always-poly.js  import './polyfills';  import React from 'react';  import ReactDOM from 'react-dom';  import App from './App/App';  import './index.css';  const render = () => {    ReactDOM.render(<App />, document.getElementById('root'));  }  render(); // yes I am pointless, for now

使用 bundle splitting 的 Webpack 配置,我的 polyfills 將自動拆分為四個不同的文件,因?yàn)檫@里有四個 npm 包。 它們總共大約 25 KB,并且 90% 的瀏覽器不需要它們,因此值得動態(tài)加載它們。

使用 Webpack 4 和 import() 語法(不要與 import 語法混淆),有條件地加載polyfill 非常容易。

import React from 'react';  import ReactDOM from 'react-dom';  import App from './App/App';  import './index.css';  const render = () => {    ReactDOM.render(<App />, document.getElementById('root'));  }  if (    'fetch' in window &&    'Intl' in window &&    'URL' in window &&    'Map' in window &&    'forEach' in NodeList.prototype &&    'startsWith' in String.prototype &&    'endsWith' in String.prototype &&    'includes' in String.prototype &&    'includes' in Array.prototype &&    'assign' in Object &&    'entries' in Object &&    'keys' in Object  ) {    render();  } else {    import('./polyfills').then(render);  }

合理? 如果支持所有這些內(nèi)容,則渲染頁面。 否則,導(dǎo)入 polyfill 然后渲染頁面。 當(dāng)這個代碼在瀏覽器中運(yùn)行時,Webpack 的運(yùn)行時將處理這四個 npm 包的加載,當(dāng)它們被下載和解析時,將調(diào)用 render() 并繼續(xù)進(jìn)行。

順便說一句,要使用 import(),你需要 Babel 的動態(tài)導(dǎo)入插件。另外,正如 Webpack 文檔解釋的那樣,import() 使用 promises,所以你需要將其與其他polyfill分開填充。

基于路由的動態(tài)加載(特定于React)

回到 Alice 的例子,假設(shè)站點(diǎn)現(xiàn)在有一個“管理”部分,產(chǎn)品的銷售者可以登錄并管理他們所銷售的一些沒用的記錄。

本節(jié)有許多精彩的特性、大量的圖表和來自 npm 的大型圖表庫。因?yàn)槲乙呀?jīng)在做 bundle splittin 了,我可以看到這些都是超過 100 KB 的陰影。

目前,我有一個路由設(shè)置,當(dāng)用戶查看 /admin URL時,它將渲染 <AdminPage>。當(dāng)Webpack 打包所有東西時,它會找到 import AdminPage from './AdminPage.js'。然后說"嘿,我需要在初始負(fù)載中包含這個"

但我們不希望這樣,我們需要將這個引用放到一個動態(tài)導(dǎo)入的管理頁面中,比如import('./AdminPage.js') ,這樣 Webpack 就知道動態(tài)加載它。

它非常酷,不需要配置。

因此,不必直接引用 AdminPage,我可以創(chuàng)建另一個組件,當(dāng)用戶訪問 /admin URL時將渲染該組件,它可能是這樣的:

// AdminPageLoader.js   import React from 'react';  class AdminPageLoader extends React.PureComponent {    constructor(props) {      super(props);      this.state = {        AdminPage: null,      }    }    componentDidMount() {      import('./AdminPage').then(module => {        this.setState({ AdminPage: module.default });      });    }    render() {     const { AdminPage } = this.state;      return AdminPage        ? <AdminPage {...this.props} />        : <div>Loading...</div>;    }  }  export default AdminPageLoader;

這個概念很簡單,對吧? 當(dāng)這個組件掛載時(意味著用戶位于 /admin URL),我們將動態(tài)加載 ./AdminPage.js,然后在狀態(tài)中保存對該組件的引用。

在 render 方法中,我們只是在等待 <AdminPage> 加載時渲染 <div>Loading...</div>,或者在加載并存儲狀態(tài)時渲染 <AdminPage>。

我想自己做這個只是為了好玩,但是在現(xiàn)實(shí)世界中,你只需要使用 react-loadable ,如關(guān)于 code-splitting 的React文檔 中所述。

以上是“如何使用Webpack分離數(shù)據(jù)”這篇文章的所有內(nèi)容,感謝各位的閱讀!相信大家都有了一定的了解,希望分享的內(nèi)容對大家有所幫助,如果還想學(xué)習(xí)更多知識,歡迎關(guān)注創(chuàng)新互聯(lián)行業(yè)資訊頻道!

網(wǎng)頁標(biāo)題:如何使用Webpack分離數(shù)據(jù)
路徑分享:http://chinadenli.net/article2/piggic.html

成都網(wǎng)站建設(shè)公司_創(chuàng)新互聯(lián),為您提供虛擬主機(jī)做網(wǎng)站手機(jī)網(wǎng)站建設(shè)網(wǎng)站導(dǎo)航網(wǎng)站收錄面包屑導(dǎo)航

廣告

聲明:本網(wǎng)站發(fā)布的內(nèi)容(圖片、視頻和文字)以用戶投稿、用戶轉(zhuǎn)載內(nèi)容為主,如果涉及侵權(quán)請盡快告知,我們將會在第一時間刪除。文章觀點(diǎn)不代表本網(wǎng)站立場,如需處理請聯(lián)系客服。電話:028-86922220;郵箱:631063699@qq.com。內(nèi)容未經(jīng)允許不得轉(zhuǎn)載,或轉(zhuǎn)載時需注明來源: 創(chuàng)新互聯(lián)

成都做網(wǎng)站