來看下知名團隊 Vercel 是如何使用【微前端】的吧!
Vercel 是一個 專為前端 開發者提供一體化平臺,簡化 Web 應用程序的構建和部署流程的公司。
除此之外,Vercel 團隊還開源了很多知名前端框架,比如:Next.js。所以這是一個典型的由眾多技術大佬組成的團隊。
差點跑偏了,咱們回到今天內容的主題!
在上周,Vercel 團隊公布了他們內部的【微前端設計方案】,所以咱們今天就來看看,這種頭部技術團隊,如何構建微前端方案的!
Vercel 如何采用微前端
官方團隊原文:https://vercel.com/blog/how-vercel-adopted-microfrontends
Vercel 的主網站曾是一體化的 Next.js 大型應用,既服務于普通訪客,也涵蓋登錄用戶的儀表板。然而,隨著 Vercel 的快速擴展,這種架構逐漸暴露出效率瓶頸:構建時間延長、依賴管理復雜化、工作流程頻繁卡頓。哪怕是微小的變更,都需要重新構建整個應用,延緩了獨立開發的進度,也影響了 CI 管道的運行效率。
于是,我們意識到:是時候進行架構變革了。
我們重新設計了架構,轉向垂直微前端,從而簡化了開發體驗,縮短了預覽構建時間和本地開發編譯時間——提升超過 40%。通過刪除非必要的微前端代碼,我們不僅減少了依賴的體積,還大幅降低了頁面加載時間,從而優化了用戶性能。此舉使得核心 Web 指標,如最大內容繪制 (LCP) 和 下一次繪制交互 (INP) 等都有了顯著提升。
在 Vercel 對微前端支持的基礎上,這一重大調整極大地改善了開發人員體驗 (DX),同時也為進一步優化提供了清晰的方向。通過此次內部大規模遷移測試,我們為平臺開發找到了更高效的流程。這篇博客不僅記錄了我們的轉型歷程,也展示了我們為開發者簡化流程、加速構建的實踐。今后,我們將持續提升單個應用程序的構建速度,在保障用戶性能的前提下,實現更優越的開發體驗 (DX)。
接下來,讓我們深入探討這次轉型的具體方法。
利用 Turbo
我們的第一步是著力改善 本地編譯、構建時間 和 CI 工作流程。借助 Turborepo 支持的 Vercel monorepo,我們能夠利用 Vercel Remote Cache 等功能,在 CI 管道中智能執行受影響的任務,大幅度減少了冗余操作。同時,我們引入了 Turbopack,極大提升了本地開發的速度。
然而,在推進這些優化的過程中,我們意識到:單一應用模式 對當前的 Vercel.com 已不再必要。通過應用內邏輯拆分,我們能夠避免構建和編譯中的無效工作,為開發人員帶來更顯著的速度提升。
水平和垂直微前端的選擇
為了進一步提升效率,我們引入了微前端架構,將大型應用分解為更小、更獨立的單元,支持跨產品領域和工程團隊的并行開發。微前端架構的主要分割策略包括:
- 垂直微前端:按路徑拆分,即每個頁面由單個應用管理。這種方式清晰而高效,適合具有獨立頁面邏輯的場景,確保每個頁面的開發與構建相對獨立。
- 水平微前端:按功能拆分,多個應用同時在一個頁面上運行。這種方式更適合需要在單頁內加載不同功能模塊的復雜應用場景。
圖片
微前端的兩種常見方法:單個頁面內的多個微前端(水平分割)或使用單個微前端管理整個頁面(垂直分割)。
每種微前端方法各有優缺點,根據具體用例都能帶來實質性好處。正如 Luca Mezzalira 在其微前端專著中所述,垂直和水平分割的選擇應依據項目需求權衡。
垂直分割 提供了良好的內聚力,但在切換不同微前端應用時可能帶來導航挑戰。雖然預取技術和 Chromium 的推測 API 可以緩解這一問題,但它們往往會增加資源使用,并受限于瀏覽器支持。
相比之下,水平分割 在同一頁面上運行多個微前端模塊,使得測試、發布、監控和調試更復雜,增加了運維管理難度。
我們最終選擇了 垂直微前端,將應用拆分為用戶少訪問的邏輯部分,以減少構建時間和依賴復雜度,同時保留了單一存儲庫的統一性。早期測試結果顯示,這種方法將構建時間縮短了 50%,并在開發與生產中簡化了模塊所有權,使開發人員能夠享受到單一應用的流暢體驗。
我們的遷移路徑
接下來,我們將單體前端應用遷移到更小的垂直應用中,以確保開發和用戶體驗不受影響。具體來說,我們將應用劃分為三個核心區域:
- 營銷
- 文檔
- 登錄儀表板
這些區域在功能和用戶界面上各自獨立,用戶不常在它們之間切換,因此非常適合分離。
圖片
用戶在單個微前端內體驗軟導航,在微前端之間移動時體驗硬導航
借助 Next.js 的 Multi-Zones 功能,我們可以無縫支持垂直微前端架構。為了控制遷移風險,我們選擇增量遷移,創建全新的應用而非分叉原始代碼庫。雖然分叉看似簡單,但它會帶來復雜的同步和一致性問題,尤其是在共享頁眉、頁腳和設計系統等組件時,需要在多個存儲庫中維護。
繼續使用 monorepo 并將代碼集中到 packages 中,使得共享組件能夠保持一致,同時可以靈活劃分關鍵區域。我們采用了 Turborepo 和 Dependency Cruiser 等工具,以便簡化分區和依賴管理過程。
圖片
Vercel 的 monorepo 采用“apps”文件夾中的獨立微前端結構,同時提升共享包以實現所有應用程序的無縫訪問。
通過功能標記,我們逐步將流量從單體前端應用轉移至新的微前端應用,從而在刪除舊代碼前驗證性能改進并將風險降至最低。一旦新頁面穩定運行一周且無錯誤,我們便從現有應用中移除舊代碼,從而逐步減少依賴并縮短構建時間。
圖片
在增量遷移期間,頁面同時存在于原始前端整體和新的微前端中。功能標志控制路由,直到微前端版本完全上線。
借助 monorepo 設置和垂直分區方法,我們得以快速行動,保持一致性并縮短構建時間,同時讓整個開發過程始終清晰、簡單。
吸取的教訓和管理權衡
在成功實現 Vercel.com 的微前端架構后,我們將同樣的方法擴展到其他項目,例如 2024 年 Next.js Conf 頁面。此頁面作為獨立于 nextjs.org 的應用運行,得益于新架構,不同的區域可以獨立提取為單獨的應用程序,從而加快開發周期。Next.js Conf 團隊和 Next.js 開發團隊可以快速、獨立地迭代更新。
然而,遷移過程中仍然面臨挑戰。為確保性能不受影響,我們采用了 Speed Insights 等工具來實時監控用戶體驗,并使用 Vercel Toolbar 跟蹤布局轉換和交互時間警報,確保頁面響應性達標。
我們也意識到在本地和預覽版環境中測試微前端相當困難。例如,草稿模式等功能不穩定,而性能瓶頸(如硬導航)更是常見問題。為了解決這些問題,我們應用了預取和預渲染策略,借助 Chromium 的推測規則優化用戶體驗。
平衡性能與資源使用的策略
為降低硬導航的延遲,我們首先加載初始頁面資源(JavaScript 和 CSS),在鏈接可見時提前填充瀏覽器緩存。這樣用戶導航時,資源可以立即從緩存中加載,減少等待時間。但頁面仍需渲染并獲取其他資源(如 HTML)來完成加載。
我們更進一步,在用戶交互(例如點擊鏈接)時預渲染頁面,使頁面在后臺完成渲染和網絡請求處理。這樣當用戶到達頁面時,體驗更接近即時加載。通過在適當時機執行預取和預渲染,我們在性能與資源使用之間取得了平衡,避免設備過載,同時提供了流暢的用戶體驗。
圖片
頁面在用戶交互時預渲染或預取,提供流暢的導航,同時優化性能和資源使用
展望
隨著迭代速度的加快,我們正在全力推動整個平臺的微前端發展,重點優化路由、簡化預覽工作流程,并提升硬導航性能。同時,我們正致力于增強儀表板體驗并解決工作流程中的挑戰,以全面提升微前端開發的效率。
向垂直微前端架構的轉變顯著提升了開發速度和構建效率。團隊現在能夠更加獨立地工作,同時通過共享軟件包保持一致性,形成了一個在自主性和統一性之間取得平衡的系統。
隨著我們不斷優化這一架構,團隊對其潛力充滿期待。無論您是在探索微前端,還是偏好單一應用模式,Vercel 致力于提供最佳的開發者體驗。