打開任何一個全新安裝的 WordPress 網站,按右鍵看一下原始碼,你會在 <head> 裡看到一堆從來沒設定過、卻自己冒出來的東西:一段偵測 emoji 的 JavaScript、一個指向 wp-embed.min.js 的腳本、一條連到 s.w.org 的 DNS 預抓、還有 RSD、wlwmanifest、產生器版本號這些幾乎沒人會用到的標籤。這些是 WordPress 為了「相容所有可能的網站」而預設塞進來的,但對大多數台灣站長來說,它們只是讓每個頁面多送幾個請求、多載幾 KB、多一次對外連線而已。
WordPress 移除多餘請求的重點,不在於砍掉它能省下多少毫秒,而在於它幾乎零風險、一次設定就長期受用,還能順手收掉一些對外洩漏資訊的小破口。這篇會把這些預設載入逐項拆開,講清楚每一項實際送出的是「HTTP 請求」「一段內嵌標記」還是「一次 DNS 查詢」,哪些可以放心移除、哪些移除前要先確認用不到,最後給一份依風險分層、可以直接複製的整合程式碼。
為什麼 WordPress 會自己載入這些多餘的東西
這些請求不是外掛裝出來的,而是 WordPress 核心預設行為。原因是 WordPress 要服務全世界各種版本的瀏覽器、各種使用情境,所以它把「有些人可能會用到」的功能全部預載:舊瀏覽器看不懂 emoji,所以塞一段相容腳本;有人想貼 YouTube 連結自動變成影片,所以載入 oEmbed;有人用 Windows Live Writer 寫文章,所以加上 wlwmanifest。
問題是這些情境對現在的台灣網站幾乎都不成立。emoji 相容腳本是 2015 年 WordPress 4.2 為了當年的舊瀏覽器加的,而現在的瀏覽器早就能原生顯示 emoji;Windows Live Writer 這套桌面寫作軟體更是停止開發多年。換句話說,這些載入幾乎都是替「不存在的使用者」服務。
實際省下的量級要先講清楚,避免期待落差。移除這些東西,整頁大小大約少 30 到 80 KB、請求數少 2 到 7 個、JavaScript 執行時間少幾毫秒到二十幾毫秒。對流量小的網站,肉眼幾乎感覺不出來;真正的價值是在內容多、流量高的站,這些小東西每頁、每次造訪累積起來才看得出差別。比起換一個輕量佈景、用快取、壓縮圖片,移除這些請求是「報酬率小但成本更小」的優化——它不需要花錢,也不太會弄壞網站。
emoji 相容腳本到底載入了什麼,怎麼移除
emoji 功能在前端其實同時塞進三樣東西,不是只有一個 JS 檔。第一是 <head> 裡一段內嵌的偵測腳本(wp-emoji-release.min.js 的載入器),用來判斷瀏覽器能不能顯示 emoji;第二是一段 emoji 專用的 inline CSS;第三是一條對 s.w.org 的 DNS 預抓提示(dns-prefetch),等於替訪客先對 WordPress.org 的伺服器做一次網域查詢。
對台灣讀者來說,第三項其實最值得留意:那是一次對外網域的連線提示,移除後訪客瀏覽器就不會主動去碰 s.w.org,順帶減少一點對外資訊外流。把以下程式碼加進佈景的 functions.php(建議用子佈景,理由後面會說),就能把這三樣一次收掉:
// 移除前端、後台、RSS 與 email 的 emoji 載入
function ezwps_disable_emojis() {
remove_action( 'wp_head', 'print_emoji_detection_script', 7 );
remove_action( 'admin_print_scripts', 'print_emoji_detection_script' );
remove_action( 'wp_print_styles', 'print_emoji_styles' );
remove_action( 'admin_print_styles', 'print_emoji_styles' );
remove_filter( 'the_content_feed', 'wp_staticize_emoji' );
remove_filter( 'comment_text_rss', 'wp_staticize_emoji' );
remove_filter( 'wp_mail', 'wp_staticize_emoji_for_email' );
add_filter( 'tiny_mce_plugins', 'ezwps_disable_emojis_tinymce' );
add_filter( 'wp_resource_hints', 'ezwps_disable_emojis_dns_prefetch', 10, 2 );
}
add_action( 'init', 'ezwps_disable_emojis' );
// 移除編輯器裡的 emoji 外掛
function ezwps_disable_emojis_tinymce( $plugins ) {
if ( is_array( $plugins ) ) {
return array_diff( $plugins, array( 'wpemoji' ) );
}
return array();
}
// 移除指向 s.w.org 的 DNS 預抓
function ezwps_disable_emojis_dns_prefetch( $urls, $relation_type ) {
if ( 'dns-prefetch' === $relation_type ) {
$emoji_svg_url = apply_filters( 'emoji_svg_url', 'https://s.w.org/images/core/emoji/2/svg/' );
$urls = array_diff( $urls, array( $emoji_svg_url ) );
}
return $urls;
}
移除之後 emoji 並不會消失。現在的瀏覽器都內建 emoji 字型,文章裡照打照顯示,只是不再由 WordPress 額外載入相容檔。
oEmbed 與 wp-embed.min.js 移除前要先確認用不用得到
oEmbed 是 WordPress 4.4 併進核心的功能,讓你只要貼一條 YouTube、X(Twitter)、Vimeo 的網址,它就自動變成可播放的嵌入卡片。代價是每個前端頁面都會多載一個 wp-embed.min.js(約 1.7 KB),就算你整篇文章一個嵌入都沒有,這個檔還是會載。
這裡要分清楚兩件常被混為一談的事:移除 wp-embed.min.js 這個腳本,跟關掉整套 oEmbed 是不同層級的動作。前者只是不載那個前端 JS 檔,後者會連帶關掉 oEmbed 的 REST 路由、自動探索連結與改寫規則。如果你的文章還會用到「貼站內文章網址自動變預覽卡」這類功能,整套關掉就會讓那個功能失效。
判斷原則很簡單:如果你都是用 YouTube、X 官方提供的 iframe 嵌入碼,或根本不在文章裡貼自動嵌入,那整套移除沒問題。下面這段就是 WordPress 官方 Disable Embeds 外掛的核心邏輯,可直接放進 functions.php:
function ezwps_disable_embeds() {
// 移除 oEmbed REST API 路由
remove_action( 'rest_api_init', 'wp_oembed_register_route' );
// 關閉 oEmbed 自動探索
add_filter( 'embed_oembed_discover', '__return_false' );
// 不過濾 oEmbed 結果
remove_filter( 'oembed_dataparse', 'wp_filter_oembed_result', 10 );
// 移除 head 裡的 oEmbed 探索連結
remove_action( 'wp_head', 'wp_oembed_add_discovery_links' );
// 移除前後台的 oEmbed JS(wp-embed.min.js)
remove_action( 'wp_head', 'wp_oembed_add_host_js' );
// 從編輯器移除 wpembed 外掛
add_filter( 'tiny_mce_plugins', function ( $plugins ) {
return array_diff( $plugins, array( 'wpembed' ) );
} );
// 移除 embed 相關的改寫規則
add_filter( 'rewrite_rules_array', function ( $rules ) {
foreach ( $rules as $rule => $rewrite ) {
if ( false !== strpos( $rewrite, 'embed=true' ) ) {
unset( $rules[ $rule ] );
}
}
return $rules;
} );
}
add_action( 'init', 'ezwps_disable_embeds', 9999 );
如果你只想拿掉那個前端 JS 請求、但保留 oEmbed 嵌入能力,可以只移除腳本本身,把整套關閉的邏輯留著:
function ezwps_dequeue_embed() {
wp_dequeue_script( 'wp-embed' );
}
add_action( 'wp_footer', 'ezwps_dequeue_embed' );
wp_head 裡那些用不到的中繼標籤,移除哪些才安全
除了 emoji 和 embed,WordPress 還會在 <head> 裡輸出好幾條中繼連結與標籤。這些大多不會送出額外 HTTP 請求,而是「多印幾行 HTML 標記」,移除它們主要是讓原始碼乾淨、收掉資訊外洩破口,順便讓爬蟲少看幾條無意義連結。
最值得移除的是產生器版本號(<meta name="generator" content="WordPress 6.x">)。它沒有任何功能,卻直接把你的 WordPress 版本公告給全世界,等於替想找特定版本漏洞的人省了第一步。其他像 RSD(Really Simple Discovery,給舊版桌面部落格軟體連線用的)、wlwmanifest(Windows Live Writer 用的)、短連結標籤(shortlink,現在幾乎沒人用)、以及 REST API 的探索連結,都屬於可以安心移除的類別。
function ezwps_clean_wp_head() {
// 移除 WordPress 版本號(前端與 RSS)
remove_action( 'wp_head', 'wp_generator' );
add_filter( 'the_generator', '__return_empty_string' );
// 移除 RSD 連結
remove_action( 'wp_head', 'rsd_link' );
// 移除 Windows Live Writer manifest
remove_action( 'wp_head', 'wlwmanifest_link' );
// 移除短連結標籤
remove_action( 'wp_head', 'wp_shortlink_wp_head', 10 );
// 移除 REST API 探索連結
remove_action( 'wp_head', 'rest_output_link_wp_head', 10 );
remove_action( 'template_redirect', 'rest_output_link_header', 11 );
}
add_action( 'init', 'ezwps_clean_wp_head' );
要特別澄清一個常見誤會:移除「REST API 的探索連結」只是把 <head> 裡那條 <link rel="https://api.w.org/"> 標記拿掉,並沒有關閉 REST API 本身。WordPress 的區塊編輯器、許多外掛都靠 REST API 運作,真要把整個 REST API 關掉會弄壞後台與一堆功能,那是另一回事,這裡做的只是清掉那條指引標籤而已。
至於 RSS feed 連結(feed_links),則屬於「移除前要想一下」的類別。如果你的網站完全不靠 RSS——沒有 Podcast、沒人用閱讀器訂閱、沒接 Feedburner,移除它無妨;但只要還有訂閱需求,就別動。
dashicons 與 jQuery Migrate 移除前的相容性風險
這兩項是省下來最有感、但也最容易踩雷的,移除前一定要先確認自己用不到。
dashicons 是 WordPress 後台用的圖示字型,整包約 70 KB。問題是它預設也會載給「前台未登入的訪客」,多數佈景的前端根本沒用到它。如果你的佈景或某些外掛(例如部分表單、相簿、圖示按鈕)有在前端用 dashicons,移除後圖示會變空白方塊。安全做法是只對未登入訪客移除,登入後台時保留:
function ezwps_dequeue_dashicons() {
if ( ! is_user_logged_in() ) {
wp_dequeue_style( 'dashicons' );
wp_deregister_style( 'dashicons' );
}
}
add_action( 'wp_enqueue_scripts', 'ezwps_dequeue_dashicons' );
jQuery Migrate(jquery-migrate.min.js)是一個讓舊版 jQuery 寫法在新版仍能運作的相容層。移除它能省一個請求,但風險明顯較高:很多上了年紀的佈景與外掛仍依賴它,移掉之後若前端某些互動(輪播、彈窗、選單)失效,多半就是這個原因。建議只在你確定整站用的都是維護良好、不依賴舊 jQuery 寫法的佈景與外掛時才動,而且移除後務必把網站的互動功能逐一點過一遍。
function ezwps_remove_jquery_migrate( $scripts ) {
if ( ! is_admin() && isset( $scripts->registered['jquery'] ) ) {
$script = $scripts->registered['jquery'];
if ( $script->deps ) {
$script->deps = array_diff( $script->deps, array( 'jquery-migrate' ) );
}
}
}
add_action( 'wp_default_scripts', 'ezwps_remove_jquery_migrate' );
XML-RPC 也常被歸在這類「移除有額外好處」的項目。它本身不是前端請求,但長年是暴力破解與垃圾留言的入口之一;如果你不用 Jetpack、不用 App 遠端發文,可以考慮停用,這偏向資安面而非載入精簡,這裡先點到。
用程式碼還是用外掛,以及怎麼放才不會被更新覆蓋
這些調整有兩條路:直接寫程式碼,或裝一個現成外掛(例如官方的 Disable Embeds、Disable Emojis,或整合型的優化外掛)。各有取捨。
外掛的優點是零門檻、裝了就生效、不怕寫錯語法白屏;缺點是每多裝一個外掛就多一份要維護、要更新、可能彼此衝突的負擔,而這幾項調整的程式碼其實短到不需要為它養一個外掛。直接寫程式碼則更輕、更穩、可以精準控制移除哪幾項,缺點是寫錯一個字元可能讓整站白屏。
不論選哪條,關鍵是放對地方,否則更新一次就被洗掉:
- 不要直接改父佈景的 functions.php。佈景一更新,整個檔案會被覆蓋,你的設定全部消失。
- 自己有開發能力的,建立子佈景,把上述程式碼放進子佈景的 functions.php,更新父佈景時不受影響。
- 不想碰子佈景的,用程式碼片段管理外掛(例如 WPCode 這類),把片段設成 PHP、自動插入並啟用即可。這比硬改檔案安全,誤刪也只影響那段片段。
- 動手前先備份整站。改 functions.php 的典型風險就是語法錯誤導致白屏,有備份就能在幾分鐘內還原。
移除前後怎麼驗證真的生效了
做完別只憑感覺,實際驗一次才知道有沒有生效、有沒有弄壞東西。
最直接的方法是看原始碼:在前台頁面按右鍵選「檢視網頁原始碼」,用瀏覽器搜尋功能找關鍵字。移除前後各搜一次這幾個字串,看它們是否消失:wp-emoji、wp-embed、s.w.org、generator、wlwmanifest、rsd。原本找得到、改完找不到,就代表那條已經拿掉。
要看請求數與檔案的變化,打開瀏覽器開發者工具的「Network(網路)」分頁,重新整理頁面,比對改之前與改之後的請求列表,wp-emoji-release.min.js、wp-embed.min.js、dashicons 這幾筆應該會不見。想看整體分數變化,可以用 PageSpeed Insights、GTmetrix 這類工具,前後各跑一次,觀察請求數、總頁面大小與 JavaScript 執行時間的差異——數字會動,但別期待它讓分數暴漲,這是累積型的小優化。
最後別忘了功能回歸測試:移除 oEmbed 後,確認該嵌入的內容還在;移除 dashicons、jQuery Migrate 後,把前端的選單、輪播、彈窗、表單逐一點過,確認互動都正常。只要有一項壞掉,回頭把對應那段程式碼註解掉即可,這也是建議分項加入、而非一次全貼的原因。
把這些調整變成你網站的固定基底
WordPress 移除多餘請求不是什麼進階魔法,而是把核心為了「相容所有人」而預載、但你根本用不到的東西收乾淨。emoji 相容腳本、wp-embed.min.js、s.w.org 的 DNS 預抓這幾項幾乎人人可移;產生器版本號、RSD、wlwmanifest、短連結這些清掉只有好處沒有壞處;dashicons、jQuery Migrate、整套 oEmbed 與 RSS 則要先確認自己用不到再動。
實際做法上,先備份,把程式碼放進子佈景或程式碼片段外掛裡,分項加入、逐項驗證,確認原始碼裡對應的字串消失、前端功能沒壞,就把它留著當網站的固定基底。下次架新站時,把這份整合片段直接帶過去,新站從第一天起就乾淨、輕、少送幾個對外請求。