島嶼架構(Islands Architecture)如何兼顧 UX 與 SEO ?
島嶼架構(Islands Architecture)是一個新的前端架構概念。最早由 Katie Sylor-Miller 於 2019 年提出 Component Island 的概念,後由 Jason Miller 完整描述。此架構藉由改變 SSR 網頁可互動內容的 Hydrate 方式提高載入效率,以在不犧牲使用者體驗同時兼顧使用者體驗狀況下建立網頁。
島嶼架構 圖片來源:jasonformat.com - "Islands Architecture" by Jason Miller
SSR 的現況
在說明島嶼架構之前,我們必須先了解過去與現在,前端世界中是如何實現 SSR 的。
舉例來說,在某 SSR 的頁面中有多個不同區塊提供和使用者互動的功能。當網頁載入時,會有一腳本統一排程各個區塊進行 Hydration。當其中某個區塊在 Hydrate 過程中預到了須較長時間完成的工作,其他尚未 hydrate 的區塊也得等待他完成。此時,使用者可能會納悶的看著眼前空有軀殼卻無法使用的網頁。
在撰寫網站時,我們需要在互動性和 SEO 上做出取捨,而很多的 SSR 框架都標榜其優異的 SEO。但是現實中,我們不該為了觸及而放棄互動性,也不該為了互動性而忽略觸及,在理想的狀況中這兩者應要是能共存的。
撰寫 SSR 網頁的開發者卻經常忽略載入互動功能時的效率,而網頁若是不能即時的提供互動,會影響到使用者的體驗。這些效能問題可以透過許多不同的方式改善,例如根據該區塊是否可見、各元件的優先度來進行載入的排程,但這並沒有根本的解決問題。
島嶼架構原理
於島嶼架構中,使用者預設不會皆收到任何 JavaScript。包含網頁中可見的內容都已經在伺服端 render,而可互動的區塊(島嶼)則是由該區塊所 render 出的 HTML 作為「placeHolder」填入。當網頁載入時,各個島嶼會各自進行 Hydrate,並重複利用最初接收到的 HTML 內容。
這樣的作法有幾個好處:
Time to Interactive(Time-to-Interactive)
在這樣的架構中,單一區塊的性能問題不會影響到其他區塊,因為各區塊中不存在母子關係。即使單一區塊停滯,瀏覽器也能夠先行完成其他區塊的 Hydration,並且降低 TTI,達到更佳的使用者體驗。
開發時的考量
對比多數的 SSR 框架,在島嶼架構中這些優點並非開發者須主動實做的優化,而是整個框架基礎的一部分。開發者和團隊能夠放心的撰寫載入速度極快的網頁,而不用擔心墮入 Client-side 的 Hydrate 的效能陷阱。
網頁大小
最終抵達使用者端的資料只有 HTML 和用來提供各島嶼互動性的 JavaScript,網頁也不需要為了 Re-Hydrate 而重建大量複雜的 Vitual DOM。
無障礙網頁
使用原生 HTML 連結,無論該連結在實際使用時是否會被攔截並使用其他腳本處理,都有易於提昇該網頁的無障礙友善程度。
島嶼架構的缺點
雖然島嶼架構向擁有許多優勢,但是很大程度上它也存在自己的缺陷。
不適合高度互動的環境
以社群軟體為例,要顯示大量的對話和發文可能會用上上千個島嶼,島嶼的優勢就不再那麼明顯,反而可能會對於頁面中顯示推文的數量造成限制,或是得在同專案中回頭使用傳統於客戶端生成該內容的方式。
不易 Migrate 現有專案到島嶼架構
因為這個架構與現有 SSR 框架在基礎概念上的差異,我們很難直接將現有專案在最低修改的狀況下遷移到這個架構。而所有新的專案也被局現於現有寥寥無幾的 Island Architecture 前端框架中,或是從頭開發專用的框架。
尚未形成足夠大的社群
這個前端架構的概念最早由 Katie Sylor-Miller 在和 Jason Miller 的會面中提出。隨後由 Jason Miller 於個人部落格的文章中整理並詳細描述,除此之外的討論並不熱烈。
雖然近期有許多前端框架開始採用島嶼架構,但是實際使用的程度還不高,代表可能還有許多實務上的問題尚未被發覺。
個人心得
我認為島嶼架構提出獨立 Hydrate 現有 HTML 的概念很有趣,但是整個架構所提供的優勢並無法蓋過所造成的其他困難,例如先前提到不適合高度互動的環境。
如果我沒有理解錯誤,Island Architecture 是不允許在客戶端改變 DOM 結構的,若是我們有需要動態改變 DOM 的需求,例如先前提到的社群媒體平台的案例,使用者需要不斷刷新頁面才能看到新的內容。
當然,所有工具都有他適用的場景,而島嶼架構也有它最適合被使用的領域。但我個人認為他所帶來的不便對於他的應用產生了不小的限制,若是可以選擇性的使用 Virtual DOM rehydrate 部份網頁,可以讓主要使用此架構的框架更加泛用。
實際案例
Fresh
官網:Link
建立於 Deno 上,採用 Jason Miller 的 preact 函式庫所建立的前端框架。得益於 Deno deploy,所有網頁接在 Edge render 完成,再由 Client 端完成島嶼的 Hydration。