微前端:前端的微服務(wù)
我們可以采用微服務(wù)架構(gòu)模式并將其應(yīng)用到前端嗎?
微服務(wù)是構(gòu)建可以獨立工作的小型自治團隊的流行方式。不幸的是,就其本質(zhì)而言,微服務(wù)只在后端工作。即使有最好的微服務(wù)架構(gòu),前端開發(fā)仍然需要高度的相互依賴,這會引入耦合和通信開銷,這會拖慢每個人的速度。
我們可以采用微服務(wù)架構(gòu)模式并將其應(yīng)用到前端嗎?事實證明我們可以。Netflix、Zalando和Capital One等公司已將這一模式推向前沿,為微前端奠定了基礎(chǔ)。本文將探討微前端、它們的優(yōu)點和缺點,以及它們與傳統(tǒng)微服務(wù)的不同之處。
前端的微服務(wù)
當(dāng)我們將微服務(wù)方法帶到前端時,我們就會得到微前端。換句話說,微前端由不同團隊擁有的組件組成,這些組件可以獨立部署。組裝這些組件以創(chuàng)建一致的用戶體驗。
從左到右,我們展示了 4 個場景。 跨越所有場景,中間的水平線將前端與后端分開。
在左側(cè),我們有一個跨越前端和后端(包括 UI)的單體。 接下來,我們在后端有一個單體應(yīng)用程序,在前端有一個 SPA 網(wǎng)頁(UI 與后端分離)。 在第三個位置,我們在前端有相同的 SPA,但在后端將單體拆分為微服務(wù)。 最后一個場景在后端使用微服務(wù),在前端使用微前端。 前端包括與其余部分隔離的不同組件或小部件。
單體可以以不同的方式分解。我們可以拆分前端和后端或在后端使用微服務(wù)。我們甚至可以將前端重新創(chuàng)建為由不同團隊管理的隔離組件的集合。
使用微前端,沒有一個團隊擁有整個 UI。相反,每個團隊都擁有一塊屏幕、頁面或內(nèi)容。例如,一個團隊可能負(fù)責(zé)搜索框,而另一個團隊可能會根據(jù)用戶的口味對建議進行編碼。其他團隊可能會對音樂播放器進行編碼、管理播放列表或呈現(xiàn)計費頁面。我們增加了復(fù)雜性,但作為回報,團隊獲得了更多的自主權(quán)。
音樂流媒體網(wǎng)站的線框圖。 總共有5個團隊:“主頁”本身的一個,播放列表的一個,推薦的一個,搜索框的一個,音樂播放器的一個。 每個團隊都在主頁內(nèi)分配了相應(yīng)的小部件或組件。
前端功能由不同的團隊管理,獨立部署,并以透明的方式注入到最終用戶的主頁中。
微前端的好處和挑戰(zhàn)
微前端提供與微服務(wù)類似的好處。也就是說,我們可以通過將前端代碼分解成獨立的部分來擴大開發(fā)規(guī)模,由不同的團隊負(fù)責(zé)。與微服務(wù)一樣,每個功能都可以隨時自行發(fā)布,幾乎不需要協(xié)調(diào)。這導(dǎo)致更頻繁的更新。
垂直團隊
微前端可以創(chuàng)建垂直團隊,這意味著一個全棧開發(fā)團隊可以同時擁有后端和前端的功能。
垂直團隊處理給定功能或組件的所有功能和代碼。 我們有 3 個團隊:建議、搜索和播放列表。 每個團隊都獨立于其他團隊管理其微服務(wù)后端和微前端。
全棧垂直團隊負(fù)責(zé)功能或組件的前端和后端。
可連續(xù)部署的組件
微前端的每個部分都是一個可部署的單元。這允許團隊發(fā)布他們的更改,而無需等待發(fā)布火車或依賴其他團隊完成他們的工作。最終結(jié)果是前端可以每天更新幾次。
每個團隊都有一個單獨的源存儲庫、CI/CD 管道和生產(chǎn)服務(wù),為微前端內(nèi)容提供服務(wù)。
所有獨立微前端的組合在客戶端呈現(xiàn)一個前端。
每個團隊都可以擁有單獨的存儲庫、CI/CD 管道和服務(wù)機器?;蛘?,我們可以在 monorepo 上托管所有內(nèi)容,并擁有一個共享的 CI/CD 管道。
微前端設(shè)計的挑戰(zhàn)
微前端的主要挑戰(zhàn)是創(chuàng)建一個快速響應(yīng)的客戶端。我們絕不能忽視這樣一個事實,即前端存在于內(nèi)存、CPU 和網(wǎng)絡(luò)有限的環(huán)境中,否則我們就有可能導(dǎo)致 UI 緩慢。
簡潔的用戶界面對于產(chǎn)品的成功至關(guān)重要。最近的一項調(diào)查指出,“1 秒內(nèi)加載的網(wǎng)站的轉(zhuǎn)化率是 5 秒內(nèi)加載的網(wǎng)站的 3 倍”。用戶必須等待的每一秒,錢都會被扔出窗外。
除了微服務(wù)所面臨的所有挑戰(zhàn)之外,微前端設(shè)計還帶來了一些問題:
- 隔離:每個團隊的代碼最終都必須在同一個瀏覽器上共存。我們必須慎重隔離單獨的模塊以避免代碼或樣式?jīng)_突。
- 共享資源:為避免重復(fù)并保持前端精簡,組件應(yīng)盡可能共享資產(chǎn)和庫,這可能會產(chǎn)生不良耦合。
- 可訪問性:嚴(yán)重依賴 JavaScript 來呈現(xiàn)頁面會對可訪問性產(chǎn)生負(fù)面影響。
- 樣式:當(dāng) UI 由各個團隊制作的組件組成時,保持一致的外觀更加復(fù)雜。小的風(fēng)格不一致會讓人感到不和諧。
- 協(xié)調(diào):有這么多活動部件,API 需要非常明確和穩(wěn)定。團隊必須協(xié)調(diào)微前端中不同組件之間以及后端微服務(wù)之間的通信方式。
構(gòu)建微前端的原則
有兩種互補的方法可以從單獨的微前端組件渲染統(tǒng)一的 UI:服務(wù)器端渲染和客戶端渲染。
服務(wù)器端渲染 (SSR)
服務(wù)器端渲染提供更快的性能和更易于訪問的內(nèi)容。在服務(wù)器上渲染是快速提供內(nèi)容的好選擇——尤其是在低功耗設(shè)備(如低端手機)上。當(dāng) JavaScript 被禁用時,它也是一種合適的后備模式。
服務(wù)器端渲染示意圖。 網(wǎng)絡(luò)服務(wù)器輪詢各種微服務(wù)。 他們用網(wǎng)絡(luò)服務(wù)器組裝并轉(zhuǎn)發(fā)給用戶瀏覽器的 HTML 片段進行回復(fù)。
網(wǎng)絡(luò)服務(wù)器從不同微服務(wù)提供的內(nèi)容中組裝完整的頁面。這是第一個內(nèi)容豐富的頁面。然后可以使用水合來添加更多動態(tài)內(nèi)容。
我們有幾種執(zhí)行 SSR 的方法:
- 服務(wù)器端包含(SSI):是一種由網(wǎng)絡(luò)服務(wù)器執(zhí)行的簡單腳本語言。該語言使用指令將 HTML 片段構(gòu)建成一個完整的頁面。這些片段可能來自其他文件或程序的響應(yīng)。所有主要的網(wǎng)絡(luò)服務(wù)器都支持 SSI,包括 Apache、Nginx 和 IIS。
- iframes:古老的 iframe 功能允許我們在頁面上嵌入任意 HTML 內(nèi)容。
- Edge Side Includes (ESI):一種更現(xiàn)代的 SSI 替代方案。ESI 可以處理變量,有條件,并支持更好的錯誤處理。緩存 HTTP 服務(wù)器(例如Varnish )支持 ESI 。
因此,例如,我們可以使用 SSI 從 HTML 渲染頁面:
該virtual關(guān)鍵字使網(wǎng)絡(luò)服務(wù)器從 URL 或 CGI 程序請求內(nèi)容。在我們的例子中,我們需要設(shè)置網(wǎng)絡(luò)服務(wù)器以/hello-world使用合適的片段根據(jù)路徑響應(yīng)請求:
SSR 在許多 Web 框架中用于渲染第一個屏幕。此外,還有一些有趣的特定于 SSR 的實用程序,例如compoxure、nodei和Tail。
客戶端渲染 (CSR)
客戶端渲染通過從微服務(wù)獲取數(shù)據(jù)并操作 DOM 在用戶瀏覽器中構(gòu)建頁面。大多數(shù) Web 框架使用某種形式的 CSR 來改善用戶體驗。
客戶端渲染示意圖。 用戶的瀏覽器從 CDN 下載頁面源。
在加載時,頁面從不同的微服務(wù)端點加載數(shù)據(jù)并動態(tài)呈現(xiàn)視圖。
CSR 使用端點提供的數(shù)據(jù)在用戶瀏覽器上動態(tài)呈現(xiàn)頁面。
我們編寫松散耦合組件的主要工具是自定義元素。自定義元素是 HTML 標(biāo)準(zhǔn)的一部分。它們允許我們創(chuàng)建新的 HTML 標(biāo)記并將邏輯和行為附加到它們。
使用 JavaScript 從頁面動態(tài)裝載和卸載自定義元素:
定義后,我們可以像使用任何其他 HTML 標(biāo)記一樣使用新元素:
在示例中,整個頁面將包含一個用于獲取 JavaScript 組件的腳本標(biāo)記:
雖然大多數(shù)前端框架都可用于微前端,但有些框架是專門為它們設(shè)計的:
- Piral:實現(xiàn)稱為pilets的獨立組件。Pilets 是捆綁內(nèi)容和行為的模塊。
- Ragu:框架的框架。它允許我們將編寫在任何框架中的代碼作為小部件嵌入。
- 單一 SPA:一個元框架,用于將 UI 拼湊在一起,使用 React、Angular 和 Ember 等前端框架的任意組合。
- Frint:另一個用于構(gòu)建基于組件的應(yīng)用程序的模塊化框架。與 React、Vue 和 Preact 集成。
- Module Federation:一個 WebPack 插件,通過捆綁單獨的構(gòu)建來創(chuàng)建單頁應(yīng)用程序 (SPA)。這些構(gòu)建可以獨立于每個構(gòu)建
結(jié)論
切換到微前端架構(gòu)可以給我們的開發(fā)團隊更多的自主權(quán),從而加速開發(fā)。但是,適用于微服務(wù)的相同警告也適用于微前端。我們需要經(jīng)過驗證的設(shè)計,這意味著微前端不適合新建項目。
新項目最好采用傳統(tǒng)模式,例如由單個團隊管理的單頁應(yīng)用程序 (SPA)。只有前端經(jīng)受住了時間的考驗,我們才能將微前端視為前進的方向。