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 就是一个瞄准生成静态页面为主的框架。

延伸阅读