摘要:原文來自我的代碼拆分與動態導入當項目越做越大時,體積過大導致加載速度過慢,性能問題直接影響用戶體驗。這時我們會考慮將代碼拆分。
原文來自我的github: https://github.com/Vibing/blog
代碼拆分與動態導入當項目越做越大時,體積過大導致加載速度過慢,性能問題直接影響用戶體驗。
這時我們會考慮將代碼拆分。
拆分,顧名思義就是將一個大的東西拆分成N個小的東西,用公式表示就是:Sum = n * Sub
代碼拆分基于動態導入
什么是動態導入?就是我需要什么,你給我什么,我不需要的時候,你別給我,我嫌重。
動態導入可以將模塊分離成一個多帶帶的文件 在需要的時候加載進來。
對于動態導入,webpack 提供了兩個類似的技術。
第一種,也是優先選擇的方式是,使用符合 ECMAScript 提案 的 import() 語法。
第二種,則是使用 webpack 特定的 require.ensure。
從webpack 2以后,一般使用第一種。
async-loadable由于import()方法返回的是Promise對象,我們為了能方便的返回組件,
這里推薦使用async-loadable插件
例子代碼:
import loadable from "async-loadable"; import Loading from "./my-loading-component"; const LoadableComponent = loadable({ loader: () => import("./my-component"), loading: status =>, }); export default class App extends React.Component { render() { return ; } }
代碼里有熟悉的 import() 方法。async-loadable 使用 webpack 的動態導入,調用loadable方法可以方便的返回要使用的組件。
下面我將以我本人的項目經歷,來講解代碼拆分(code splitting)
代碼拆分前當初還是小白的我,一開始哪知道有代碼拆分這個技術啊,就一個人負責一個小項目,一開始項目不大,跑起來也是嗖嗖的,這里先貼一下路由代碼:
import Home from "./home"; import Page1 from "./page1"; import Page2 from "./page2";
這里沒有使用動態導入,而是直接將所有頁面靜態引入進來,然后賦到對應路由上。
這么做的壞處就是:打包時,整個項目所有的頁面都會打包到一個文件中,隨著頁面增多,這個文件也越來越大,最后我看了一下,達到了近25M(我嚇得打開度娘...)。
如果用一張圖來表示的話,這張圖在適合不過了:
哈哈,整個一坨有沒有。所有路由在這一坨紅色里,看著真特么憋屈啊
基于路由的代碼拆分打開度娘的我臉色漸漸有了好轉,通過搜索,看到了webpack有個code splitting功能(代碼拆分),
前面說過,代碼拆分其實就是使用動態導入的技術實現的,那么我們就使用動態導入來優化一把之前的路由:
import Loadable from "async-loadable"; import Loading from "./my-loading-component"; const Home = Loadable({ loader: () => import(`./home`), loading: Loading }); const Page1 = Loadable({ loader: () => import(`./page1`), loading: Loading }); const Paeg2 = Loadable({ loader: () => import(`./page2`), loading: Loading });} /> } /> } />
我們不再使用 import module from "url" 來靜態引入模塊,而是使用 loadComponent 來動態導入,它返回的是Loadable的結果,也就是我們想要的組件,我們把再把組件給對應的路由,這就完成了基于路由的代碼拆分。
使用以后,鄙人懷著激動的心情開始打包項目,當我看到控制臺的打包日志時,我的表情是這樣的:
咳咳,這種好事情當然要分享一下啦,你要的結果:
可以看到,webpack打包時已經將之前的一個臃腫文件按路由拆分成了三個文件,當我們點擊一個路由時,會動態加載對應的文件。
比如我點擊home頁面的路由時:
我再點擊page1時:
嗯,是按照路由來拆分的代碼,完美~
這樣看來,我們需要將之前的那張圖改成這樣的:
看著項目加載速度變快了,心里真特么高興
基于模塊拆分其實基于路由的代碼拆分已經可以滿足絕大多數項目了,再大的項目也能滿足。
但隨著項目做的多了,慢慢的發現了一個問題:代碼浪費。
比如我要做一個Tab切換的功能,像醬紫的:
對應的代碼大概是醬紫的:
import { Tabs } from "antd"; import TabOne from "./component/tab1"; import TabTwo from "./component/tab2"; import TabThree from "./component/tab3"; const TabPane = Tabs.TabPane; export default class Home extends Component { render() { return (); } }
Tab切換,每個前端小伙伴都做過,其實說白了,就是顯示隱藏的效果。
但是在這個頁面中,已經把每個Tab里的代碼都加載進來了,如果用戶只看第一個Tab,其他Tab不點擊,就造成了代碼浪費。
如何解決這個問題呢?還是那句話:我需要什么,你給我什么,我不需要的時候,你別給我,我嫌重。
我們使用動態導入的方式改造一下代碼:
import { Tabs } from "antd"; import Loadable from "async-loadable"; import TabOne from "./component/tab1"; import Loading from "./component/loading"; const TabPane = Tabs.TabPane; const loadComponent = path => Loadable({ loader: () => import(`${path}`), loading: Loading }); const Tab2 = loadComponent("./component/tab2.tsx"); const Tab3 = loadComponent("./component/tab3.tsx"); export default class Home extends Component { render() { return (); } }
同樣 我們不再使用import module from "url"的方式,而是使用 loadComponent 方法動態導入。
由于TabOne是第一個默認顯示的,所以沒必要動態導入。
現在我們來點擊Tab 2看看效果:
非常棒,正是我們想要的。
再點擊Tab 3 :
簡直完美!
文章版權歸作者所有,未經允許請勿轉載,若此文章存在違規行為,您可以聯系管理員刪除。
轉載請注明本文地址:http://specialneedsforspecialkids.com/yun/95356.html
摘要:按照的要求我需要將的坐標拆分為多行。到這里相當于將列中所有文本拆成了一個巨大的表,表中每個單元格有一個值。有些行拆分后的元素比較少,沒有值可以填充的單元格補充會把整個表逐行堆疊成一列。彩蛋我在列拆分為多行的基礎上,還將拆分成了兩個變量。 背景 手頭的項目要求用 Tableau 創建一個 story,數據集是摩拜上海城區用戶使用數據。其中有一個維度的數據處理起來有點棘手。 數據格式 sh...
摘要:拆分了錄屏代碼,監控插件壓縮至,另外我們還原了部分,幫助用戶更方便地。請大家及時更新哈拆分錄屏代碼從版本開始,我們拆分了錄屏代碼。自從年雙十一正式上線,累計處理了億錯誤事件,付費客戶有金山軟件百姓網等眾多品牌企業。 摘要: BUG監控插件壓縮至18K。 showImg(https://segmentfault.com/img/bVbpIPC?w=900&h=383); 1.7.1拆分了...
摘要:劃分標準根據稿,不同的展示模塊分為不同的組件。比如頂部底部導航列表等容器組件業務組件與數據源后臺本地存儲進行數據傳輸操作不止是劃分標準根據業務功能劃分。最常見的是列表組件。 為什么要拆分組件 提高可讀性、可維護性 如果不拆分 代碼量大,所有內容集中在一起 相同組件無法復用 業務開發分工不明確,開發人員要關心非業務的代碼 改代碼時,可能會影響其他業務,牽一發動全身(耦合) 任何一個操作...
閱讀 2662·2021-11-25 09:43
閱讀 2472·2021-09-22 15:29
閱讀 984·2021-09-22 15:17
閱讀 3628·2021-09-03 10:36
閱讀 2223·2019-08-30 13:54
閱讀 1740·2019-08-30 11:23
閱讀 1163·2019-08-29 16:58
閱讀 1290·2019-08-29 16:14