網誌

靜態網站在重新發佈時保持上線

以往在 Mythex 重新發佈靜態網站時,會先刪除線上的檔案,再上傳新的建構版本,因此在上傳期間,部分訪客會看到 404 頁面,或是缺少腳本的頁面。上傳失敗的話,網站可能會變成空白,或只有一半是新內容。現在新的建構會覆寫舊的版本,頁面最後上傳,多餘的檔案則會在幾分鐘後移除。第二項修正令重新發佈能在數秒內生效,而不是一分鐘;至於像標誌這類檔案,以往可能要等上一整天。

靜態網站如何提供服務

靜態網站就是純粹的檔案:HTML 頁面、JavaScript、CSS 和圖片。你在 Mythex 發佈時,我們會建構它,把輸出上傳到物件儲存空間中屬於你網站的資料夾,並透過邊緣網絡提供服務——邊緣伺服器位於接近訪客的位置,會從儲存空間取得檔案,並把副本保留一段時間。(如果你對此還不熟悉,我們的指南什麼是 CDN介紹了這個概念。)

有兩件事出了問題:重新發佈時更改檔案的順序,以及舊副本保留的時間。

問題一:上傳時先清空了網站

重新發佈會先刪除網站資料夾中的所有內容,再上傳新的建構版本。在上傳的整段時間裡——在我們本地測試中,一個 250 個檔案的網站需時 12 秒——如果訪客的請求未在邊緣快取中,就會得到 404,或是一個腳本回傳 404 的 HTML 頁面。

上傳失敗的情況更糟。資料夾已經是空的,而且在其中一條上傳路徑上,新的 index.html 可能會先於那個失敗的檔案落地。被標示為失敗的發佈,可能會令一個只有一半是新內容的網站繼續在線上。

修復方法:覆寫、頁面最後、事後清理

  1. 不要先刪除。 新的建構會覆寫在舊的版本之上。
  2. 資源先於頁面。 頁面會指明它需要哪些腳本和樣式,因此頁面最後上傳。在新頁面到達之前,訪客拿到的是舊頁面,而它指向的舊資源仍然存在。新頁面到達後,它所指向的新資源早已就位。
  3. 稍後移除多餘檔案。 上傳之前,我們會列出網站由哪些檔案組成。在成功上傳三分鐘後,清單中新建構沒有重寫的任何檔案都會被刪除。三分鐘比頁面在邊緣和瀏覽器中可能被快取的 60 秒更長,因此仍持有舊頁面的訪客,能找到該頁面指向的資源。
  4. 拿不準就什麼都不刪。 如果上傳前的列出步驟失敗,就不會進行任何清理。多餘的檔案無害,下一次發佈會清除它們。在不知道裡面有什麼的情況下刪除,正是網站變成空白的原因。

現在,上傳失敗會讓上一個網站保持原狀。

我們在本地端到端測試了這項改動,使用的是真正的上傳腳本、真正的上傳路由和儲存空間提供服務,並以冷邊緣快取的方式模擬訪客。舊程式碼下,重新發佈期間有 91 次中的 55 次造訪出錯,失敗的發佈則有 92 次中的 61 次出錯。新程式碼下,橫跨兩條上傳路徑、一次失敗的上傳以及之後的發佈,大約 3,500 次造訪中零次出錯,而且被清理的恰好是多餘的檔案。

問題二:重新發佈需時太久才顯示

即使上傳順利,變更出現得也很慢。邊緣會把頁面副本保留 60 秒、其他所有檔案保留一天,並告知瀏覽器也這樣做。像 logo.png、字型,或任何來自 public/ 資料夾的檔案,這些固定名稱的檔案在重新發佈後,可能會顯示舊版本長達一天。

修復方法:把檔案副本歸於建構版本之下

當邊緣向我們的 API 查詢網站的位置時,回應現在會包含一個建構標記,每次發佈生效時都會改變。邊緣會把副本歸入該標記之下。因此,一旦邊緣那 30 秒的查詢到期,發佈就會變成一組全新的快取鍵。舊副本永遠不會再被找到,所以邊緣可以保留副本一天,卻永遠不會在被取代的發佈之後仍提供它們。

瀏覽器則採用兩種不同的規則:

  • 雜湊過的建構輸出——例如 assets/index-CzLcxDO8.js 這類檔案名稱會隨內容改變的檔案——會被快取一年,並標示為 immutable。在該名稱之下,它永遠不會過時。
  • 其他一切——頁面和像標誌這類固定名稱的檔案——都標示為 no-cache,即「使用前先檢查」。如果沒有改變,現在我們已遵守瀏覽器的 If-None-Match 檢查,回應就只是一個很小、沒有內容的 304 Not Modified。

區分這兩者需要小心:從 public/assets/ 複製的檔案會保留自己的名稱,如果把 assets/logo.png 快取一年,就會讓舊標誌被釘住一年。因此,只有在建構輸出資料夾中,並且名稱中含有看起來像雜湊的片段(而不是普通字詞)的檔案,才會被視為雜湊檔案。

在本地,新的頁面和標誌在發佈上線後 6 秒內便可見。以前頁面需要 60 秒,標誌則需要一天。

兩項較小的修正

  • HEAD 請求導致的空白頁面。 HEAD 請求只要求頁面的標頭而不要內容。我們以前會快取這些空回應,因此下一位訪客打開該頁面時會看到空白。現在 HEAD 回應不再被快取。
  • 「這裡沒有任何東西」的真正頁面。 指向沒有應用程式的位址,以前會得到一段純文字「此已發佈的應用程式已離線或找不到連結」,並附帶 502 錯誤代碼。現在它會得到一個正式頁面「這裡沒有應用程式」,附帶 404 狀態,並提供讓擁有者返回 Mythex 的途徑。無法識別的自訂網域也會得到同一頁面。

我們的心得

  • 順序本身就是正確性的一部分。 以不同順序上傳同樣的檔案,就是損壞的網站與正常運作的網站之間的分別。
  • 延後刪除,而且只刪除你知道的內容。 以上傳前取得的清單進行清理是安全的;清空資料夾然後寄望上傳能順利完成則不然。
  • 依版本快取,而不是依時間快取。 到期時間是對內容何時改變的猜測。隨建構改變的鍵則是事實。

相關閱讀:你的已發佈應用程式現在在重新發佈期間仍保持上線。更多發佈相關資訊,請參閱文件。

Mythex · Pricing · 用 AI 建造任何嘢 · 網站及應用程式範本 · Mythex 比較 · AI 應用程式開發詞彙表 · 免費 AI 應用程式開發工具 · English

English አማርኛ العربية Български বাংলা Bosanski Català Čeština Dansk Deutsch Ελληνικά Español Español (España) Eesti فارسی Suomi Français Français (Canada) ગુજરાતી हिन्दी Hrvatski Magyar Հայերեն Bahasa Indonesia Íslenska Italiano 日本語 ქართული Қазақ тілі ಕನ್ನಡ 한국어 Lietuvių Latviešu Македонски മലയാളം Монгол मराठी Bahasa Melayu မြန်မာ Norsk bokmål Nederlands ਪੰਜਾਬੀ Polski Português (Brasil) Português (Portugal) Română Русский Slovenčina Slovenščina Soomaali Shqip Srpski Svenska Kiswahili தமிழ் తెలుగు ไทย Tagalog Türkçe Українська اردو Tiếng Việt 简体中文 繁體中文(台灣)