Astro 使用心得——它能維持我作品集頁面的效能分數嗎?

Eason Lin
7 min readApr 4, 2024

--

Photo by Marc-Olivier Jodoin on Unsplash

如果只是想知道我的驗證結果,先說結論:可以。後續只是我的驗證過程和成果,如果沒興趣就可以關閉此文並到 Astro 官網看看了🤣🤣🤣

大家好,這篇文我想來試用一下這陣子滿多話題的 Astro。說來有趣,我最早知道 Astro 時並不是在某個社群或聽同事提及,而是某一次我下班後去上跳舞課時,就剛好瞄到有位上同堂課的學員正在用 Mac 寫前端,並發現他的專案是基於 Astro,用手機稍微 Google 一下才知道這個框架。

我們學習一個新的框架或庫通常是為了去嘗試解決某些問題。閱讀了 Astro 的介紹頁後,我就想到我自己作品集頁面的一個痛點。

想要解決的問題

我的作品集是採用 Express.js 作為伺服器掛載靜態頁放在機器上的,掛載的就是一個很單純的靜態 html 檔案。會這樣做是因為當初在開發時就希望它除了以單純為主外,所有效能指標都必須要是滿分,而當初也很順利地做到:

Mobile
Desktop

不過因為我當初在製作時就是很單純地用 html 去編寫,因此作品的部分就不免要剪剪貼貼,如果樣式需要調整就會很麻煩。但畢竟我的頁面最多也就只需要去 for loop 我的作品區塊,不需要寫什麼邏輯。曾想過使用簡單的模板系統如 Mustache.js 去解決這個問題,不過礙於這個庫偏冷門加上自己懶惰就作罷,React, Vue 這類的庫或框架我則沒有什麼信心它能維持一樣的效能分數。不過,再看到 Astro 文件中的敘述:

需要兼顧網站載入速度與 SEO 嗎?Astro 非常適合你。

就引起我想要嘗試的興趣了。我的目標非常簡單:

  1. 改用 Astro 來寫我的作品集頁面
  2. 效能分數不能有任何一項指標低於滿分

進行開發

雖然說是進行開發,不過 Astro 的學習門檻是真的很低,從建構 Astro 專案、把作品集頁面搬移到 Astro 專案中、邊閱讀文件、邊將作品寫成組件前後耗費也就一小時左右。而語法部分,例如代表作品的組件語法就長這樣:

---
interface Props {
title: string;
description: string;
tags: string[];
image: string;
link: string;
ariaLabel: string;
}

const { title, description, tags, image, link, ariaLabel } = Astro.props;
---

<div class="grid-item">
<a href={link} aria-label={ariaLabel} target="_blank" rel="noopener">
<div class="hoverbox ef-move-right light">
<img src={image} alt="" loading="lazy" />
<div class="hb_back">
<h2 class="work__title">{title}</h2>
<p class="work__text">{description}</p>
</div>
<ul class="work__tags">
{tags.map((tag) => <li>{tag}</li>)}
</ul>
</div>
</a>
</div>

不論是習慣使用 Vue 還是 React 的開發者,應該都不難看出這段語法代表的意思吧?如果需要在組件內寫樣式,也就只要在最後一個 </div> 下方增加 <style> 即可編寫樣式。

再來最重要的來了:基於 Astro 框架 Build 出來的靜態頁面,可以和原本的靜態頁面一樣維持所有指標均為 100 分嗎?我用了非常土法煉鋼的方式:

  1. npm run build 產出靜態資料
  2. 將靜態資料包含圖片、CSS、JavaScript 及 HTML 覆蓋到原本的專案
  3. 在本地啟動原本專案的伺服器確認無問題
  4. 將專案推送至機器上並在站上重跑一次 Lighthouse 效能檢測

跑出來的結果如下:

Mobile
Desktop

前後效能分數並無太大差異,甚至在我順手修了一個 LCP 的小問題後還提升了一點點。換句話說,Astro 的確可以替代我目前直接寫靜態頁面導致維護較為困難的問題

最後一個要解決的問題就是:將專案直接遷移到 Astro 下,由原本自建的超陽春 Express.js 專案改由 Astro 來一站式處理。

開始遷移

翻了一下 Astro SSR 一些解決方案的說明後,發現它可以使用 hybrid 的方式,也就是像我原本的作法直接產出靜態頁面,而非收到請求時才進行渲染,這樣應該可以確保效能分數不會受到任何影響:

// astro.config.mjs
import { defineConfig } from "astro/config";

import node from "@astrojs/node";

// https://astro.build/config
export default defineConfig({
output: "hybrid",
adapter: node({
mode: "standalone",
}),
});

機器部分,我用的是 fly.io,它本身部署需要的設定就非常少,費用也不會很貴,針對 Astro 也有說明使用方式,這邊就不贅述。

最後分享完成調整後站上出現 Astro 的喜悅感:

至於為什麼當初會用 Express.js 而非直接放在如 Github Page 之類的地方,是因為原本是要做 MPA,也是有需要在部分頁面處理請求、也的確有實作出來只是沒有實際運用,而目前依然是打算保留這個彈性,所以才會沿用伺服器的方式。

結論

從開始接觸 Astro 到撰寫完這篇文,前後也就花了大約四小時。Astro 真的是一個很好入門,在效能上確實也跟自己寫靜態頁面相去不遠,目前已經想好未來能應用的場景,也期待能很快再使用它去處理其他不同的問題。這篇文就到這,若內文有任何錯誤,也歡迎指出,謝謝。

References:

--

--

Eason Lin
Eason Lin

Written by Eason Lin

Frontend Web Developer | Books

No responses yet