Vesta
4分鐘閱讀
2026-09-24
寫部落格,最先催稿的居然是硬碟。
多了幾篇 Markdown,重新整理要等,點進文章要等,連切個分類也要等。機械硬碟在桌下忙得很有存在感;頁面倒是不慌不忙。我一開始懷疑是文章解析太重,後來連不存在的路由都慢,才知道找錯人了。
其實最早露出馬腳的是主題按鈕:按一下,瀏覽器先送 POST 存 cookie,再送 GET 重新讀取主題。畫面原本跟著第二筆請求一起等。後來讓畫面先讀 fetcher.formData 立即切色,cookie 照常在背景保存,按鈕總算不再慢半拍。但文章與分類頁仍然慢,得繼續往下查。
這個專案用 React Router Framework Mode、Vite,部署到 Cloudflare Workers。當時的 pnpm dev 也載入 Cloudflare Vite 外掛,伺服器端程式會在本機的 Worker 模擬環境執行。
我另外開一個開發伺服器,用 curl 量首頁、分類頁和文章頁。以下記的是暖機後一筆請求的伺服器回應時間;瀏覽器完成排版的時間另算。每條路由只取了一次,這些數字用來定位問題:
| 路由 | 原本的本機 Worker 模式 | 調整後的日常開發模式 |
|---|---|---|
| 首頁 | 約 750 ms | 約 11 ms |
| 分類頁 | 約 565 ms | 約 8 ms |
| 文章頁 | 約 613 ms | 約 8 ms |
第一次開首頁時,舊模式甚至花了約 6.7 秒;那一輪包含依賴重新處理,和暖機後的數字要分開看。另一個線索更有用:靜態 favicon 約 2 ms 就回來了,不存在的動態路由卻要約 1 秒。連不存在的路由都慢,問題落在本機動態路由共用的開發流程。
於是把兩種用途分開:pnpm dev 用一般的 React Router/Vite 本機開發伺服器;要檢查 Cloudflare Workers 行為,再跑 pnpm dev:worker。設定裡保留了建置和預覽時的 Cloudflare 外掛,因此正式部署流程沒有換掉。
// 日常 HMR 用 Node;建置、預覽及 Worker 檢查使用 workerd。 const useCloudflare = command === "build" || isPreview || process.env.EASTLOG_WORKER_DEV === "1";
之前部署站點的主題切換請求約兩百毫秒一筆;本機模擬的數字無法代表線上延遲。寫頁面時求的是迭代順手;檢查 Worker 專屬功能時,還是得回到 Worker 模式。
伺服器回應快了,文章頁的瀏覽器腳本仍值得看一眼。原本直接匯入 react-syntax-highlighter 的完整 Prism,會帶進大量語言定義;目前文章中的程式碼區塊只有 ts、bash 和 css。
改用 PrismLight,只註冊這三種語言後,文章頁的 JavaScript 檔案從 782,793 B 降到 206,844 B;gzip 後從約 272 KB 降到 62 KB。文章腳本因此變輕;分類頁原先的伺服器等待則由開發模式處理。以後文章若要高亮其他語言,記得補上註冊。
改完建置仍會看到 gray-matter 的 eval 警告。它來自套件提供的 JavaScript frontmatter 解析器;目前文章用的是 YAML frontmatter,沒有走那段解析程式。警告指出套件裡有這段程式碼,並不表示這次建置執行了它。若日後開放外部投稿,文章來源和 frontmatter 格式就需要另外把關。
現在平常用 pnpm dev 寫文章、調版面;碰到 Cloudflare 專屬行為,才切到 pnpm dev:worker。硬碟終於不用每次點分類都先發表意見了。