你裝了 WP Rocket、把圖片全壓成 WebP,PageSpeed Insights 分數也衝到九十幾分,但網站點下去那一瞬間還是要等個半秒以上才開始有畫面。問題很可能不在前端,而在伺服器吐出第一個位元組之前那段你看不見的等待,也就是 WordPress TTFB 過高。
TTFB 過高的麻煩在於它是一切的起點。瀏覽器連第一個位元組都還沒拿到,後面再厲害的圖片延遲載入、JavaScript 延後執行都還沒輪到上場。這篇文章不打算再給你一份「降 TTFB 的六個方法」清單,而是帶你用一套逐層拆解的方法,從主機與網路、PHP、資料庫一路往內排查,找出到底是哪一層在拖,再對症下藥。
TTFB 是什麼,WordPress 的 TTFB 多少才算過高
TTFB(Time to First Byte,第一位元組時間)指的是從瀏覽器送出請求,到它收到伺服器回傳的第一個位元組之間的這段時間。它涵蓋三件事:DNS 查詢與連線建立、伺服器處理請求(跑 PHP、查資料庫)、伺服器送出回應的第一個位元組。對 WordPress 來說,中間那段「處理請求」幾乎決定了一切,因為每一個沒被快取的頁面,都要即時跑 PHP、查 MySQL 才生得出 HTML。
數值的判讀標準,業界與多數主機商的共識相當一致。TTFB 在 200 毫秒以下算優異,訪客幾乎感覺不到延遲;落在 200 到 500 毫秒之間屬於正常、可接受;持續超過 600 毫秒就該認真排查;Google 的 Core Web Vitals 則把 800 毫秒當成一條較寬鬆的及格線。換句話說,如果你的 WordPress 未快取頁面 TTFB 長期卡在 600 毫秒以上,那不是裝個外掛就能蓋過去的,是體質問題。
要特別釐清一個常見誤會:TTFB 不等於整體載入速度。它只衡量「伺服器多快開始回應」,至於畫面多快畫完、能不能互動,是後續渲染階段的事。這也是為什麼 PSI 分數可能很漂亮、體感卻很慢——分數被前端優化拉高了,但伺服器回應這段慢,使用者一點下去就先乾等。TTFB 本身因為偏伺服器端、較不貼近真實感受,所以沒被單獨列為 Core Web Vitals 指標,但它直接牽動最大內容繪製(LCP),照樣是排名與體驗的地基。
怎麼正確量出 WordPress 的 TTFB
在動手優化前,先把目前的 TTFB 量準,否則改了也不知道有沒有效。測量方法分成瀏覽器與線上工具兩類,建議兩種都用。
瀏覽器這邊用 Chrome 開發者工具最直接。在要測的頁面按 F12,切到「Network」分頁,強制重新整理(Mac 是 Cmd + R、Windows 是 Ctrl + R),點開最上面那筆文件請求,在右側「Timing」分頁找「Waiting for server response」那一行,數字就是 TTFB。wp-admin 後台頁面只能用這個方法測,因為線上速度工具掃不到登入後的頁面。
線上工具則推薦 PageSpeed Insights、WebPageTest、GTmetrix、Pingdom。它們會在瀑布圖裡單獨列出 TTFB。用線上工具有兩個前提要記住:第一、測試節點的地理位置會影響結果,從台北測台灣主機,和從美國測台灣主機,數字天差地遠,要挑離你主要讀者最近的節點;第二、單次測試不準,快取與 CDN 是否命中會讓結果跳動很大,同一頁多測幾次取平均才有意義。
如果你習慣指令列,用 curl 量原始 TTFB 最乾淨,不受瀏覽器外掛與快取干擾:
curl -o /dev/null -s -w "TTFB: %{time_starttransfer}sn" https://yoursite.com/
量的時候務必分開測「已快取」與「未快取」兩種頁面。首頁、文章頁通常會被頁面快取接住,TTFB 會很低;但購物車、結帳、會員中心、登入後的後台這類頁面天生無法被頁面快取,反映的才是你伺服器真實的動態處理能力。只看快取過的首頁,會嚴重低估問題。
用逐層替換法找出拖慢回應的那一層
與其亂槍打鳥把所有優化招式都試一遍,不如用一套像二分搜尋的逐層替換法,幾步就能把問題鎖定在某一層。先在測試站或備份環境操作,避免動到正式站。
第一步、先測多個頁面,看是全站都慢還是只有特定頁慢。只有幾頁慢,多半是那幾頁共用的某個元素(某張巨圖、某段外掛短碼)在拖;全站都慢,問題在更底層的主機、PHP 或資料庫。
第二步、上傳一個純靜態的 test.html(裡面只放幾個字)測它的 TTFB。如果連靜態檔都慢,代表伺服器本身負載或設定有問題,這時要找主機商;如果靜態檔很快、WordPress 頁面才慢,問題就在 WordPress 動態生成這一段,繼續往下查。
第三步、切換成預設佈景主題(例如 Twenty Twenty-Four)。TTFB 明顯下降,就是你原本的主題有問題,去找更新或聯絡主題作者;沒改善,往下一步。
第四步、停用全部外掛再測。TTFB 降下來,就一個一個重新啟用,抓出那隻肇事外掛;停用全部外掛後 TTFB 還是高,那矛頭就指向資料庫——通常是 autoload 資料或慢查詢。
這套流程的價值在於,它把「主機 / 主題 / 外掛 / 資料庫」四個可能性逐一隔離,你不會再花三天優化圖片,最後才發現元兇是一隻每次載入都打外部 API 的外掛。鎖定了是哪一層,後面四節就是各層的具體解法。
主機與網路這層怎麼降 TTFB
如果逐層測下來連靜態檔都慢,或是換了主題、關了外掛 TTFB 依舊高,那答案多半在主機與網路這一層,而這也是最常見、影響最直接的一層。
最典型的兇手是共享主機。為了壓低成本,很多站長選一個月幾百塊的共享方案,等於和幾百個陌生網站擠在同一台機器、共用同一顆 CPU 與記憶體。只要其中一個鄰站流量暴衝或程式失控吃滿資源,主機商就會啟動資源節流,你的網站跟著被降速,這正是 TTFB 忽快忽慢的主因。把站搬到雲端 VPS 或代管型 WordPress 主機,拿到專屬的 CPU 與 RAM,通常是改善 TTFB 最立竿見影的一步。
主機的地理位置同樣關鍵。如果你的主要讀者在台灣,主機卻放在美國機房,光是訊號來回跨太平洋的物理延遲就省不掉。解法有兩個方向:一是直接選台灣或鄰近亞洲節點的機房;二是套上 CDN,把圖片、CSS、JavaScript 這些靜態資源快取到離訪客最近的邊緣節點。進一步可以開啟 Cloudflare 的 APO(Automatic Platform Optimization),它能連 HTML 整頁都快取到邊緣,讓主機即使在國外,台灣讀者也接近本地速度。
還有兩個容易被忽略的小地方。一是 DNS,多數人沿用主機商附的 DNS,但解析速度未必快,換成有全球節點的優質 DNS 服務能省下 DNS 查詢的時間。二是多重轉址,從 http 跳 https、再跳 www 這種一層接一層的 301 轉址,每一跳都加到 TTFB 上,能合併成單次轉址就合併。
PHP 這層怎麼降 TTFB
PHP 是 WordPress 的引擎,每個未快取頁面都要靠它即時組出 HTML,所以 PHP 跑得多快,直接寫進 TTFB 裡。這一層有三件事該做。
第一件、把 PHP 升到最新的穩定版本。新版 PHP 不只是補安全漏洞,效能本身就有明顯進步——同一台機器,較新的 PHP 版本每秒能處理的請求數更多,意味著相同流量下伺服器更從容、回應更快。升級前記得在測試站確認佈景主題與外掛相容,再切到正式站。
第二件、開啟 OPcache。這是常被和物件快取搞混的一層。OPcache 屬於「opcode 快取」,它把 PHP 編譯後的中間碼存在記憶體裡,省下每次請求都要重新把 PHP 原始碼編譯一遍的功夫。它的好處是普惠式的,每一個請求都受惠,是 PHP 效能的基礎打底,和後面會談的物件快取(快取資料庫查詢結果)分工不同,兩者該一起開。多數代管主機後台都能一鍵啟用 OPcache。
第三件、留意 PHP 程式裡會卡住流程的寫法。最常見的地雷是某段程式在生成 HTML 時,先去打一個外部 API(例如第三方的匯率、社群牆、客服機器人),然後傻等對方回應才繼續。一旦對方伺服器慢或掛掉,你的頁面就卡在原地空轉,TTFB 直接爆。這類同步外部請求要嘛改成非同步、要嘛加上逾時與快取,別讓你的 TTFB 被別人家的伺服器綁架。
資料庫這層怎麼降 TTFB
當你關掉所有外掛、TTFB 還是高,元兇幾乎都在資料庫,而其中最隱形、殺傷力最大的就是 autoload 資料。
WordPress 每次載入頁面,不管那一頁用不用得到,都會先跑一句查詢,把 wp_options 資料表裡所有標記為 autoload = yes 的選項全部讀進記憶體:
SELECT option_name, option_value FROM wp_options WHERE autoload = 'yes';
問題出在,很多外掛會把大量設定、甚至日誌塞進這張表並標記為自動載入,而且被刪掉之後常常留下這些「殘骸」不清。一個健康站的 autoload 資料大約落在 500KB 到 1MB;WP Engine 建議控制在 80 萬位元組(約 0.8MB)以內;一旦超過 2MB 就屬於嚴重、會明顯拖慢每一次頁面載入。更要警惕的是,當你同時開了物件快取(它通常只有 1MB 的緩衝),過大的 autoload 資料有機會直接觸發 502 錯誤。
診斷很簡單,在 phpMyAdmin 或用 WP-CLI 跑兩句查詢就好。先算總量(單位是位元組):
SELECT SUM(LENGTH(option_value)) AS autoload_size FROM wp_options WHERE autoload = 'yes';
再揪出最肥的前幾筆,看是誰在佔空間:
SELECT option_name, LENGTH(option_value) AS size FROM wp_options WHERE autoload = 'yes' ORDER BY size DESC LIMIT 20;
跑出來常見的肇事者有三種:早就停用的外掛留下的設定、清理程序失靈而堆積的過期暫存資料(transients),以及某些頁面建構器存進來的全域樣式與備份。動手清之前務必先完整備份資料庫,一句下錯的 SQL 就可能弄壞站台設定;確認某筆 option 屬於已刪除的外掛,再刪除或把它的 autoload 改成 no。
autoload 之外,資料庫還有兩件事要顧。一是慢查詢,太多、跑太久、或根本跑不完的查詢都會直接拉高 TTFB,缺索引導致整張表掃描是常見原因。要找出是哪些查詢在拖,裝一個 Query Monitor 外掛,它會列出每次頁面載入跑了哪些查詢、各自花多久、由哪個外掛或主題觸發,一目了然。二是日常清理,文章修訂版本、垃圾留言、過期暫存會隨時間越積越多,定期用 WP-Optimize 這類工具清理並重整資料表,能讓查詢更俐落。
快取怎麼補上未快取請求的那一段
前面幾層是讓伺服器「生成頁面」這件事本身變快,快取則是讓伺服器盡量「不必重新生成」。這兩件事要分開理解,才不會以為裝了快取外掛就萬事大吉。
頁面快取(page cache)是第一道。沒有它,WordPress 每來一個訪客都得重跑一次 PHP 和 MySQL;開了它,伺服器把生成好的 HTML 存成靜態檔,後面的訪客直接拿現成的,TTFB 自然極低。WP Super Cache、WP Rocket、LiteSpeed Cache 都能做,部分代管主機則是內建伺服器級快取,效果通常比 PHP 外掛更好。
但頁面快取有個天生罩門:它只對「人人看到都一樣」的頁面有效。一旦頁面因人而異就無法整頁快取——這正是 WooCommerce 的痛點。購物車、結帳、會員帳戶這些頁面每個人內容都不同,登入後的後台也一樣,這些頁面繞過頁面快取,反映的就是伺服器赤裸裸的動態處理能力。這也是為什麼很多 WooCommerce 站首頁飛快、結帳頁卻慢吞吞。
補上這段缺口的,是物件快取(object cache),通常用 Redis 或 Memcached 實作。它快取的不是整頁 HTML,而是資料庫查詢的結果存進記憶體,因為記憶體的讀取速度遠快於硬碟。當一個頁面非得即時生成不可(例如結帳頁、登入使用者),那些重複的查詢就能從記憶體秒回,不必每次都翻硬碟。物件快取對未快取請求與登入使用者的幫助最大,業界普遍觀察到,導入 Redis 物件快取後,資料庫負載與動態頁面的 TTFB 都能明顯下降。
實務上的順序是:頁面快取負責處理大量匿名訪客的靜態頁,物件快取負責壓低那些非動態生成不可的頁面,兩者搭配,再加上前面開好的 OPcache,整個快取堆疊才算完整。設定上多數好主機後台有一鍵開啟 Redis 的選項,開啟後再搭配支援物件快取的外掛對接即可。
wp-cron 與 Heartbeat 這兩個被忽略的 WordPress 內建負擔
排到最後這層,是兩個 WordPress 內建、卻很少被算進 TTFB 帳上的負擔:wp-cron 與 Heartbeat API。它們不像主機或資料庫那麼顯眼,但在流量不低的站上,足以讓 TTFB 偶發性地抽高。
先說 wp-cron。WordPress 的排程任務(發佈定時文章、檢查更新、跑外掛的背景工作)預設是「假 cron」——它不是真的系統排程,而是搭在訪客的請求上觸發。意思是,當排程到期時,下一個倒楣連進來的訪客,他的那次請求就得順便扛起跑排程的工作,TTFB 被硬生生加上一段。解法是關掉內建的 wp-cron,改用伺服器真正的 cron job 固定間隔去呼叫,例如每 15 分鐘跑一次,讓排程不再壓在訪客頭上。
再說 Heartbeat API。它負責瀏覽器與伺服器之間的即時溝通,像文章自動儲存、後台多人編輯的鎖定提示都靠它。問題是它預設每 15 秒就對伺服器發一次請求,當你或編輯群長時間開著後台,這些頻繁的背景請求會持續吃伺服器資源,連帶影響整體回應。用 Heartbeat Control 這類工具把頻率調低,或在不需要的頁面停用,就能把這份隱形負擔降下來。
這兩項單獨看影響不大,但它們的特性是「偶發、難重現」——你測 TTFB 時可能一切正常,真實流量下卻時不時抽高。把它們一起處理掉,TTFB 的表現會更穩定。
排查 WordPress TTFB,該照什麼順序動手
降低 WordPress TTFB 沒有一招通吃的銀彈,但有清楚的先後順序。先把 TTFB 量準,分開測已快取與未快取的頁面;接著用逐層替換法,靠靜態檔、換主題、關外掛幾步,把問題鎖定在主機、PHP 或資料庫其中一層;確定哪一層,再進去動刀——主機與位置這層花的錢最值得,PHP 升版加 OPcache 是低成本高回報,資料庫先顧 autoload 再清慢查詢,最後用頁面快取加物件快取把未快取的請求補起來,順手關掉 wp-cron 與 Heartbeat 的隱形負擔。
照這個順序走,你不會再對著一份雜亂的優化清單瞎試。現在就打開開發者工具或 curl,量出你站台的未快取 TTFB,從數字最差的那一層開始拆。