某個外掛升級之後,後台突然變慢,你打開 wp-config.php 把 WP_DEBUG 打開,盯著 debug.log 一行一行找哪裡出錯,看到的卻只是一堆看不出優先順序的警告訊息,完全抓不出是哪支外掛在拖慢資料庫查詢,還是哪個佈景主題檔案多載入了不必要的樣式表。想確認某個 hook 上掛了什麼函式,只能自己在程式碼裡到處插 var_dump()、印完再刪掉,除錯一次就得來回改好幾次程式碼。
Query Monitor 就是為了解決這種看得到症狀、卻抓不到病灶的窘境而生的除錯外掛。它把 WordPress 網站產生這一頁時做過的每一件事,執行過哪些 SQL 查詢、觸發過哪些 hook、載入了哪些腳本與樣式表、發生過哪些 PHP 錯誤,全部攤開在管理工具列的下拉選單裡,不用另外裝瀏覽器擴充功能,也不用自己寫程式碼掛勾監聽。對經常要排查效能瓶頸或外掛衝突的人來說,這代表原本要來回改程式碼、猜測、重新整理頁面才能驗證的事,現在點開一個面板就能直接看到結果。
Query Monitor 是什麼?免除設定的 WordPress 開發者工具面板
如果你熟悉瀏覽器內建的開發者工具,Query Monitor 差不多就是把同一套邏輯搬進 WordPress 後台,Chrome DevTools 讓你看到瀏覽器端在做什麼,Query Monitor 則讓你看到伺服器端在產生這一頁的過程中做了什麼。它是由 John Blackbourn 開發並維護的外掛,Blackbourn 目前在 Human Made 擔任 WordPress 安全主管;整支外掛完全免費,並以 GPL 授權開源,安裝並啟用之後不需要額外設定任何選項,裝上去就能直接使用。
官方把它定位成「WordPress 與 WooCommerce 的開發者工具面板」,實際涵蓋的除錯範圍相當廣:資料庫查詢、PHP 錯誤、hooks 與 actions、區塊編輯器內容、已載入的腳本與樣式表,以及透過 HTTP API 發出的請求,都在它的偵測範圍內。支援方面,Query Monitor 相容近 3 年內發布的 WordPress 版本,PHP 環境則要求 7.4 以上,官方也已經測試到 PHP 8.5,不算是只支援舊版環境的外掛。

部分代管平台乾脆把它內建進自己的環境裡。WordPress VIP 就是一例,VIP 環境透過 MU 外掛(must-use plugin)的方式載入 Query Monitor,但即使帳號本身就是 Administrator,也還要額外取得 view_query_monitor 這項權限才看得到輸出內容;Altis Cloud 同樣把它列為代管環境的一部分。同一位開發者名下還維護另外 2 支姊妹外掛:User Switching 用來切換使用者帳號、WP Crontrol 用來管理 WP-Cron 排程任務,三支外掛合起來算是同一套除錯與維運工具鏈的延伸。
安裝後直接出現在管理列,權限預設只留給管理員
安裝的過程跟裝其他外掛沒有兩樣,不需要額外的設定精靈,啟用後就會直接生效。啟用之後,WordPress 的管理工具列(前台與後台都會出現,但只有登入的使用者才看得到)會多出一個項目,直接顯示目前這一頁的 4 個摘要數字:頁面產生時間(Page Generation Time)、尖峰記憶體用量(Peak Memory Usage)、SQL 查詢累計耗費的時間,以及這一頁總共執行了幾條 SQL 查詢。點一下這個摘要,就會展開完整的面板選單,裡面列出的每一個項目,各自對應到 Query Monitor 不同的除錯面板。

預設只有單站台的 Administrator,或多站台(Multisite)環境下的 Super Admin,能看到 Query Monitor 輸出的內容,其他角色登入後台看不到這個項目。如果需要在登出狀態下查看,或是想確認某個權限較低的角色實際會看到的畫面,可以到 Query Monitor 的設定面板點「Set authentication cookie」設定一組認證 Cookie,不需要時再按「Clear authentication cookie」清除。這個做法常常搭配同一位開發者維護的 User Switching 外掛一起用,在會員制網站或 WooCommerce 這類需要依角色顯示不同內容的站台上,確認不同身分的使用者實際看到什麼畫面。
總覽面板先列出四個數字,快速定位效能異常
點開管理工具列的摘要之後,第一個看到的就是 Overview 面板,這裡等於是除錯工作的健檢起點。它會重複顯示管理工具列的那 4 個摘要數字,讓你不用捲回頂端就能對照,同時把尖峰記憶體用量換算成一個更好判斷的數字,也就是目前用掉的記憶體佔 PHP 或 WordPress 記憶體上限的百分比。單看用了多少 MB 不容易判斷嚴不嚴重,換算成百分比之後,一眼就能看出這一頁是不是已經逼近上限。
Overview 面板同時會顯示物件快取(Object Cache)的統計數字。如果站台沒有安裝 Redis 或 Memcached 這類持久物件快取外掛,面板會直接跳出「External object cache not in use」的提示,代表資料庫查詢的結果沒有辦法跨請求保留下來,每次有人瀏覽頁面,該查的資料庫還是得重新查一次,對整體效能是一項扣分。看到這個提示,通常就代表接下來該考慮安裝快取外掛,或是跟主機商確認能不能提供 Redis 之類的持久快取環境。
資料庫查詢面板列出慢查詢與重複查詢
如果說 Overview 面板是健檢起點,Queries 面板就是 Query Monitor 資訊量最大、也最常被拿來抓問題的核心面板。它會逐條列出目前這一頁執行過的每一條 SQL 查詢,每一筆都顯示完整的查詢語法、呼叫者(Caller,也就是哪一段程式碼觸發了這條查詢)、所屬元件(是 WordPress 核心本身、目前使用的佈景主題,還是某一支外掛)、影響的資料筆數,以及這條查詢實際花費的時間。點擊每一筆查詢左側的加號,還能展開看到更詳細的資訊。
面板會自動幫 3 種異常的查詢加上標示:執行時間偏長的慢查詢(slow)、重複出現的查詢(duplicate),以及執行時發生錯誤的查詢(erroneous)。要縮小範圍時,可以依查詢類型(SELECT、UPDATE、DELETE 等)、負責的元件、觸發的函式這 3 個維度篩選,各自也提供彙整檢視。有一個容易被忽略的提醒:如果某個頁面顯示的查詢數異常偏低,原因通常不是網站真的變快了,而是頁面本身有快取,或是某支外掛自己把查詢結果快取起來。遇到這種情況,除錯時建議先暫時關閉快取外掛,才能看到頁面實際會跑幾條查詢。

依外掛與佈景主題分組排查拖慢效能的元件
Queries 面板底下還有幾個子面板,能直接回答哪一支外掛在拖慢資料庫這個問題。Queries by Component 子面板會列出所有觸發過查詢的元件,包含 WordPress 核心、目前的佈景主題,以及每一支個別的外掛;點擊某個元件,就能看到它觸發的所有查詢,是找出哪支外掛用掉大量或緩慢查詢、拖累資料庫最直接的入口。
Queries by Caller 子面板則依實際呼叫的函式列出所有 caller,點擊某個函式可以看到它觸發的查詢清單,適合用來檢查這段自己寫的程式碼是不是查詢下得太兇。Duplicate Queries 子面板專門把重複執行的查詢挑出來,並且直接點名這些查詢是潛在的問題製造者。同一條查詢在同一頁被跑了好幾次,通常可以透過物件快取或調整程式邏輯來避免,省下重複查詢消耗的時間。
db.php 連結失敗時,元件分類就顯示不出來
依元件分類這個功能背後有一個技術細節值得說清楚。Query Monitor 會在 wp-content 目錄下建立一個符號連結(symlink),指向它自己的 db.php 檔案,讓這支外掛能在資料庫驅動程式載入之前就先啟動,藉此記錄每一條查詢完整的呼叫堆疊,才有辦法判斷這條查詢屬於哪一個元件,並且記錄查詢的結果,包括影響筆數或發生的錯誤訊息。
如果這個符號連結沒有成功建立,Query Monitor 會在介面上顯示錯誤提示,其他功能仍然可以正常運作,只是看不到依元件分類的查詢資訊。常見的失敗原因有 2 種:一種是 wp-content 資料夾的檔案權限不足,沒辦法建立符號連結;另一種是 wp-content/db.php 這個路徑已經被別的外掛佔用,最常見於某些快取外掛(例如 W3 Total Cache)會自己放一個 db.php 在同樣的位置。遇到這種情況,可以自己手動建立這個符號連結,或是透過 WP-CLI 指令排解,官方 GitHub 上也有針對這個問題的專門說明頁面。

Hooks 與 Actions 面板,攤開外掛掛載的每個鉤子
資料庫查詢之外,另一個常被拿來抓外掛衝突的面板是 Hooks & Actions。它列出當前頁面觸發過的所有 hook,filter 與 action 都算在內,包含每個 hook 掛載的 callback 函式、執行的優先權(priority),以及所屬元件是核心、佈景主題,還是某支外掛。可以依元件或 hook 名稱篩選,快速找到想確認的目標。
點擊某個 action 項目還能展開,直接看到觸發它的實際檔案路徑與行號。這個面板的用途主要落在客製開發,比如想確認某支外掛在 wp_footer 這個 action 上掛了什麼函式、優先權設定成多少,或是懷疑兩支外掛在同一個 hook 上互相衝突,這裡都能直接看到全貌,不必再逐一打開檔案用文字搜尋去找。

HTTP API 呼叫面板,揪出拖慢載入的外部連線
除了站內的資料庫查詢與 hook,拖慢頁面的另一個常見來源是對外部服務的請求,這正是 HTTP API Calls 面板負責的範圍。它列出當前頁面所有透過 WordPress HTTP API(像是 wp_remote_get()、wp_remote_post() 這類函式)發出的伺服器端請求,顯示的欄位包括請求方法、URL、HTTP 狀態碼、呼叫者、所屬元件、逾時設定(timeout)、回應大小,以及實際耗費的時間。如果某筆請求失敗或回應不是 200,面板會加上警示標示,並提供可以點擊的連結方便追查。
額外支援的部分,官方提供了一個 middleware,讓透過 Guzzle 這套 HTTP 用戶端函式庫發出的請求也能一併顯示在同一個面板裡,涵蓋了那些繞過 WordPress 自家 HTTP API、改用 Guzzle 發送的請求。多數一般頁面應該顯示「No HTTP API calls」,這其實是好現象;如果一個平常不該呼叫外部服務的頁面卻跳出好幾筆 HTTP API 呼叫,常見於金流、物流或第三方資料同步類的外掛,這往往就是拖慢頁面載入時間的隱藏原因。
PHP 錯誤與過時函式用法,即時顯示在管理列
除了主動去查資料庫或外部連線,PHP 本身跳出的錯誤與警告,Query Monitor 也會直接攔截下來。PHP Errors 面板顯示當前頁面觸發的 PHP warnings、notices,以及 strict 與 deprecated 等級的錯誤,每一筆錯誤都會附上觸發它的責任元件與完整呼叫堆疊,也可以依錯誤等級(Level)篩選。只要頁面上出現任何錯誤,管理工具列就會立刻顯示明顯的警示顏色提醒,不需要另外打開 debug.log 才發現。
這個面板也會列出程式碼中使用「Doing it Wrong」或「Deprecated」功能的紀錄,這是 WordPress 核心內建的機制——用來警告開發者某個函式的用法已經過時,或是用錯了方式。Query Monitor 把這些紀錄攤在同一個面板裡,同樣附上是哪個元件觸發的,不需要開發者自己再去猜是哪支外掛還在呼叫已經被棄用的函式。

Ajax 與 REST API 請求同樣夾帶除錯資訊
以上幾個面板處理的多半是整頁載入時發生的事,前端非同步的 Ajax 與 REST API 請求同樣被涵蓋在內。任何由 jQuery 發起的 Ajax 請求,它的回應標頭(header)會自動夾帶各種除錯資訊,不需要額外撰寫程式碼掛勾。如果這次 Ajax 請求剛好觸發了 PHP 錯誤,錯誤內容也會一併輸出到瀏覽器的開發者主控台(console),不用再回頭查伺服器端的紀錄檔才知道哪裡出錯。
已經通過身分驗證的 WordPress REST API 請求也享有同樣的待遇,只要發出請求的使用者有權限看到 Query Monitor 的輸出,回應標頭就會附帶效能總覽與 PHP 錯誤資訊;如果請求採用 enveloped 格式(也就是在請求加上 _envelope 參數),回應內容的 qm 屬性還會包含更完整的除錯資料。這對表單送出、購物車更新、無限捲動這類前端非同步互動特別實用,出錯時打開瀏覽器的 Network 分頁看回應標頭,不必額外安裝別的瀏覽器擴充功能就能定位問題。
腳本與樣式表面板,標示載入順序中斷的相依套件
Scripts 面板列出當前頁面所有透過 wp_enqueue_script() 載入的 JavaScript 檔案,顯示載入位置、handle 名稱、來源主機、版本號、相依套件(dependencies)與被依賴者(dependents),遇到相依關係中斷或缺失的情況會加上警示。它同時支援 WordPress 6.5 開始加入的 script modules 功能。Styles 面板的顯示邏輯完全相同,只是列的是透過 wp_enqueue_style() 載入的 CSS 檔案。
兩個面板都可以依來源主機、相依或被依賴關係篩選。有一條經驗法則值得記住,腳本與樣式表的數量越多,頁面通常越慢,因為每一支檔案都會增加檔案大小與 HTTP 請求數。用這兩個面板可以直接抓出某支外掛額外載入了哪些其實沒必要的資源,是排查前端載入速度時最快的起點。
範本階層與管理畫面面板的客製開發用途
Template 面板只會出現在網站前台頁面,顯示目前使用的樣板檔名、完整的 template hierarchy(樣板階層)、哪些 template parts 曾經被請求、其中哪些真的被載入、哪些沒有,同時支援區塊主題與傳統主題,也會列出該頁面可用的 body class。想確認 WordPress 這次挑中了哪一個樣板檔案,這個面板直接給答案,不必自己對照樣板階層的規則去猜。
Admin Screen 面板只會出現在 WordPress 後台畫面。如果正在查看的是一個列表頁(list table),它會顯示自訂的欄位篩選與可用動作(actions),並且顯示 get_current_screen() 回傳的狀態。這兩個面板平常用不到,但客製佈景主題,或是替後台某個列表頁掛自訂欄位邏輯時,是相當關鍵的除錯工具,值得一併認識。
環境資訊與條件判斷面板,記錄伺服器與頁面的狀態
Environment 面板把詳細資訊分成 4 類:PHP(記憶體限制、錯誤回報等級、各項相關常數值)、資料庫(MySQL 或 MariaDB 的版本、快取與效能相關設定)、WordPress(版本號等)、Web 伺服器。這是判斷該不該升級 PHP 版本、該不該調高記憶體限制這類主機設定決策的依據,例如發現記憶體限制偏低,就該考慮調高;發現用的還是舊版 PHP,就該規劃升級以換取效能提升。
Conditionals 面板列出當前頁面所有 WordPress 條件式函式(is_single()、is_home()、is_admin() 等)各自回傳的結果,True 用綠色呈現、False 用灰色呈現。客製開發時用這個面板確認這段程式碼判斷式在這個頁面會不會被執行最直接,不必自己在程式碼裡插一行 var_dump() 再刪掉。
Capability Checks 面板預設關閉,加一行常數才看得到
Capability Checks 面板預設是關閉的,這是官方基於效能考量的預設值,需要在網站的 wp-config.php 加入一行 define( 'QM_ENABLE_CAPS_PANEL', true ); 才會啟用。啟用之後,面板會列出當前頁面每一次的使用者權限檢查(capability check),包括檢查的能力名稱、使用者 ID、檢查結果、呼叫者,以及所屬元件。
這個面板在會員制網站,或是 WooCommerce 這類需要依角色分權顯示內容的站台上特別實用,可以直接確認某個角色的使用者在這個頁面通不通過某項權限檢查,不必自己在程式碼裡插入除錯敘述再刪掉,省下不少來回測試的時間。
Languages 面板抓出翻譯檔遺漏的語言包
Languages 面板顯示網站的語言設定與各個文字網域(text domain),列出每一支外掛或主題實際被請求、且已經載入或找不到的翻譯檔,包含 MO 檔與 JSON 檔。這對多語站台,或是使用非官方完整翻譯語系包的站台特別有用。
遇到後台或前台某個外掛顯示的還是英文介面,懷疑翻譯檔沒被正確載入時,不必逐一去外掛的 languages 資料夾裡確認檔案存不存在,直接打開這個面板就能找出哪支外掛的翻譯檔沒有被正確載入,省下大量猜測與翻資料夾的時間。
Logs 與 Timings 面板,把 var_dump 換成結構化紀錄
前面的面板多半是 Query Monitor 自動蒐集到的資訊,Logs 與 Timings 這兩個面板則反過來,需要開發者自己在程式碼裡動手才會有內容。用 do_action( 'qm/debug', '訊息內容' ); 就能把自訂訊息記錄進 Logs 面板,相當於把傳統的 var_dump() 或 error_log() 輸出,結構化地呈現在同一個介面上;剛安裝好、還沒有任何自訂記錄時,這個面板會是空的。這套機制相容 PSR-3 標準,總共支援 8 種等級,由輕到重依序是 qm/debug、qm/info、qm/notice、qm/warning、qm/error、qm/critical、qm/alert、qm/emergency;只要記錄的等級達到 warning 或更高,管理工具列就會跳出警示提醒。
Timings 面板則是讓開發者用 do_action( 'qm/start', '計時器名稱' ); 與 do_action( 'qm/stop', '計時器名稱' ); 把想量測的一段程式碼包起來,量出這段程式碼實際耗費的時間與約略的記憶體用量,是最輕量、不需要安裝額外剖析工具(profiler)就能自己動手做效能量測的方法。官方也提醒,這裡顯示的時間與記憶體數字都是約略值,不是絕對精確的數字,拿來抓量級落差已經很夠用。
qm/cease 動作在大量匯入或備份時關閉監控
在程式碼裡執行 do_action( 'qm/cease' );,可以讓 Query Monitor 立即停止繼續收集資料,捨棄目前已經收集到的內容,並且在這次頁面請求剩餘的過程中都跳過輸出。這是一個容易被忽略、但對開發者很實用的細節功能。
官方列出的典型使用情境包括備份或還原網站、匯入或匯出大量資料,以及執行安全性掃描,這幾種操作本身就會觸發非常大量的資料庫查詢,或耗用大量記憶體,但這些查詢跟一般的效能除錯無關。讓 Query Monitor 全程監控,反而會拖慢這些操作的執行速度,甚至讓它自己的記憶體用量跟著暴增,所以遇到這類長時間執行的操作,先呼叫這個動作關掉監控會更划算。
核心免費版之外的瀏覽器擴充功能與外掛生態
核心免費版看到的這些面板之外,官方與社群還延伸出幾個值得認識的周邊。官方另外提供一款瀏覽器開發者工具擴充功能,作為同樣資訊的替代呈現方式,這個面板不會佔用頁面本身的顯示空間,可以自由調整大小,也能像其他瀏覽器開發者工具面板一樣拖曳或固定位置。Query Monitor 也透明支援 Debug Bar 外掛的所有 add-on,只要停用 Debug Bar 本體、保留它的 add-on,這些 add-on 就會自動出現在 Query Monitor 的選單裡,涵蓋了 ElasticPress、Elementor、Cache Lookup 等整合。
GitHub 上的官方 README 另外列出多款相關的延伸或替代外掛,例如針對 Redis、Memcached 快取的除錯工具,以及跟 WP-CLI 相關的排錯外掛。維護與贊助模式方面,Query Monitor 由 John Blackbourn 主導開發與維護,部分維護時間由 Automattic 等單位透過贊助支持,外掛本身完全免費、開源。
有一點值得誠實交代,Query Monitor 本身也會消耗一點效能。官方 FAQ 直接承認有影響,但影響很小,只有在單一頁面的查詢數達到數百筆這種極端情況下,因為要替每一條查詢記錄完整的呼叫堆疊,記憶體用量才會變得比較吃重,這也是開發者持續在優化的方向。換句話說,平常拿它排查問題不必擔心會反過來拖慢站台,真正該留意的只有查詢量特別大的少數頁面。
把這些面板攤開來看,Query Monitor 做的事其實很單純,就是把 WordPress 產生一頁內容的整個過程原封不動地攤在你眼前,不用另外寫程式碼監聽,也不用在 debug.log 裡大海撈針。真正決定它有沒有用的,不是裝了它,而是遇到問題時知道該打開哪一個面板:資料庫變慢先看 Queries,懷疑外掛衝突就翻 Hooks & Actions,前台載入卡頓先查 Scripts 與 Styles。下次網站又突然變慢,或是某支外掛的行為怎麼想都想不透,打開管理工具列的那個摘要數字,答案多半就在接下來點開的那個面板裡。
