跳至主要內容

開發紀錄

文章變多之後,為什麼要做原生靜態分頁

從本站每頁六篇的一般文章列表出發,整理發布過濾、排序、靜態路由與原生分頁連結如何共用同一份資料,以及頁碼不能保證什麼。

林予晴
發布 更新
  • 內容工程
  • Astro
  • 分頁
  • 原生 HTML

文章列表只顯示六張卡片,不一定代表網站真的有分頁。它可能先把全部文章交給瀏覽器,再用腳本隱藏其餘項目;也可能替下一頁準備好獨立網址與 HTML。

本站選擇後者。第 2 頁是一份可直接打開的靜態頁面,頁碼連結指向那份頁面。這符合目前以本地 Markdown 建置公開筆記的方式,不需要為了換頁再建立一套瀏覽器狀態。

先決定哪些文章能進列表,再計算頁數

現在的一般列表每頁最多六篇。這個數量來自 NOTES_PER_PAGE,是目前的呈現設定,不是所有網站都應該採用的標準。

切頁以前,資料已經經過幾個步驟:

文章來源
  → 選出該語言已符合發布條件的文章
  → 依發布時間排序,同時間以 stableId 排定順序
  → 排除精選文章
  → 計算一般列表頁數,取出該頁項目

順序不能隨便交換。如果先切成六篇再排除草稿,一頁可能只剩幾張卡片;如果先把三種語言混在一起切頁,每個語言的列表也會失去自己的頁數。

精選文章會在每個有效分頁的獨立區塊出現,不占一般列表的六個位置。這裡沿用的是既有精選規則;分頁要做的是一致地使用那份集合,而不是再發明另一套推薦排序。

頁碼是一個真實路由

繁中的第 1 頁使用 /notes,後續頁面使用 /notes/page/2、/notes/page/3 等路由。英文與日文各自使用語言前綴,也各自計算一般文章的總頁數。

Astro 靜態模式的動態路由由 getStaticPaths() 列出需要產生的網址;框架也提供 paginate() 輔助函式。[2] 本站沒有直接使用那個輔助函式,而是以自訂的 paginateNotes() 統一列表與 sitemap 的頁數計算,再回傳後續頁面的路由參數。

這個差異值得寫清楚:paginateNotes() 是本站的程式,不是另一個 Astro API。原生靜態分頁指的是使用框架的靜態路由和 HTML 連結,不表示每個細節都必須採用內建 helper。

產生路由時只列出實際存在的後續頁面。paginateNotes() 會把超出範圍的內部頁碼縮到有效範圍,但那是資料函式的保護,不代表網站已經替任意輸入的頁碼建立網址。

換頁不需要把點擊攔下來

分頁元件輸出的是 <a href="…">。上一頁與下一頁只有在目的地存在時才出現,目前頁碼帶有 aria-current="page"。

Astro 的一般路由導覽使用標準 HTML 連結。[2] 對這個列表而言,頁碼已有確定的目的地,沒有必要把它改成只更新記憶體狀態的按鈕。讀者可以複製第二頁網址,也能直接請求該頁;卡片內容已經在回傳的 HTML 裡,不依賴換頁腳本才出現。

這只說明列表和換頁的責任。網站其他位置仍可能有動畫、抽屜或局部腳本,不能因為分頁不需要 JavaScript,就把整個網站描述成完全沒有 JavaScript。

路由、列表和 sitemap 要算出相同的頁數

如果頁面切分使用一般文章,sitemap 卻把精選文章也算進去,就可能列出根本沒有產生的最後一頁。反過來,只產生路由卻漏掉 sitemap,也會讓兩份公開網址清單不一致。

目前列表、後續路由和 sitemap 都以該語言的正式文章為基礎;精選文章在每個有效列表頁呈現,但不占一般列表項目或頁數。三者使用同一個一般文章分頁依據,分別輸出卡片、HTML 頁面和網址清單。

多語列表也不要求每種語言都有相同頁數。英文只有兩頁時,不能為了配合繁中的第五頁,就製造一個空的英文第五頁。

同樣的頁碼也不保證同樣的內容。繁中第 2 頁與英文第 2 頁,都是各自語言列表的位置,不是逐篇翻譯的配對結果。要切換同一篇文章的語言,仍應使用文章頁的 stableId 關係。

頁面能被分享,內容位置卻不會永久固定

新文章發布後,排序會改變,原本在第 1 頁末端的文章可能移到第 2 頁。取消或加入精選,也可能改變一般列表的頁數。

所以頁碼網址適合表示「這份列表的某一頁」,不適合代替文章自己的永久入口。要分享特定文章,仍然使用文章路由;不要把第 3 頁當成那篇文章永遠所在的位置。

靜態分頁還有更新成本:來源、發布資格或排序改變後,需要重新建置並更新網站,讀者才會拿到新的列表。它不是即時搜尋,也不是游標式分頁,更不適合直接拿來處理持續變動的個人交易資料。

目前要整理的是公開文章,不是頻繁更新的操作資料,因此我會保留這種分頁。每頁六篇是否舒服,仍要看標題長度和手機閱讀;有獨立 HTML,也不能直接推論載入速度、搜尋排名或閱讀完成率已經改善。

紀錄範圍

本文描述現有一般列表、分頁路由、分頁元件與 sitemap 的分工。沒有新增搜尋、無限捲動或即時查詢,也沒有提供分頁前後的效能比較。

延伸閱讀:精選文章與時間排序如何共存。

Sources

[2] https://docs.astro.build/en/guides/routing — Astro — Routing