Day2 - Astro Series: Problem and Solution

Astro 系列文第二日:現有問題與解方

一個漂亮的漸層背景上面有一句標題:「現有問題與解方」

前言

前面提到 Astro 是一個以「靜態內容為主軸」的框架,並且讓 JavaScript 只在必要時被運輸執行,這麼說還是有點攏統,要了解 Astro 的優勢就需要了解現有的問題,需要進一步了解什麼是所謂的「靜態網站」什麼是「動態網站」。

靜態網站 vs 動態網站

  • 靜態網站:網站是由文件所構成的,最常見像是 HTML、CSS、JS、圖片……等檔案,託管在網頁伺服器上,用戶可以索取這些文件而伺服器只需傳遞這些靜態的文件即可。
  • 動態網站:當用戶索取頁面時伺服器動態的生成頁面內容並且提供給用戶。

可以想像得到靜態與動態網站各有它們的優缺點,問題不在「哪種方法比較優越?」而是「哪種方法比較符合需求?」,靜態網頁內容制式但便宜方便部屬,動態網頁靈活但複雜昂貴許多,就像是超市冷凍披薩和手工現烤披薩一樣。

剛出爐的披薩在烤爐旁

慶幸的是現今有許多的框架可以讓我們自由的切換渲染網頁的時機與模式,渲染網頁的方法可以被統稱為「渲染模式 Rendering Pattern」,關係到用戶與開發者的體驗。由於渲染模式與網頁效能指標是額外且獨立的課題,因此附上我所撰寫的相關文章補充:

現有問題

傳統對於多頁面靜態網站會使用工具像是 Jekyll、Hexo、Hugo、11ty ……等靜態生產器透過模板語言,或是使用元框架如 Gatsby、Next、Nuxt 撰寫 React 或 Vue 來生成頁面,於是產生了全新的問題:

  • 為什麼只能用 A 框架? 能不能用 B 框架?
  • 為什麼還要額外學模板語言或框架?能不能……只要 HTML、CSS、JS 就好?
  • 為什麼單純的靜態內容的網頁還要加載客戶端 JS?

Astro 前來拯救

Astro 讓你將頁面拆分成一塊塊的元件島嶼,並鼓勵你整合引入自己喜愛的 UI 語言(或是使用 Astro 語法,類似 HTML 與 JS 的集合,十分易學)如下:

---
import Navbar from '/components/Navbar.astro';
import Carousel from '/components/Carousel.astro';
import Article from '/components/Article.astro';
---
<html>
<body>
<header>
<Navbar />
</header>
<main>
<article></article>
<Carousel />
</main>
</body>
</html>

為了達成「運送盡可能少的 JavaScript 到客戶端」Astro 預設會在伺服端將所有元件預先渲染完畢,並且在頁面需要該元件被使用時再加載關聯 JavaScript 到網頁中使其可以被使用,這樣的行為也被稱為 Hydration。Astro 中我們可以簡單的透過「範本指令 Template Directives Reference🔗」來為元件 Hydrate 的時機,像是:client:visibleclient:media……等。

選擇性 hydration

<!-- 該導覽列切換元件只在裝置尺寸 500px 以下才開始加載-->
<NavbarToggle client:media="(max-width: 500px)" />
<!--該跑馬燈元件只在出現於用戶螢幕顯示範圍時才開始加載-->
<Carousel client:visible />

以上便是 Astro 為了針對「內容為主軸的網頁」所選擇的網頁渲染方案:「Selective Hydration」也就是「 Astro Island」 架構實踐的模式,這種渲染方式對於偏靜態類型的網頁來說剛剛好,既確保了網頁速度與 SEO,同時也能有效率的加載頁面中的 JavaScript。

選擇性 hydration 流程圖

總結

今天理解到了動態網站與靜態網站的區別(冷凍披薩與現烤披薩),並且也大致了解現代網頁有各式各樣的需求,有的網頁內容偏向靜態,有的偏向動態,關係到了網頁「渲染模式」的抉擇,而 Astro 就及是一個瞄準生成靜態頁面為主的框架。

延伸閱讀