自拍偷在线精品自拍偷,亚洲欧美中文日韩v在线观看不卡

Web性能優(yōu)化: 使用Webpack分離數(shù)據(jù)的正確方法

開(kāi)發(fā) 前端
制定向用戶提供文件的最佳方式可能是一項(xiàng)棘手的工作。 有很多不同的場(chǎng)景,不同的技術(shù),不同的術(shù)語(yǔ)。在這篇文章中,我希望給你所有你需要的東西。

 [[258746]]

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

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

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

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

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

  •  Bundle splitting: 創(chuàng)建更多更小的文件,并行加載,以獲得更好的緩存效果,主要作用就是使瀏覽器并行下載,提高下載速度。并且運(yùn)用瀏覽器緩存,只有代碼被修改,文件名中的哈希值改變了才會(huì)去再次加載。
  •  Code splitting:只加載用戶最需要的部分,其余的代碼都遵從懶加載的策略,主要的作用就是加快頁(yè)面的加載速度,不加載不必要的代碼。

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

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

就讓我們一探究竟吧。

Bundle splitting

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

值得注意的是,由于 bundle splitting 都是關(guān)于緩存的,所以對(duì)于***次訪問(wèn)來(lái)說(shuō)沒(méi)有什么區(qū)別。

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

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

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

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

  •  Alice 每周訪問(wèn)我們的網(wǎng)站一次,持續(xù) 10 周
  •  我們每周更新一次網(wǎng)站
  •  我們每周都會(huì)更新我們的“產(chǎn)品列表”頁(yè)面
  •  我們也有一個(gè)“產(chǎn)品詳細(xì)信息”頁(yè)面,但我們目前還沒(méi)有開(kāi)發(fā)
  •  在第 5 周,我們向站點(diǎn)添加了一個(gè)新的 npm 包
  •  在第 8 周,我們更新了一個(gè)現(xiàn)有的 npm 包

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

基線

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

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

  1. // webpack.config.js   
  2. const path = require('path')  
  3. module.exports = {  
  4.   entry: path.resolve(__dirame, 'src/index.js')  
  5.   output: {  
  6.     path: path.resolve(__dirname, 'dist'),  
  7.     filename: '[name].[contenthash].js'  
  8.   }  

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

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

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

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

分解 vendor 包

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

  1.  // webpack.config.js   
  2. const path = require('path')  
  3. module.exports = {  
  4.   entry: path.resolve(__dirname, 'src/index.js'),  
  5.   output: {  
  6.     path: path.resolve(__dirname, 'dist'),  
  7.     filename: '[name].[contenthash].js',  
  8.   },  
  9.   optimization: {  
  10.     splitChunks: {  
  11.       chunks: 'all'  
  12.     }  
  13.   }  

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

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

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

總共:2.64 MB。

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

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

但我們可以做得更好。

分離每個(gè) npm 包

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

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

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

  1. const path = require('path');  
  2. const webpack = require('webpack');  
  3. module.exports = {  
  4.   entry: path.resolve(__dirname, 'src/index.js'),  
  5.   plugins: [  
  6.     new webpack.HashedModuleIdsPlugin(), // so that file hashes don't change unexpectedly  
  7.   ],  
  8.   output: {  
  9.     path: path.resolve(__dirname, 'dist'),  
  10.     filename: '[name].[contenthash].js',  
  11.   },  
  12.   optimization: {  
  13.     runtimeChunk: 'single',  
  14.     splitChunks: {  
  15.       chunks: 'all',  
  16.       maxInitialRequests: Infinity,  
  17.       minSize: 0,  
  18.       cacheGroups: {  
  19.         vendor: {  
  20.           test: /[\\/]node_modules[\\/]/,  
  21.           name(module) {  
  22.             // get the name. E.g. node_modules/packageName/not/this/part.js  
  23.             // or node_modules/packageName  
  24.             const packageName = module.context.match(/[\\/]node_modules[\\/](.*?)([\\/]|$)/)[1];  
  25.             // npm package names are URL-safe, but some servers don't like @ symbols  
  26.             return `npm.${packageName.replace('@', '')}`;  
  27.           },  
  28.         },  
  29.       },  
  30.     },  
  31.   },  
  32. }; 

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

  •  Webpack 有一些不太聰明的默認(rèn)設(shè)置,比如分割輸出文件時(shí)最多3個(gè)文件,最小文件大小為30 KB(所有較小的文件將連接在一起),所以我重寫(xiě)了這些。
  •  cacheGroups 是我們定義 Webpack 應(yīng)該如何將數(shù)據(jù)塊分組到輸出文件中的規(guī)則的地方。這里有一個(gè)名為 “vendor” 的模塊,它將用于從 node_modules 加載的任何模塊。通常,你只需將輸出文件的名稱定義為字符串。但是我將 name 定義為一個(gè)函數(shù)(將為每個(gè)解析的文件調(diào)用這個(gè)函數(shù))。然后從模塊的路徑返回包的名稱。因此,我們將為每個(gè)包獲得一個(gè)文件,例如 npm.react-dom.899sadfhj4.js。
  •  NPM 包名稱必須是 URL 安全的才能發(fā)布,因此我們不需要 encodeURI 的 packageName。 但是,我遇到一個(gè).NET服務(wù)器不能提供名稱中帶有 @(來(lái)自一個(gè)限定范圍的包)的文件,所以我在這個(gè)代碼片段中替換了 @。
  •  整個(gè)設(shè)置很棒,因?yàn)樗且怀刹蛔兊摹?無(wú)需維護(hù) - 不需要按名稱引用任何包。

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

總共: 2.24 MB.

與基線相比減少了44%,這對(duì)于一些可以從博客文章中復(fù)制/粘貼的代碼來(lái)說(shuō)非??帷?/p>

我想知道是否有可能超過(guò) 50% ? 這完全沒(méi)有問(wèn)題。

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

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

我之前提到過(guò),我們?cè)诖苏军c(diǎn)上有兩個(gè)不同的部分:產(chǎn)品列表和產(chǎn)品詳細(xì)信息頁(yè)面。 每個(gè)區(qū)域中的唯一代碼為25 KB(共享代碼為150 KB)。

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

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

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

  1. module.exports = {  
  2.   entry: {  
  3.     main: path.resolve(__dirname, 'src/index.js'),  
  4.     ProductList: path.resolve(__dirname, 'src/ProductList/ProductList.js'),  
  5.     ProductPage: path.resolve(__dirname, 'src/ProductPage/ProductPage.js'),  
  6.     Icon: path.resolve(__dirname, 'src/Icon/Icon.js'),  
  7.   },  
  8.   output: {  
  9.     path: path.resolve(__dirname, 'dist'),  
  10.     filename: '[name].[contenthash:8].js',  
  11.   },  
  12.   plugins: [  
  13.     new webpack.HashedModuleIdsPlugin(), // so that file hashes don't change unexpectedly  
  14.   ],  
  15.   optimization: {  
  16.     runtimeChunk: 'single',  
  17.     splitChunks: {  
  18.       chunks: 'all',  
  19.       maxInitialRequests: Infinity,  
  20.       minSize: 0,  
  21.       cacheGroups: {  
  22.         vendor: {  
  23.           test: /[\\/]node_modules[\\/]/,  
  24.           name(module) {  
  25.             // get the name. E.g. node_modules/packageName/not/this/part.js  
  26.             // or node_modules/packageName  
  27.             const packageName = module.context.match(/[\\/]node_modules[\\/](.*?)([\\/]|$)/)[1];  
  28.             // npm package names are URL-safe, but some servers don't like @ symbols  
  29.             return `npm.${packageName.replace('@', '')}`;  
  30.           },  
  31.         },  
  32.       },  
  33.     },  
  34.   },  
  35. }; 

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

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

只有 1.815 MB!

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

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

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

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

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

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

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

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

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

#2:每個(gè)webpack包中沒(méi)有 開(kāi)銷/引用 代碼嗎?

是的,這也是真的。

好吧,狗屎:

  •  more files = 更多 Webpack 引用
  •  more files = 不壓縮

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

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

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

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

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

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

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

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

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

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

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

,以滿足你的測(cè)試樂(lè)趣。

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

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

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

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

如何決定?

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

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

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

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

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

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

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

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

讓我們看兩個(gè) code splitting 的例子。

Polyfills

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

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

  1. // polyfills.js   
  2. require('whatwg-fetch');  
  3. require('intl');  
  4. require('url-polyfill');  
  5. require('core-js/web/dom-collections');  
  6. require('core-js/es6/map');  
  7. require('core-js/es6/string');  
  8. require('core-js/es6/array');  
  9. require('core-js/es6/object'); 

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

  1. // index-always-poly.js  
  2. import './polyfills';  
  3. import React from 'react';  
  4. import ReactDOM from 'react-dom';  
  5. import App from './App/App';  
  6. import './index.css';  
  7. const render = () => {  
  8.   ReactDOM.render(<App />, document.getElementById('root'));  
  9.  
  10. render(); // yes I am pointless, for now 

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

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

  1. import React from 'react';  
  2. import ReactDOM from 'react-dom';  
  3. import App from './App/App';  
  4. import './index.css';  
  5. const render = () => {  
  6.   ReactDOM.render(<App />, document.getElementById('root'));  
  7.  
  8. if (  
  9.   'fetch' in window &&  
  10.   'Intl' in window &&  
  11.   'URL' in window &&  
  12.   'Map' in window &&  
  13.   'forEach' in NodeList.prototype &&  
  14.   'startsWith' in String.prototype &&  
  15.   'endsWith' in String.prototype &&  
  16.   'includes' in String.prototype &&  
  17.   'includes' in Array.prototype &&  
  18.   'assign' in Object &&  
  19.   'entries' in Object &&  
  20.   'keys' in Object  
  21. ) {  
  22.   render();  
  23. } else {  
  24.   import('./polyfills').then(render);  

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

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

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

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

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

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

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

它非常酷,不需要配置。

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

  1. // AdminPageLoader.js   
  2. import React from 'react';  
  3. class AdminPageLoader extends React.PureComponent {  
  4.   constructor(props) {  
  5.     super(props);  
  6.     this.state = {  
  7.       AdminPage: null,  
  8.     }  
  9.   }  
  10.   componentDidMount() {  
  11.     import('./AdminPage').then(module => {  
  12.       this.setState({ AdminPage: module.default });  
  13.     });  
  14.   }  
  15.   render() { 
  16.     const { AdminPage } = this.state;  
  17.     return AdminPage  
  18.       ? <AdminPage {...this.props} />  
  19.       : <div>Loading...</div> 
  20.   }  
  21.  
  22. export default AdminPageLoader; 

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

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

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

總結(jié)

對(duì)于上面總結(jié)以下兩點(diǎn):

  •  如果有人不止一次訪問(wèn)你的網(wǎng)站,把你的代碼分成許多小文件。
  •  如果你的站點(diǎn)有大部分用戶不訪問(wèn)的部分,則動(dòng)態(tài)加載該代碼。

代碼部署后可能存在的BUG沒(méi)法實(shí)時(shí)知道,事后為了解決這些BUG,花了大量的時(shí)間進(jìn)行l(wèi)og 調(diào)試,這邊順便給大家推薦一個(gè)好用的BUG監(jiān)控工具 Fundebug。

 

責(zé)任編輯:龐桂玉 來(lái)源: segmentfault
相關(guān)推薦

2020-09-19 21:26:56

webpack

2019-03-15 15:00:49

Webpack構(gòu)建速度前端

2021-11-09 09:57:46

Webpack 前端分包優(yōu)化

2014-12-10 10:12:02

Web

2021-12-15 09:21:59

Webpack 前端Sourcemap

2019-03-18 15:35:45

WebCSS前端

2019-03-22 09:50:52

WebJavaScript前端

2021-09-27 08:16:38

Webpack 前端Cache

2018-06-13 10:27:04

服務(wù)器性能優(yōu)化

2019-03-26 10:02:16

WebpackJavascript前端

2024-04-24 08:25:00

性能Android生命周期

2022-03-02 11:13:50

Web前端開(kāi)發(fā)

2023-04-27 08:35:20

Webpack 4性能優(yōu)化

2021-11-05 10:36:19

性能優(yōu)化實(shí)踐

2021-11-15 09:44:49

Webpack 前端 Scope Hois

2023-05-31 08:19:23

Webpack4Webpack 5

2013-09-16 15:16:20

Android性能優(yōu)化

2009-12-31 15:21:48

Silverlight

2010-08-17 09:11:42

DB2數(shù)據(jù)庫(kù)備份性能

2014-04-04 10:16:51

Nginx配置Nginx性能優(yōu)化
點(diǎn)贊
收藏

51CTO技術(shù)棧公眾號(hào)