WordPress 默认在所有页面的 head 区域注入一段 _wpemojiSettings 相关代码——约 80 行 JS + 一段 CSS,用于把页面里的 emoji 字符(😀😢👍)转换为兼容老浏览器的图片表情。这段代码在 2015 年(WP 4.2 引入)有意义,但 2024 年所有现代浏览器(含 Edge、Safari、移动端)都原生支持 emoji 字体渲染,wpemoji 的存在变成纯粹的性能负担:每页多一次 wp-emoji-release.min.js 的请求(13 KB)+ inline JS 阻塞 head 解析。本文给出从「functions.php 关闭」到「mu-plugin 全站统一关闭」「与缓存插件协同」「Heartbeat 与其他默认请求一起优化」的完整 head 瘦身方案。
wpemoji 的性能影响
具体损耗
用 Lighthouse 与 WebPageTest 测量典型 WordPress 站点:
- Inline JS 字节:head 里 ~3.5 KB 的 wpemoji 检测脚本。
- 外部 JS 请求:wp-emoji-release.min.js 约 13 KB,gzip 后 5 KB。
- JS 解析阻塞:head 里的 inline JS 会同步执行,平均阻塞 30-80ms(取决于 CPU)。
- Canvas 检测开销:脚本会创建 canvas 检测 emoji 渲染能力,触发 GPU 上下文初始化。
累积影响:单页 LCP 平均增加 100-200ms,Lighthouse 性能分扣 3-5 分。流量大的站点这是不可忽视的损耗。
用户损失
关掉 wpemoji 之后用户失去什么?答案:在现代浏览器上几乎什么也没有。
- Chrome/Edge/Safari/Firefox 的现代版本(2017 后)都原生支持 emoji 字体(Apple Color Emoji、Segoe UI Emoji、Noto Color Emoji)。
- Android 与 iOS 原生支持 emoji。
- 仅 IE 11 及以下(市占率 < 0.3%)会显示成方框。
损失对象是这极少数老浏览器用户。多数中文站点完全不依赖 emoji(中文用户用得少),关掉零代价。
关闭 wpemoji 的完整代码
基础版(functions.php 直接加)
/**
* 关闭 WordPress 自带 emoji 加载
*/
function disable_wp_emojis() {
/* 前台 head 区 */
remove_action('wp_head', 'print_emoji_detection_script', 7);
remove_action('wp_print_styles', 'print_emoji_styles');
/* 后台 head 区 */
remove_action('admin_print_scripts', 'print_emoji_detection_script');
remove_action('admin_print_styles', 'print_emoji_styles');
/* RSS feed */
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');
/* TinyMCE 编辑器内的 emoji 插件 */
add_filter('tiny_mce_plugins', 'disable_emojis_tinymce');
/* 删除 dns-prefetch */
add_filter('wp_resource_hints', 'disable_emojis_remove_dns_prefetch', 10, 2);
}
add_action('init', 'disable_wp_emojis');
function disable_emojis_tinymce($plugins) {
return array_diff($plugins, ['wpemoji']);
}
function disable_emojis_remove_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/');
$urls = array_diff($urls, [$emoji_svg_url]);
}
return $urls;
}相比原文方案的改进
- 用 init 钩子注册而不是直接调 remove_action,避免主题加载顺序问题。
- 额外移除 dns-prefetch(WordPress 5.x 起会预解析 s.w.org,关 wpemoji 时也应该移除)。
- 禁用 TinyMCE 编辑器的 wpemoji 插件,让后台编辑器也不加载 emoji JS。
- 用单独函数封装方便管理。
head 区其他可优化项
关 wpemoji 是 head 瘦身的开胃菜。WordPress 默认注入 head 的还有这些可酌情删除:
WP REST API 链接
remove_action('wp_head', 'rest_output_link_wp_head', 10);
remove_action('template_redirect', 'rest_output_link_header', 11);WordPress 4.4+ 会在 head 加 <link rel="https://api.w.org/" href=".../wp-json/" />。如果你的站点不开放 REST API,删掉。
wlwmanifest(Windows Live Writer 适配)
remove_action('wp_head', 'wlwmanifest_link');Windows Live Writer 早就停止维护,这个 link 完全是历史遗留。
RSD(远程发布协议)
remove_action('wp_head', 'rsd_link');RSD 是 XML-RPC 远程发布协议入口。关掉 XML-RPC 时同步关 RSD。
shortlink
remove_action('wp_head', 'wp_shortlink_wp_head');WP 自动给每篇文章生成 ?p=123 形式的短链接放 head。多数站点用不到。
generator meta
remove_action('wp_head', 'wp_generator');暴露 WordPress 版本号方便攻击者针对性扫漏洞。强烈建议删除。
预加载与 prefetch 优化
有些主题会盲目添加 dns-prefetch 或 preconnect 标签到 head。审计一遍只保留真正会请求的域名。
整合所有优化的 mu-plugin
把所有 head 瘦身代码放进 mu-plugin(must-use plugin),所有共享 wp-content 的多站点自动加载,无需修改主题:
<?php
/**
* Plugin Name: Head Optimizer
* Description: 移除 WordPress 默认的非必要 head 资源
* Version: 1.0
*/
add_action('init', function() {
/* emoji */
remove_action('wp_head', 'print_emoji_detection_script', 7);
remove_action('wp_print_styles', 'print_emoji_styles');
remove_action('admin_print_scripts', 'print_emoji_detection_script');
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');
/* head 元信息瘦身 */
remove_action('wp_head', 'wlwmanifest_link');
remove_action('wp_head', 'rsd_link');
remove_action('wp_head', 'wp_shortlink_wp_head');
remove_action('wp_head', 'wp_generator');
remove_action('wp_head', 'rest_output_link_wp_head');
/* prev/next link(WP 5.x 后已自动移除,老版本主题保留) */
remove_action('wp_head', 'adjacent_posts_rel_link_wp_head', 10);
remove_action('wp_head', 'index_rel_link');
remove_action('wp_head', 'parent_post_rel_link', 10);
remove_action('wp_head', 'start_post_rel_link', 10);
});
add_filter('tiny_mce_plugins', function($plugins) {
return array_diff($plugins, ['wpemoji']);
});
add_filter('wp_resource_hints', function($urls, $relation_type) {
if ('dns-prefetch' === $relation_type) {
$emoji_svg_url = apply_filters('emoji_svg_url', 'https://s.w.org/images/core/emoji/');
$urls = array_diff($urls, [$emoji_svg_url]);
}
return $urls;
}, 10, 2);
/* 移除版本号让 generator meta 即便有也是空 */
add_filter('the_generator', '__return_empty_string');把以上代码保存为 wp-content/mu-plugins/head-optimizer.php。mu-plugin 不需要在后台「插件」页激活,自动生效。
Heartbeat 与默认请求优化
Heartbeat API
WordPress 后台每 15 秒发一次 admin-ajax.php 请求做心跳检测。这在多人编辑时有用(实时知道谁正在编辑),但单人博客是负担:
add_action('init', function() {
if (!is_admin()) return;
wp_deregister_script('heartbeat');
});
/* 或者只在文章编辑页保留 */
add_filter('heartbeat_settings', function($settings) {
$settings['interval'] = 60; // 默认 15 秒,改成 60 秒
return $settings;
});移除 jQuery Migrate
WP 默认加载 jquery-migrate.js(兼容 jQuery 老 API)。多数现代主题不需要:
add_action('wp_default_scripts', function($scripts) {
if (!empty($scripts->registered['jquery'])) {
$scripts->registered['jquery']->deps = array_diff(
$scripts->registered['jquery']->deps,
['jquery-migrate']
);
}
});关闭 XML-RPC
XML-RPC 是早期博客客户端协议,2024 年很少用且是攻击入口(暴力破解 XMLRPC.php 的 HTTP 请求每天上千次):
add_filter('xmlrpc_enabled', '__return_false');nginx 层直接 deny 更彻底:
location = /xmlrpc.php { deny all; }与缓存插件的协同
本文方案在 PHP 层移除资源,缓存插件(WP Rocket、W3 Total Cache、WP Super Cache)从优化后的 PHP 输出生成静态缓存,效果叠加。
注意:
- 有些缓存插件自带「Disable Emoji」选项(WP Rocket 设置里有),与本文 mu-plugin 重复但无害。
- 缓存清理后第一次访问会重新生成缓存,那次访问看到的是优化后的 head。
- 清缓存命令:
wp cache flush(WP-CLI)或者插件自带的「清空缓存」按钮。
验证优化效果
方法一:查看页面源码
浏览器右键「查看源代码」,搜 wpemoji 与 _wpemojiSettings。看到的话说明没生效。
方法二:Lighthouse 跑分
Chrome DevTools - Lighthouse - Performance。优化前后对比 Performance 分数与 LCP/FCP 数值。
方法三:WebPageTest 瀑布图
webpagetest.org 跑一次,看 head 区资源加载瀑布图。优化后应当少 1-2 个 wp-emoji 相关请求。
方法四:grep 网站源代码
curl -s https://example.com | grep -c emoji返回 0 说明完全清除。返回非 0 说明还有 emoji 相关代码残留。
常见故障
故障 1:functions.php 加了代码但 wpemoji 还在
三个排查:缓存插件未清理;OPcache 缓存了旧 PHP;某些重型主题(Avada、Divi)有自己的 emoji 加载逻辑覆盖了 WP 默认。检查主题 functions.php 是否包含独立的 emoji 引入。
故障 2:删 wpemoji 后评论显示 emoji 变成方框
用户评论里写了 emoji 字符。现代浏览器会原生渲染,但极老浏览器(IE 11)会方框。这是预期内的取舍,市占率极低不影响整体。
故障 3:删 generator 后 SEO 插件报警
少数 SEO 插件(Yoast 老版本)会读 generator meta 判断 WP 版本做兼容性。检查插件 changelog,新版多数已经不依赖。
故障 4:删 RSD 后远程发布工具失效
如果你确实用 Microsoft Word、ScribeFire 等工具远程发文,需要保留 RSD 与 wlwmanifest。多数 2024 年的运营完全不用这些工具。
故障 5:移除 jQuery Migrate 后某些插件报错
老插件(2018 年前的)可能调用 jQuery 已废弃 API(如 $.browser),失去 migrate 后报 undefined。要么升级插件,要么保留 migrate。
故障 6:mu-plugin 不生效
检查路径是否是 wp-content/mu-plugins/(注意是复数);文件后缀是否 .php;文件头是否有 PHP 注释块声明 Plugin Name。
故障 7:管理后台报错「找不到 emoji 插件」
极少数情况:某些后台插件依赖 wpemoji 全局对象。看 PHP error.log 找到具体哪个插件,要么禁用该插件,要么不要全局移除 wpemoji 改成只前台移除。
常见问题解答
关掉 wpemoji 会让 SEO 受影响吗?
不会负面,反而是正面。Lighthouse 性能分提升间接对 SEO 有利。Google 对 head 内容多少没有直接评分。
能否只在前台关闭后台保留?
能。把 admin_print_scripts 那两行去掉,保留 wp_head 那两行。
关闭后还能在文章里写 emoji 吗?
能。emoji 字符(😀😢)会被浏览器原生渲染,文章里写的 emoji 一切照常。只是 WP 不再用图片转换,依赖系统字体。
移动端是否需要 emoji 转图片?
不需要。iOS 与 Android 的现代版本都原生支持 emoji 字体。移动端用户看到的 emoji 与桌面端一致。
多语言站点要不要关 wpemoji?
同样建议关。多语言不影响 emoji 渲染,emoji 是 Unicode 标准的一部分,与语言无关。
关闭后能否单独保留某些场景的 emoji 支持?
能。比如只在评论 RSS 里保留 emoji 转图:keep add_filter('comment_text_rss', 'wp_staticize_emoji'); 这一行不删。
WordPress 多站点(multisite)怎么统一关闭?
放 mu-plugin 是最优方案。multisite 网络下所有子站点共享 wp-content,mu-plugin 自动加载。
关闭 wpemoji 节省的字节数有多少?
每个页面 head 减少约 3.5 KB inline JS + 13 KB 外部 JS 请求。日均 1 万 PV 的站点每月省下约 4-5 GB 流量,CDN 费用减少。
主题更新后 functions.php 改动会丢吗?
会。建议用子主题(child theme)或 mu-plugin,主题更新不影响。
有没有插件能可视化管理 head 优化?
有。Disable Emojis、Clearfy、Perfmatters 等插件提供可视化开关。但插件本身有开销,简单需求建议直接代码实现。