Astro 7.4 的新功能 — 建置效能診斷、分離式圖片服務到多執行緒平行預渲染

作為主打「極速、以內容為中心(Content-driven)」與「預設零 JavaScript 群島架構(Islands Architecture)」的現代 Web 框架,Astro 在近期正式推出了 Astro 7.4。

這次的 7.4 版本更新帶來了許多令開發者振奮的實用功能,特別是在建置效能可視化、混和渲染架構下的圖片最佳化、以及大型靜態網站的多核心編譯效率上取得了突破性的進展。

本文將帶你深入拆解 Astro 7.4 的關鍵新特性與背後的工程設計考量。


一、astro build --timings:看透建置瓶頸的效能剖析器

在專案規模逐漸擴大、頁面數達到數百甚至數千頁時,「為什麼今天建置變慢了?」往往是讓團隊最頭痛的難題。是某個肥大的 Vite 外掛?複雜的 Markdown 語法高亮?昂貴的圖片壓縮?還是某個元件寫出了瀑布流(Waterfall)網路請求?

過去,開發者只能靠猜測或手動埋點 console.time();而在 Astro 7.4 中,只需加上一個旗標:

astro build --timings

建置完成後,終端機會以階層樹狀與微型直方圖(Sparklines),清晰列出每一毫秒到底花在哪裡:

 build timings
total 2.61s · 9 pages · output "static"

Build phases
  resolve config                        59ms   2.3% ▄·····················
  setup                                225ms   8.6% ▃█▅···················
    route discovery                      2ms   0.1% ▁·····················
    vite config                         14ms   0.5% ▁·····················
    content sync                       206ms   7.9% ▂█▅···················
  prerender bundle                     151ms   5.8% ··▃█··················
  client bundle                         21ms   0.8% ····▂·················
  manifest injection                     2ms   0.1% ····▁·················
  generate pages                       2.10s  80.6% ····▇█████████████████
    prerenderer setup                    6ms   0.2% ····▁·················
    static paths                         3ms   0.1% ····▁·················

Page rendering (2.09s across 9 pages)
  component render                     2.08s  79.6% ····▆█████████████████
  page pipeline                         13ms   0.5%

Slowest pages (median 297ms · p95 571ms)
  /about                               571ms
  /blog/first-post                     307ms         /blog/[...slug]
  /blog/using-mdx                      303ms         /blog/[...slug]
  /blog/second-post                    299ms         /blog/[...slug]
  /rss.xml                              10ms
  /blog                                  6ms

洞察與診斷實例

官方日誌給出了一個經典範例:在部落格版型中加入 <CommentSection>,而每個 <Comment> 內部又依序 fetch 留言者的個人資料。這種巢狀串行請求在編輯器裡看完全沒錯,但一經 --timings 分析,立即發現「頁面生成占了 81% 時間」,且慢的頁面全集中在呼叫該元件的動態文章頁。

將其改寫為 Promise.all() 平行獲取後,頁面生成時間立刻從 2.1 秒腰斬至 1.13 秒!--timings 讓你直搗效能核心,不再盲人摸象。


二、分離式圖片服務:建置期(Build)與執行期(Runtime)解耦

在現代全端應用中,預渲染頁面(Prerendered Pages) 與 隨選渲染頁面(On-demand / SSR / Edge) 對於圖片處理的需求是完全截然不同的:

flowchart TD
    subgraph DualImageService ["Astro 7.4 分離式圖片服務架構"]
        direction TB
        Config["astro.config.mjs: image.service"]
        
        BuildService["【建置期服務 Build Service】<br/>• 本機完整 Node.js 環境<br/>• 使用 Sharp 高效能壓縮<br/>• 本地免費處理靜態資產"]
        RuntimeService["【執行期服務 Runtime Service】<br/>• Serverless / Cloudflare Edge<br/>• 缺乏 Native C++ 模組支援<br/>• 轉交 Image CDN (Cloudinary / Imgix / CF Images)"]
        
        Config --> BuildService
        Config --> RuntimeService
    end

    BuildPages["預渲染靜態頁面 (SSG)"] --> BuildService
    SSRPages["伺服端動態請求 (SSR / Edge)"] --> RuntimeService

在以往版本中,你只能全站統一設定單一 image.service,導致靜態頁面想用本機免費的 Sharp 壓縮、動態頁面想用 Cloudinary / Cloudflare Images 時互相打架。

在 Astro 7.4 中,image.service 支援雙軌配置:

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

export default defineConfig({
  image: {
    service: {
      build: { entrypoint: 'astro/assets/services/sharp' },
      runtime: { entrypoint: 'my-image-cdn-service' },
    },
  },
});
  • build 服務:在本地開發與 astro build 時運作,使用強大的 Sharp 產出最佳化圖片。
  • runtime 服務:在正式部署上線後,負責動態頁面或 /image 端點的即時轉移與 CDN 委託。

這項底層重構也讓 @astrojs/cloudflare 等邊緣環境適配器(Adapters)能無縫整合標準圖片管線。


三、微架構改進:notFound() 處理解耦與字型配置預警

1. 自訂入口點支援 notFound() Handler

當開發者使用 astro/fetch 或 astro/hono 自己拼裝伺服器或 Cloudflare Worker 進入點時,過去若請求未匹配任何路由,只會回傳一個毫無修飾的空白 404,而無法觸發專案內寫好的 404.astro 頁面。

Astro 7.4 新增了 notFound() 中介軟體:

import { Hono } from 'hono';
import { notFound, pages } from 'astro/hono';
import { cf } from '@astrojs/cloudflare/hono';

const app = new Hono();
app.use(cf());
app.use(notFound()); // 找不到路由時自動渲染 404.astro
app.use(pages());

export default app;

2. 字型設定防呆預警(Font Configuration Warnings)

字型家族往往只提供特定字重(如 400、700)或特定語系子集(Subsets)。過去若在設定檔填寫了該字型根本不支援的字重(例如 font-weight: 900),瀏覽器只會默默回退(Fallback)為常規字型,開發者極難察覺。

Astro 7.4 引入了 getFontProperties() 回呼機制,Astro 內建的所有字型提供者會在建置時主動對比配置,一旦發現該字型提供者無法供應的規格,立即在終端機跳出警告。此項特性將在未來的 Astro 8 中成為強制標準。


四、實驗性旗標:多核心平行預渲染與自訂 3xx 跳轉頁

本次 7.4 版本還包含了兩項極具潛力的實驗性功能(Experimental Features):

1. 平行預渲染(Parallel Prerendering)

以往 Astro 雖然具備並發(Concurrency)渲染靜態頁面的能力,但所有運算全部綁定在單一 Node.js 執行緒上。即便你的開發機或 CI 伺服器擁有 16 核心、32 核心的強大 CPU,靜態建置依然只能榨乾一顆核心。

透過開啟 experimental.parallelPrerender:

// astro.config.mjs
export default defineConfig({
  experimental: {
    parallelPrerender: true, // 預設使用 CPU 核心數 - 1
    // 或是自訂 Worker 數量以控制記憶體耗用:
    // parallelPrerender: { workers: 4 },
  },
});

Astro 會透過 Node.js Worker Threads 將成千上萬個預渲染頁面均勻分配到多個 CPU 核心平行編譯。這與 Astro 的 Content Layer 增量建置(Incremental Builds)堪稱絕配,大型網站的建置速度將迎來數倍的幾何級躍升。

2. 自訂靜態重新導向頁面(Custom Redirect Page)

在純靜態主機(如 S3、GitHub Pages、Cloudflare Pages)上,伺服器無法發送 HTTP 301/302 Header,Astro 會為每個 redirect 產生一個包含 <meta http-equiv="refresh"> 的輕量 HTML 存根頁(Stub Page)。

過去這個頁面完全是 Astro 寫死的;現在只要啟用:

export default defineConfig({
  experimental: {
    redirectPage: true,
  },
});

接著在專案建立 src/pages/3xx.astro,你就能完整自訂跳轉時的品牌樣式、多國語言提示與跳轉延遲時間(Delay):

---
import type { RedirectPageProps as Props } from 'astro';
const { from, to, status, delay } = Astro.props;
---
<html lang="zh-TW">
  <head>
    <meta http-equiv="refresh" content={`${delay};url=${to}`} />
    <meta name="robots" content="noindex" />
    <title>正在重新導向...</title>
  </head>
  <body>
    <p>頁面已搬遷,正在為您跳轉至 <a href={to}>{to}</a></p>
  </body>
</html>

五、升級指南與 Node.js 最低版本要求

隨著 Astro 7.4 的發布,官方與整合套件的最低支援環境正式提升至 Node.js 22.22.0(緊跟 Node.js LTS 與 StackBlitz 支援策略)。

升級現有專案推薦使用官方自動化工具:

# 推薦自動化升級:
npx @astrojs/upgrade

# 手動升級:
pnpm upgrade astro --latest

結語

從 Astro 1.0 的破空出世,到今日 Astro 7.4 的穩健成熟,Astro 證明了「以內容為中心、零客戶端 JS」並不等於對現代開發體驗的妥協。

astro build --timings 給了我們前所未有的工程可視度,分離式圖片服務解決了邊緣運算的現實痛點,而多執行緒平行預渲染更是為大規模企業級站點鋪平了極速建置的坦途。

如果你也在尋找一個能夠兼顧極致效能、簡約優雅與工程深度的 Web 框架,Astro 7 絕對是當今不可錯過的頂級之選。