在 PageSpeed Insights 跑完報告,看到「移除未使用 CSS」「移除未使用的 JavaScript」這兩條警告幾乎是每個 WordPress 站長都會遇到的關卡。它們不只是分數難看,背後牽動的是 LCP(最大內容繪製)、FCP(首次內容繪製)這些 Core Web Vitals 指標,直接影響使用者實際感受到的開啟速度,也連帶影響 Google 搜尋排名。
問題在於,「移除未使用 CSS」聽起來像一個按鈕,實際操作卻是一整套流程:要先搞清楚多餘的樣式從哪來,再決定用外掛自動處理還是手動 dequeue,最後還得驗證版面有沒有被砍壞。很多教學只丟給你一個外掛設定截圖,沒講清楚 inline 與 file 兩種輸出差在哪、為什麼自動移除常常把網站弄花。
這篇從診斷、避免、優化到移除驗證走完一條完整路線,CSS 與 JavaScript 兩邊都會處理,並針對 WooCommerce 商店常見的多餘樣式給出具體做法。看完你會知道每一步在做什麼,而不是照抄設定卻不知道風險在哪。
未使用的 CSS 與 JavaScript 是什麼,為什麼會拖慢網站
未使用的 CSS 指的是某個頁面載入了、但實際上沒有用到的樣式規則。瀏覽器在顯示頁面前,必須先把每一個 CSS 檔下載、解析、處理完,才會開始繪製畫面。多餘的樣式等於讓瀏覽器做白工,延後了使用者看到內容的時間,尤其拖累首屏(above-the-fold)的呈現速度。
這些多餘樣式主要來自四個地方:佈景主題、外掛、頁面建構器(如 Elementor、Divi),以及字型圖示(font icon)。多數佈景主題與外掛為了滿足各種使用情境,會把所有元件的樣式打包進同一支 style.css,於是即使你某一頁只用到一種按鈕,整套按鈕樣式照樣全部載入。
最典型的例子是聯絡表單外掛。你的聯絡頁需要它的 CSS 與 JavaScript,但每一篇部落格文章其實用不到,外掛卻預設在全站每一頁都載入。當網站有上千篇文章時,這種累積的浪費相當可觀。WooCommerce 也一樣,購物車、結帳、商品頁需要的樣式,預設會載到部落格與一般頁面上。
JavaScript 的情況類似但更棘手。未使用的 JavaScript 不只佔下載量,還會佔用瀏覽器的主執行緒(main thread)去解析與執行,拉高總阻塞時間(Total Blocking Time)。PageSpeed Insights 的效能分數有相當比重落在阻塞時間上,這也是為什麼處理腳本往往比處理樣式更能拉動分數。
PageSpeed Insights 通常要在單一頁面偵測到超過 10KB 的未使用 CSS 才會跳出這條警告,所以小型網站可能根本不會看到它;一旦看到,代表浪費的量已經值得處理。
怎麼找出哪些 CSS 與 JavaScript 沒被用到
診斷要從「看見問題」開始,最直接的兩個工具是 Chrome 開發者工具的覆蓋率(Coverage)面板與 PageSpeed Insights 本身。
Chrome DevTools 的覆蓋率面板能逐檔顯示每一支 CSS 與 JS 用到多少、浪費多少。操作方式是按 F12 開啟開發者工具,用 Ctrl + Shift + P 叫出命令選單,輸入 coverage 後選擇 Show Coverage,接著點重新整理按鈕開始記錄。記錄完成後,面板會用紅綠長條顯示每支檔案的使用比例,紅色就是沒被用到的部分。點進某一列還能在 Sources 分頁看到實際哪幾行沒用到,左側會標一條紅線。
PageSpeed Insights 則直接幫你篩出「高潛在節省」的檔案。展開「移除未使用 CSS」與「移除未使用的 JavaScript」這兩條建議,會看到每支資源的傳輸大小(transfer size)與潛在節省(potential savings)。這裡有一個實用判斷:如果某支檔案的傳輸大小和潛在節省幾乎相等,代表它在這一頁幾乎 100% 沒用到,可以放心停用。
GTmetrix 之類的測速工具提供瀑布圖(Waterfall),會把所有 CSS 與 JS 檔案列出來,而不只是高節省的那幾支,適合用來看全貌、找出哪個外掛或頁面建構器是大宗來源。
診斷時有一個容易踩的坑要先講清楚:覆蓋率工具只記錄頁面載入當下的使用情況,無法涵蓋使用者後續互動才會用到的樣式。例如把商品加入購物車後,導覽列或側邊欄出現的提示元素也需要樣式,這些是 JavaScript 動態套用的選擇器。所以看到「未使用」不代表真的能砍,這也是後面為什麼一定要做版面驗證的原因。
不靠外掛,怎麼用 functions.php 手動移除多餘樣式
如果你已經透過診斷確認某支 CSS 完全沒用到,最乾淨的做法是直接在佈景主題的 functions.php 用 wp_dequeue_style 取消註冊它。這比裝外掛更輕量,也不會引入額外的處理負擔。
最常見的目標是 Gutenberg 區塊編輯器的樣式。如果你用頁面建構器排版、完全不靠區塊編輯器,block-library 這支 CSS 通常整支都是多餘的。停用的程式碼放進 functions.php 或用 Code Snippets 外掛掛載即可:
function ezwps_remove_block_css() {
wp_dequeue_style( ‘wp-block-library’ ); // WordPress 核心
wp_dequeue_style( ‘wp-block-library-theme’ ); // WordPress 核心
wp_dequeue_style( ‘wc-block-style’ ); // WooCommerce 區塊樣式
}
掛載動作的優先序設成 100,是為了確保在樣式被註冊之後才執行 dequeue,否則取消不掉。要找到正確的樣式 handle(上面程式碼裡那串字串),可以回到 DevTools 看載入的檔名,或用 WordPress 的 wp_styles() 列出所有已註冊樣式來核對。
手動法的優點是精準、零外掛負擔,缺點是要懂程式碼、要自己一支一支處理,而且改錯 handle 名稱可能讓樣式完全消失。動手前務必備份 functions.php,並在改完後立刻檢查前台版面。對於來源複雜、檔案數量多的網站,純手動會非常吃力,這時候外掛的自動化反而比較實際。
值得提醒的是,許多重量級佈景主題會把上千行樣式塞進單一支 style.css,或以行內樣式(inline CSS)輸出。這類整包的樣式沒辦法用 dequeue 拆開只留用到的部分,只能靠後面要講的自動移除工具重新計算,或乾脆換一套輕量主題。
用外掛自動移除未使用 CSS,inline 與 file 兩種輸出怎麼選
當未使用樣式來源太雜、手動難以窮舉時,效能外掛的「移除未使用 CSS」功能會自動分析每一頁實際用到的選擇器,重新產生一份精簡的「已使用 CSS」(Used CSS),再把原本那些笨重的樣式延後或移除。常見具備這項功能的外掛包括 WP Rocket、Perfmatters、LiteSpeed Cache 與 FlyingPress。
這裡有一個關鍵差異,決定了你要選哪套工具:已使用 CSS 要用 inline(行內)還是 file(獨立檔案)輸出。
樣式塞進 HTML 首屏,PageSpeed 分數最漂亮,但每頁 HTML 變肥、無法快取
衝分數
樣式存成可快取的 CSS 檔,回訪更快、HTML 不變肥,分數略低於 inline
衝真實體驗
inline 把已使用樣式直接寫進首屏的 HTML 原始碼,這符合 Google 對首屏 CSS 的建議,PageSpeed 分數通常最好看,代價是每一頁的 HTML 都變大、而且無法被瀏覽器快取,回訪使用者每次都要重新下載這段樣式。file 則把已使用樣式存成獨立的 CSS 檔,可以被快取,回訪載入更快、HTML 也不會膨脹,對真實使用者的感受比較友善,分數會略低於 inline。
WP Rocket 目前採 inline 方式輸出。Perfmatters、LiteSpeed Cache、FlyingPress 則提供 file 選項。如果你追求 PageSpeed 高分截圖,inline 較有利;如果你重視回訪者與整體真實速度,file 通常是更好的選擇。
以 Perfmatters 為例,啟用流程是進入外掛設定的 CSS 分頁,把「Remove Unused CSS」開關打開,接著選 inline 或 file,再決定原始樣式的處理方式:延後載入(Delay,使用者互動後才載,官方建議)、非同步(Async)或直接移除(Remove,最激進、最容易需要例外設定)。WP Rocket 則在「檔案最佳化」分頁的「優化 CSS 載入」裡啟用。
一個跨外掛的共同前提:不要同時用兩套外掛去移除未使用 CSS,也要關掉「合併 CSS」功能。合併 CSS 自 HTTP/2 之後已是過時技巧,平行載入多支小檔反而更快;兩套移除工具同時運作則幾乎一定會打架、弄壞版面。
自動移除把版面弄花了怎麼辦,排除清單怎麼設
自動移除最常見的副作用就是版面跑掉,原因是工具誤判了某些「載入時看似沒用、互動後才需要」的樣式並把它砍了。解法不是關掉功能,而是把這些樣式加進排除清單(exclusions)。
排除分兩種:排除整支樣式檔,或排除特定選擇器(selector)。前者填入檔案來源網址的一段特徵字串,後者填入元素的 id 或 class 名稱,每行一個。實務上常需要排除的包括:區塊引言(blockquote、.wp-block-quote)、程式碼區塊(pre、code)、留言區(.comment)、頁面建構器的行動版選單與黏性選單,以及各家頁面建構器自己動態產生的樣式。
當版面壞掉卻不知道是哪支檔案造成時,有個快速縮小範圍的技巧:先把整個目錄暫時加進排除清單,例如 /themes/、/plugins/、/wp-includes/、/uploads/、/cache/,確認版面恢復正常後,再一個一個拿掉、找出真正的兇手。
某些頁面本身結構複雜、互動多,例如結帳頁或聯絡頁,與其逐條設例外,不如直接把整頁排除在自動移除之外。多數外掛在文章或頁面編輯畫面的側邊欄就有單頁停用的選項。
還有一類相容性問題值得注意。有些佈景主題(如 GeneratePress)的動態樣式可以選擇「行內嵌入」或「外部檔案」兩種輸出,要讓自動移除正確運作,應該選外部檔案模式,工具才抓得到、也才能被快取。如果你用第三方 CDN 搭配自訂網址,已使用 CSS 的載入順序偶爾會出問題,這時要用外掛內建的 CDN 改寫功能而不是另外的改寫方案。
每次改動樣式或新增自訂 CSS 後,記得清除已使用 CSS 快取,否則前台看到的還是舊版本。清快取的順序建議是:佈景主題、第三方外掛、效能外掛、主機商、CDN,最後用瀏覽器無痕模式確認改動生效。
從源頭減少 CSS,頁面建構器與圖示該怎麼設定
與其事後移除,更治本的做法是從一開始就少產生多餘樣式,這部分對用頁面建構器的網站特別有感,因為瀑布圖裡常常有超過一半的檔案來自建構器本身與其擴充外掛。
主流頁面建構器都有內建的效能設定,只在用到時才載入對應樣式。Elementor 的實驗功能裡有「改進的 CSS 載入」(Improved CSS Loading),開啟後會讓樣式表與動畫函式庫改為條件式載入。Divi 則有「動態 CSS」(Dynamic CSS),只載入該頁元件用到的樣式。開啟這些設定前先讀懂各自做了什麼,避免和效能外掛裡的功能重複設定而互相干擾。
字型圖示是另一個常被忽略的大宗。如果沒在用佈景主題或建構器附帶的圖示集(如 Font Awesome),把它停用就能省下一整支樣式。Elementor 在文件裡提供了停用內建圖示、Google 字型與 Font Awesome 的方法,可全站或單頁套用;Perfmatters 之類的外掛也能在腳本管理器裡關掉。
嵌入 YouTube 影片也會拉進播放器的 CSS 與腳本。如果使用者沒按播放,這些就是純浪費,尤其一頁嵌好幾支影片時。多數效能外掛提供「以預覽圖取代 YouTube iframe」的功能,把笨重的播放器延後到使用者點下播放鍵才載入。
選主題與控制外掛數量則是更上游的決策。Astra、GeneratePress 這類輕量主題本身就少載樣式與腳本,先天條件好很多。外掛則是裝越多、樣式衝突與多餘 CSS 的機率越高,定期清掉長期沒用的外掛,比事後拼命移除樣式划算。
WordPress 移除未使用 JavaScript,跟 CSS 哪裡不一樣
JavaScript 的處理邏輯和 CSS 不太一樣,理解這點能省下很多白費的力氣。CSS 可以靠工具重新計算出「只含用到的樣式」那一份,但 JavaScript 很難可靠地做到「只留用到的程式碼」——腳本的執行往往依賴互動、依賴彼此的相依關係,硬砍很容易出錯。所以對 JS 的主流策略不是「移除」,而是延後與延遲執行。
兩個核心手段是「延後載入 JavaScript」(defer)與「延遲執行 JavaScript」(delay execution)。defer 讓腳本不再阻擋 HTML 解析,等頁面結構就緒後才執行;delay execution 則更進一步,把腳本的執行延到使用者第一次互動(捲動、點擊、移動滑鼠)之後,這對第三方腳本特別有效。多數效能外掛在 JavaScript 設定區都有這兩個選項,開啟後能明顯壓低總阻塞時間,把 PageSpeed 分數往上推。
針對特定外掛的多餘腳本,可以用腳本管理器(Script Manager)這類功能在不需要它的頁面停用。例如聯絡表單腳本只留在聯絡頁、社群分享腳本只留在文章頁。Perfmatters 的腳本管理器能逐檔開關,還能顯示每支檔案屬於哪個外掛,方便判斷。
如果要走手動路線,原理和 CSS 的 dequeue 相同,改用 wp_dequeue_script 取消註冊某支腳本,一樣放在 wp_enqueue_scripts 動作、優先序拉高。但同樣的風險也在:腳本之間常有相依關係,砍掉一支可能連帶讓另一支報錯,動手後務必開瀏覽器主控台(Console)看有沒有 JavaScript 錯誤。
第三方腳本(廣告、分析、YouTube、社群外掛)是 PageSpeed 報告裡常見的未使用 JS 來源,但它們託管在別人的網域上,你無法移除其內容,只能透過延後與延遲執行去降低衝擊,或評估是否真的需要它。
WooCommerce 商店怎麼處理多餘的 CSS 與腳本
WooCommerce 預設會在全站每一頁載入它的樣式與腳本,包括完全用不到的部落格文章與一般頁面,這對內容型的電商網站是明顯的浪費。處理原則是:只在電商相關頁面(商品、商品分類、購物車、結帳、商店頁)載入 WooCommerce 資產,其他頁面一律卸掉。
效能外掛的腳本管理器是最省事的做法,可以把 WooCommerce 的樣式與腳本設成只在電商頁面載入。也有專門針對 WooCommerce 減重的外掛(如 Disable WooCommerce Bloat),提供更細的設定來關掉非電商頁面上的多餘資產。
要注意的是,WooCommerce 的購物車、結帳這類頁面有大量依賴互動的動態樣式與腳本,是自動移除工具最容易誤砍的地方。把已使用 CSS 設定中的結帳頁與購物車頁排除在自動移除之外,通常是比較安全的選擇,免得結帳流程的版面或功能出狀況——這類頁面壞掉直接影響成交,不值得為了幾分 PageSpeed 去冒險。
收款相關的頁面(金流串接、付款結果頁)也屬於這個範疇:它們的腳本與樣式請保守處理、優先排除,先確保功能正常,再談最佳化。
移除之後一定要做的版面與功能驗證
自動移除幾乎不可能 100% 精準,所以「移除完就收工」是最危險的心態。每一次調整後都要做一輪驗證,確認外觀和功能都沒被砍壞。
驗證重點放在幾個高風險區域:含有按鈕、表單、彈出視窗、輪播、手機版選單與黏性選單的頁面,這些都依賴互動時才觸發的樣式,最容易被誤判為「未使用」而砍掉。逐頁檢查時用瀏覽器無痕模式開啟,避免快取干擾判斷,看到的才是訪客真正會看到的畫面。
具體的驗證流程可以這樣跑:
清快取
無痕看版面
測互動功能
看 Console
重跑測速
先清掉所有快取層讓改動生效,再用無痕模式逐頁檢查桌機與手機版的外觀,接著實際操作互動功能(送出表單、開合選單、加入購物車、走一遍結帳),同時打開瀏覽器主控台確認沒有 JavaScript 錯誤。最後重跑 PageSpeed Insights 或 GTmetrix,比對改動前後的數字,確認分數真的有進步而不是壞掉。發現哪裡跑掉,就回到排除清單把對應的檔案或選擇器加進去,重新清快取再驗一次。
養成「改一項、驗一輪」的節奏,而不是一次開一堆設定再來找問題,能讓你在出狀況時很快定位是哪一步造成的。最佳化的目標從來不是 PageSpeed 那個數字本身,而是讓真實訪客更快看到、更順地操作你的網站;分數只是參考,版面與功能完整才是底線。處理未使用 CSS 與 JavaScript 是個持續的過程,每次新增外掛或改版後都值得再跑一遍這套流程,把多餘的負擔擋在上線之前。