我的專案適合何種架構?
首先要問自己的問題是:專案是要用來達成什麼目的?人們造訪這個網站, 是為了存取內容, 還是要使用某項特定功能?
【文件─應用程式光譜】
為了讓各位更好想像, 我們來看兩個極端案例:
● 內容取向:想像一個簡單的部落格, 使用者可以瀏覽文章, 並在專門的文章頁面上閱讀完整內文。
● 行為取向:想像一個線上繪圖程式, 使用者可以到站上以手指繪圖, 並將畫作匯出成圖檔。
內容對第一個網站非常重要, 但第二個網站並不提供內容, 純粹提供功能給使用者。不過在大型專案中, 界線不會如此壁壘分明, 這時文件─應用程式光譜就派上用場了。概念是上述兩個例子分屬光譜的兩端, 此處我們用以下簡圖表示, 只要記得越往左表示網站為內容取向, 適合伺服端渲染技術;越往右表示行為取向, 適合客戶端渲染技術, 位於中間則屬於漸進式應用, 可採用通用渲染技術。
文件(內容取向) ←–––––––––––→ 應用程式(行為取向)
我們來看兩個範例。亞馬遜購物網站位在量表的哪個位置?亞馬遜提供了許多功能, 使用者可以搜尋、排序並過濾產品清單, 還能評價商品、管理退貨、或是和線上客服人員交談。但本質上, 亞馬遜是以內容為取向的網站。一個有助於判別的好問題是:『如果去除掉所有行為, 這個網站是否還有用處?』就亞馬遜網站來說, 答案是肯定的。額外的功能無疑很重要, 但若沒有產品, 這些功能都形同虛設。因此, 我們會把亞馬遜擺在光譜偏左的地方。對於類似的微前端網站, 保險的做法是從伺服器端渲染著手, 再視情況看是否要升級到通用渲染。
接著來看第二個範例。[CodePen.io](http://codepen.io/) 是個線上程式編輯器, 讓網頁開發人員和設計師能即時預覽 HTML、CSS 及 JS 程式碼合併的效果, 勾勒其構想或是尋找潛在錯誤。CodePen 也有一個活躍的線上社群, 許多人會在上頭展示自己的作品並分享程式碼。只要瀏覽 CodePen.io (http://codepen.io/) 上的公開目錄, 你就能找到一大堆振奮人心的新技術。那麼 CodePen 會落在光譜的哪個位置?這個問題較難回答, 因為無論是行為取向的線上編輯器, 還是內容取向的公開目錄, CodePen 在這兩方面都很強。若去掉 CodePen 所有的行為, 線上編輯器就不復存在;假若移除所有內容, 目錄則會不見, 但線上編輯器還會繼續存在, 因此, 我們可能會將 CodePen 定位在光譜中間。如果我們要以微前端架構來重新開發 CodePen, 會編制兩個團隊:編輯器團隊及目錄團隊。編輯團隊會選用客戶端整合, 目錄團隊則可能採用伺服器端路由。這樣便會是一個好起點。
但若要找出最佳的微前端架構, 我們就得進一步分析各種使用案例。我們的某個團隊是否需要整合另一個團隊的內容?使用者在網站上的動線為何?這些都是得繼續深究的問題。
【挑選正確的架構及整合技術】
我們接著來看, 如何以一套具體的方法判斷你的專案需要何種架構及整合方式。你要依序問自己這幾個問題:
● 是否需要高度分離?
● 需要快速的首次頁面載入嗎?
● 需要即時使用者回饋嗎?
最後再看看你的使用案例是否需要同時啟用多個微前端個體。下面來逐一說明各項提問。
<<需要高度分離 (對於老舊或第三方程式碼)>>
你是否想做到高度技術分離, 好區隔不同團隊的程式碼?為何不呢?大家都想這樣。分離及封裝手段一般能減少意料之外的副作用, 也能減少程式錯誤。但可惜的是, 選擇高度分離會犧牲掉其他許多開發上的可能性。
因此, 正確的問題是, 你是否真的需要高度分離?如果你得整合老舊系統, 這個系統不遵從新的命名空間規範, 且需要全域變數狀態才能正確運行的話, 你就不得不採用高度技術分離。安全因素是另一個好理由:如果你的專案需要採用不可信的第三方解決方案, 或者應用程式的某部分講求高度的安全層級, 比如得處理信用卡資料, 你就可能需要讓微前端個體彼此隔離。
<<快速的首次頁面載入/漸進增強原則>>
這是個二合一的問題。能有快速的首次頁面載入總是好事, 但這點的重要性大大取決於你的業務性質。如果你想要有更高的頁面搜尋結果排名, 就不該忽視首次頁面載入的效能, 因為 Google 這類搜尋引擎越來越青睞載入速度快速的網站。但就算搜尋排名不是你的主要目標, 許多個案研究皆顯示好的網頁效能能提升業務指標。
我們在第 3 章介紹過漸進增強的好處。如果你的專案定位是落在『文件─應用程式光譜』的中間或左邊, 我非常推薦你採用漸進增強的做法, 並鼓勵所有開發團隊學習這種開發方式。對於那些以 React 或 Angular 等框架起家的網頁工程師來說, 這種概念一開始可能聽來很奇怪。然而, 以漸進增強的思維來建構新功能, 並且回歸基本的網頁元素, 這樣所產出的軟體不僅較好維護、更容易理解, 也會更為穩定。
但若你的專案定位是落在光譜的極右端, 而且是要開發一個純網路應用程式的話, 一般來說是不會有內容可以增強的。在這種情況下, 走漸進增強的路線便會完全無益。
<<即時的使用者回饋>>
前一個問題探討的是首次頁面載入效能, 但你的網站對使用者的進一步互動會如何做出回應呢?典型的『點擊連結』及『從伺服器抓取 HTML』適用於很多案例, 特別是你使用 Ajax 技術來避免重新載入整個頁面的時候。在這種模式下, HTML 會完全由伺服器端產生。這意味著若要對使用者輸入做出回應, 就至少得往返伺服器端一次才能更新使用介面。
若想突破這種侷限, 你就得採用客戶端渲染。從伺服器抓資料會變得快些, 因為 JSON 資料比完整渲染的 HTML 更精簡, 但網路延遲依舊存在。不過, 客戶端渲染最顯著的優勢就在於能帶來立即回饋;就算使用者想看的資料仍在傳送途中, 頁面也能更新, 顯示載入中的空白區塊。
客戶端渲染更能讓開發人員採用『最佳化使用者介面』(optimistic UI)模式, 也就是嘗試渲染出最可能得到的結果, 藉此讓使用者感覺效能更快。以購物車為例, 當使用者要刪除某項產品時, 他們會點刪除鈕, 瀏覽器接著會呼叫伺服器端 API。等購物車內容傳回至客戶端時, 該產品便已自購物車中移除。但若採用使 optimistic UI, 你可以假設刪除商品的 API 通常會正常運作, 因此你不等待 API 回覆就直接在畫面上移除這個商品。萬一未能正常刪除, 就在使用者介面把商品放回購物車, 並顯示適當的錯誤訊息。
optimistic UI 十分強大, 但畢竟是先斬後奏的行為, 使用上務必謹慎。這項技巧能讓你對使用者輸入做出真正立即的回應, 不僅提升使用體驗, 也讓網站感覺更像個應用程式。
<<軟導覽>>
前一個問題探討了如何在微前端個體內提升使用者體驗。接著我們要來看, 使用者在不同團隊所開發的頁面之間切換時會發生什麼事情。這個問題劃分出兩種結果:相互連結的架構以及統一的架構, 我們在第 7 章有討論過。把跨團隊的轉頁用客戶端渲染來實現 (使用軟導覽), 究竟有多重要呢?
這個問題大大取決於你所劃分的團隊界線、團隊數量以及應用程式的使用模式。如果你是根據使用者的任務及需求來設置團隊, 使用者就不會那麼常跨越團隊界線。
假設你在替一間銀行開發網站, 這個網站有兩個截然不同的範疇, 分別交由兩組團隊來做開發:使用者查詢帳戶餘額的功能給團隊 A, 使用者試算並申請房貸的功能則由團隊 B 負責。為提供良好的使用者體驗, 這兩個領域本身可能都得具備高度互動性, 這可以由團隊自行決定。不過, 既然使用者鮮少會在查詢餘額及申請房貸之間切換, 你說不定用硬導覽串起兩者即可。
再舉另外一個例子。假設我們正在打造一個客服中心應用程式, 客服人員處理訂單的功能由團隊 A 負責, 個人化推薦的功能則由團隊 B 開發。有鑑於客服人員可能會頻繁在這兩者之間切換, 採用軟導覽就是個好主意。這讓應用程式轉頁起來更快, 也對客服人員的工作流程有所助益。
<<多個微前端個體共處於單一頁面上>>
如果你已經回答完以上的問題, 也得出適合你的高層級架構, 最後一個附加問題是:『你是否需要組合微前端個體?』如果答案是肯定的話, 你可以進一步找到對應的整合技巧。若你在打造一個純 SPA, 你會需要客戶端整合。若你選擇在伺服器端生成頁面, 就該用伺服器端整合。
區塊組合並不見得必要的。上一小節的銀行開發案例, 可能根本不需要整合。帳戶查詢和申貸可以是網站上兩個不同的區塊, 彼此用超連結串起即可。最常見的組合範例是標頭及導覽的頁面區塊, 通常由一個團隊負責開發,再讓其他團隊把這些區塊添加到自家的頁面上。
首先要問自己的問題是:專案是要用來達成什麼目的?人們造訪這個網站, 是為了存取內容, 還是要使用某項特定功能?
【文件─應用程式光譜】
為了讓各位更好想像, 我們來看兩個極端案例:
● 內容取向:想像一個簡單的部落格, 使用者可以瀏覽文章, 並在專門的文章頁面上閱讀完整內文。
● 行為取向:想像一個線上繪圖程式, 使用者可以到站上以手指繪圖, 並將畫作匯出成圖檔。
內容對第一個網站非常重要, 但第二個網站並不提供內容, 純粹提供功能給使用者。不過在大型專案中, 界線不會如此壁壘分明, 這時文件─應用程式光譜就派上用場了。概念是上述兩個例子分屬光譜的兩端, 此處我們用以下簡圖表示, 只要記得越往左表示網站為內容取向, 適合伺服端渲染技術;越往右表示行為取向, 適合客戶端渲染技術, 位於中間則屬於漸進式應用, 可採用通用渲染技術。
文件(內容取向) ←–––––––––––→ 應用程式(行為取向)
我們來看兩個範例。亞馬遜購物網站位在量表的哪個位置?亞馬遜提供了許多功能, 使用者可以搜尋、排序並過濾產品清單, 還能評價商品、管理退貨、或是和線上客服人員交談。但本質上, 亞馬遜是以內容為取向的網站。一個有助於判別的好問題是:『如果去除掉所有行為, 這個網站是否還有用處?』就亞馬遜網站來說, 答案是肯定的。額外的功能無疑很重要, 但若沒有產品, 這些功能都形同虛設。因此, 我們會把亞馬遜擺在光譜偏左的地方。對於類似的微前端網站, 保險的做法是從伺服器端渲染著手, 再視情況看是否要升級到通用渲染。
接著來看第二個範例。[CodePen.io](http://codepen.io/) 是個線上程式編輯器, 讓網頁開發人員和設計師能即時預覽 HTML、CSS 及 JS 程式碼合併的效果, 勾勒其構想或是尋找潛在錯誤。CodePen 也有一個活躍的線上社群, 許多人會在上頭展示自己的作品並分享程式碼。只要瀏覽 CodePen.io (http://codepen.io/) 上的公開目錄, 你就能找到一大堆振奮人心的新技術。那麼 CodePen 會落在光譜的哪個位置?這個問題較難回答, 因為無論是行為取向的線上編輯器, 還是內容取向的公開目錄, CodePen 在這兩方面都很強。若去掉 CodePen 所有的行為, 線上編輯器就不復存在;假若移除所有內容, 目錄則會不見, 但線上編輯器還會繼續存在, 因此, 我們可能會將 CodePen 定位在光譜中間。如果我們要以微前端架構來重新開發 CodePen, 會編制兩個團隊:編輯器團隊及目錄團隊。編輯團隊會選用客戶端整合, 目錄團隊則可能採用伺服器端路由。這樣便會是一個好起點。
但若要找出最佳的微前端架構, 我們就得進一步分析各種使用案例。我們的某個團隊是否需要整合另一個團隊的內容?使用者在網站上的動線為何?這些都是得繼續深究的問題。
【挑選正確的架構及整合技術】
我們接著來看, 如何以一套具體的方法判斷你的專案需要何種架構及整合方式。你要依序問自己這幾個問題:
● 是否需要高度分離?
● 需要快速的首次頁面載入嗎?
● 需要即時使用者回饋嗎?
最後再看看你的使用案例是否需要同時啟用多個微前端個體。下面來逐一說明各項提問。
<<需要高度分離 (對於老舊或第三方程式碼)>>
你是否想做到高度技術分離, 好區隔不同團隊的程式碼?為何不呢?大家都想這樣。分離及封裝手段一般能減少意料之外的副作用, 也能減少程式錯誤。但可惜的是, 選擇高度分離會犧牲掉其他許多開發上的可能性。
因此, 正確的問題是, 你是否真的需要高度分離?如果你得整合老舊系統, 這個系統不遵從新的命名空間規範, 且需要全域變數狀態才能正確運行的話, 你就不得不採用高度技術分離。安全因素是另一個好理由:如果你的專案需要採用不可信的第三方解決方案, 或者應用程式的某部分講求高度的安全層級, 比如得處理信用卡資料, 你就可能需要讓微前端個體彼此隔離。
<<快速的首次頁面載入/漸進增強原則>>
這是個二合一的問題。能有快速的首次頁面載入總是好事, 但這點的重要性大大取決於你的業務性質。如果你想要有更高的頁面搜尋結果排名, 就不該忽視首次頁面載入的效能, 因為 Google 這類搜尋引擎越來越青睞載入速度快速的網站。但就算搜尋排名不是你的主要目標, 許多個案研究皆顯示好的網頁效能能提升業務指標。
我們在第 3 章介紹過漸進增強的好處。如果你的專案定位是落在『文件─應用程式光譜』的中間或左邊, 我非常推薦你採用漸進增強的做法, 並鼓勵所有開發團隊學習這種開發方式。對於那些以 React 或 Angular 等框架起家的網頁工程師來說, 這種概念一開始可能聽來很奇怪。然而, 以漸進增強的思維來建構新功能, 並且回歸基本的網頁元素, 這樣所產出的軟體不僅較好維護、更容易理解, 也會更為穩定。
但若你的專案定位是落在光譜的極右端, 而且是要開發一個純網路應用程式的話, 一般來說是不會有內容可以增強的。在這種情況下, 走漸進增強的路線便會完全無益。
<<即時的使用者回饋>>
前一個問題探討的是首次頁面載入效能, 但你的網站對使用者的進一步互動會如何做出回應呢?典型的『點擊連結』及『從伺服器抓取 HTML』適用於很多案例, 特別是你使用 Ajax 技術來避免重新載入整個頁面的時候。在這種模式下, HTML 會完全由伺服器端產生。這意味著若要對使用者輸入做出回應, 就至少得往返伺服器端一次才能更新使用介面。
若想突破這種侷限, 你就得採用客戶端渲染。從伺服器抓資料會變得快些, 因為 JSON 資料比完整渲染的 HTML 更精簡, 但網路延遲依舊存在。不過, 客戶端渲染最顯著的優勢就在於能帶來立即回饋;就算使用者想看的資料仍在傳送途中, 頁面也能更新, 顯示載入中的空白區塊。
客戶端渲染更能讓開發人員採用『最佳化使用者介面』(optimistic UI)模式, 也就是嘗試渲染出最可能得到的結果, 藉此讓使用者感覺效能更快。以購物車為例, 當使用者要刪除某項產品時, 他們會點刪除鈕, 瀏覽器接著會呼叫伺服器端 API。等購物車內容傳回至客戶端時, 該產品便已自購物車中移除。但若採用使 optimistic UI, 你可以假設刪除商品的 API 通常會正常運作, 因此你不等待 API 回覆就直接在畫面上移除這個商品。萬一未能正常刪除, 就在使用者介面把商品放回購物車, 並顯示適當的錯誤訊息。
optimistic UI 十分強大, 但畢竟是先斬後奏的行為, 使用上務必謹慎。這項技巧能讓你對使用者輸入做出真正立即的回應, 不僅提升使用體驗, 也讓網站感覺更像個應用程式。
<<軟導覽>>
前一個問題探討了如何在微前端個體內提升使用者體驗。接著我們要來看, 使用者在不同團隊所開發的頁面之間切換時會發生什麼事情。這個問題劃分出兩種結果:相互連結的架構以及統一的架構, 我們在第 7 章有討論過。把跨團隊的轉頁用客戶端渲染來實現 (使用軟導覽), 究竟有多重要呢?
這個問題大大取決於你所劃分的團隊界線、團隊數量以及應用程式的使用模式。如果你是根據使用者的任務及需求來設置團隊, 使用者就不會那麼常跨越團隊界線。
假設你在替一間銀行開發網站, 這個網站有兩個截然不同的範疇, 分別交由兩組團隊來做開發:使用者查詢帳戶餘額的功能給團隊 A, 使用者試算並申請房貸的功能則由團隊 B 負責。為提供良好的使用者體驗, 這兩個領域本身可能都得具備高度互動性, 這可以由團隊自行決定。不過, 既然使用者鮮少會在查詢餘額及申請房貸之間切換, 你說不定用硬導覽串起兩者即可。
再舉另外一個例子。假設我們正在打造一個客服中心應用程式, 客服人員處理訂單的功能由團隊 A 負責, 個人化推薦的功能則由團隊 B 開發。有鑑於客服人員可能會頻繁在這兩者之間切換, 採用軟導覽就是個好主意。這讓應用程式轉頁起來更快, 也對客服人員的工作流程有所助益。
<<多個微前端個體共處於單一頁面上>>
如果你已經回答完以上的問題, 也得出適合你的高層級架構, 最後一個附加問題是:『你是否需要組合微前端個體?』如果答案是肯定的話, 你可以進一步找到對應的整合技巧。若你在打造一個純 SPA, 你會需要客戶端整合。若你選擇在伺服器端生成頁面, 就該用伺服器端整合。
區塊組合並不見得必要的。上一小節的銀行開發案例, 可能根本不需要整合。帳戶查詢和申貸可以是網站上兩個不同的區塊, 彼此用超連結串起即可。最常見的組合範例是標頭及導覽的頁面區塊, 通常由一個團隊負責開發,再讓其他團隊把這些區塊添加到自家的頁面上。