跳到內容

Astro 群島

Astro 開創並推廣了群島前端架構,打造更佳的前端效能,避免靠 JavaScript 產生所有內容的做法,並自動移除頁面中非必要的 JavaScript。開發者能把他們最喜歡的 UI 元件和框架帶來 Astro,而且仍然能享有前述好處。

「元件群島」一詞最早由 Etsy 的前端架構師 Katie Sylor-Miller 於 2019 提出,後由 Preact 作者 Jason Miller 於 2020 年 8 月 11 日在這篇文章延伸。

「群島」架構的構想看似簡單:在伺服器端算繪 HTML 頁面,接著在高度動態的區域周圍嵌入預留位置或插槽 [⋯⋯] 這些區域可在客戶端「注水」,形成各自獨立的小工具,重複使用最初由伺服器端算繪的 HTML。 — Jason Miller,Preact 作者

這種架構與衍伸作法也稱作部分水合作用(partial hydration)選擇性水合作用(selective hydration)

對比之下,大部分以 JavaScript 為基礎的 web 框架則會算繪整個網站並為其注水(hydrate),把網站當作一個巨大的 JavaScript 應用程式(也稱作單頁應用程式或 SPA)。SPA 簡潔且能做到許多事,但它高度依賴客戶端的 JavaScript,導致頁面載入效能不佳。

SPA 依舊存在發揮空間,甚至可以嵌入到 Astro 頁面之中。然而時至今日,其缺乏對選擇性注水(selectively hydrate)與策略性注水(strategically hydrate)的原生支援,儼然成為 web 開發時較拙劣的選擇。

拜 Sylor-Miller 提出的元件群島架構所賜,Astro 以首個內建選擇性水合作用的主流 JavaScript web 框架聞名。

什麼是 Astro 群島?

標題為 什麼是 Astro 群島?

一座 Astro「島嶼」指的是頁面中任一可互動的 UI 元件。想像一座互動式小工具島嶼,座落在靜態、輕量、由伺服器端算繪的 HTML 汪洋中。

頁首(互動式島嶼)

如文字、圖片等靜態內容。

出處:Islands Architecture: Jason Miller

島嶼之間相互獨立,且多座島嶼可以在同一個頁面並存。雖然獨立,但島嶼之間也能共享狀態,互相溝通。

這種彈性讓 Astro 支援多種 UI 框架,例如 ReactPreactSvelteVueSolidJS。由於島嶼之間相互獨立,你甚至可以在各頁面混用多個框架。

Astro 預設會將所有 UI 元件算繪成靜態的 HTML 與 CSS,自動移除所有客戶端的 JavaScript

src/pages/index.astro
<MyReactComponent />

聽起來有點嚴格,但正是這行為讓 Astro 網站預設即迅速,避免開發者不小心傳送不必要或不想要的 JavaScript,進而拖慢網站效能。

如果要把靜態 UI 元件轉換成互動式島嶼,只需加上 client* 指令即可。Astro 會自動建構、打包客戶端 JavaScript,並為其優化效能。

src/pages/index.astro
<!-- 這個元件現在可以在頁面上互動了!網站其餘部分則維持靜態。 -->
<MyReactComponent client:load />

client* 指令標記可互動元件後,島嶼的客戶端 JavaScript 才會載入。

能否互動是以元件為等級設定,因此你可以根據各元件的用途決定不同的載入優先順序。舉例來說,client:idle 讓元件等到瀏覽器閒置時才載入,而 client:visible 則會使元件等到進入可視區域時才載入。

群島的優勢是什麼?

標題為 群島的優勢是什麼?

使用 Astro 群島建立網站最顯著的優勢就是效能:大部分網站內容都會轉換成快速、靜態的 HTML,而 JavaScript 只會在個別所需的元件中載入。JavaScript 是其中一個載入速度最慢的資源,所以每個 Byte 都要斤斤計較。

另一個優勢是平行載入。如上面的例子所闡釋,低優先度的「圖片輪播」不需要阻擋到高優先度的「頁首島嶼」。兩個平行載入且獨立注水,就表示頁首可以立即互動,而不用等待較肥大的圖片輪播拖慢整個網頁。

更棒的是,你可以明確告訴 Astro 如何、何時算繪各個元件。如果載入圖片輪播的成本較高,你可以附加特殊的客戶端指令,告訴 Astro:當輪播在頁面上可見時才會載入,如果使用者不會看到那就不會載入。

身為開發人員,你可以明確告訴 Astro,頁面的哪些元件需要在瀏覽器上執行。Astro 會確實為需要的地方注水,讓網站其他部分維持靜態 HTML。

群島是讓 Astro 效能達到預設即迅速的秘密武器!

貢獻

你有哪些想法?

社群
京ICP备15031610号-99