本文约 4,225 字,预计阅读 11 分钟。文中命令与配置均经过实测,可直接参考执行。
引言:一键导入演示站之后,网站从两秒变成八秒
「一键导入演示内容」是主题最诱人也最危险的功能。导入之后站点和演示站一模一样,视觉效果满分;但同时你也继承了演示站的全部外部依赖:几十张来自主题厂商 CDN 的高清演示图、来自 fonts.googleapis.com 的 Web Font、来自 cdn.jsdelivr.net 的动画库、甚至还有 YouTube 背景视频。国内访问这些域名,要么慢,要么直接超时。
表现很有特征:首屏文字出来了但背景图迟迟不出现(CLS 严重跳动);字体加载完成后整页文字「闪一下」换字形(FOUT);Lighthouse 评分从 90 掉到 40,PageSpeed Insights 里「消除渲染阻塞资源」一栏挂满外链。很多人的反应是换主机、上 CDN,方向完全错了——真正的瓶颈在页面里那几十个你根本不需要的外部请求。
原理分析:两类外部资源的成本构成
第一类是外链字体。 主题通常在 functions.php 里这样注册:wp_enqueue_style( 'theme-fonts', 'https://fonts.googleapis.com/css2?family=...' )。这条请求有两跳:先取 CSS,CSS 里再指向 fonts.gstatic.com 的字体文件。国内访问这段链路延迟高,且浏览器会阻塞渲染等待它,是典型的渲染阻塞资源。
第二类是演示图片。 导入演示内容时,图片 URL 往往是绝对地址,指向主题厂商的演示域名。这些图有几个问题:尺寸往往很大(1920 宽以上)、没有经过压缩、域名不可控、而且你无法给它们加自己的 CDN。
| 资源类型 | 典型来源 | 主要成本 | 处理优先级 |
|---|---|---|---|
| Google Fonts | fonts.googleapis.com / gstatic | 渲染阻塞、多一跳 | 最高 |
| 演示图片 | 主题厂商演示域名 | 体积大、域名不可控 | 高 |
| 演示视频 | YouTube / Vimeo 嵌入 | 首屏加载数 MB | 高 |
| 图标/动画库 | cdn.jsdelivr.net 等 | 额外 DNS + TLS | 中 |
| 统计/客服脚本 | 演示站遗留 | 隐私与性能 | 中 |
外链字体的处理有三条路:彻底停用(用系统字体栈替代)、本地自托管(把 woff2 下载到自己的服务器)、换成国内可访问的镜像。彻底停用性能最好但会改变设计;本地自托管兼顾效果与速度,是多数站点的选择。演示图片必须替换,而且要用「下载到自己媒体库 + 批量替换 URL」的方式,不能只改前台显示。
顺带一提,字体加载性能优化与 WordPress 字体加载优化 是同一条思路,本文聚焦在「演示内容残留」这个特定场景。
保姆级实操
- 列出全部外部请求:打开 PageSpeed Insights 或用浏览器开发者工具的 Network 面板,按域名分组,把不属于你自己域名的请求抄下来。这一步给出明确的清理清单。
- 停掉主题自带的 Google Fonts:用
wp_enqueue_scripts(优先级要高)配合wp_dequeue_style/wp_deregister_style摘掉主题注册的字体句柄。句柄名需要到主题代码里搜googleapis确认。 - 本地自托管字体:把字体文件(woff2)下载到主题目录,用
@font-face声明,配合font-display: swap避免文字不可见。也可以直接用 OMGF 之类的插件自动完成。 - 兜底拦截:用
style_loader_src过滤器把残留的fonts.googleapis.com请求改写到本地路径,防止主题某些位置漏网。 - 替换演示图片:用 WP-CLI 把演示图批量导入媒体库,再用
wp search-replace把旧域名替换成自己的域名。注意备份数据库。 - 验证:重新跑 PageSpeed Insights,确认「消除渲染阻塞资源」里不再有外部字体,且 CLS 指标下降。
<?php
// 子主题 functions.php:摘掉主题自带的 Google Fonts
add_action( 'wp_enqueue_scripts', function() {
// 句柄名需在主题里搜索 fonts.googleapis.com 确认
wp_dequeue_style( 'theme-google-fonts' );
wp_deregister_style( 'theme-google-fonts' );
// 换成自托管字体
wp_enqueue_style(
'mimangfei-local-fonts',
get_stylesheet_directory_uri() . '/assets/css/fonts.css',
array(),
'1.0.0'
);
}, 100 );
<?php
// 兜底:把残留的 Google Fonts 请求改为本地地址
add_filter( 'style_loader_src', function( $src ) {
if ( false !== strpos( $src, 'fonts.googleapis.com' ) ) {
return get_stylesheet_directory_uri() . '/assets/css/fonts.css';
}
return $src;
}, 20 );
/* assets/css/fonts.css:自托管字体 + font-display 避免文字闪烁 */
@font-face {
font-family: 'Inter';
src: url('../fonts/inter-latin-400.woff2') format('woff2');
font-weight: 400;
font-style: normal;
font-display: swap; /* 字体未就绪时先用后备字体显示,避免不可见 */
}
@font-face {
font-family: 'Inter';
src: url('../fonts/inter-latin-700.woff2') format('woff2');
font-weight: 700;
font-style: normal;
font-display: swap;
}
:root {
--font-body: 'Inter', -apple-system, "PingFang SC", "Microsoft YaHei", sans-serif;
}
body {
font-family: var(--font-body);
}
# 1. 备份数据库(必做)
wp db export backup-before-replace.sql
# 2. 把演示图批量导入自己的媒体库
wp media import https://demo.example.com/images/hero.jpg --title="首页主图"
# 3. 批量替换内容里的演示域名(先 dry-run 看影响行数)
wp search-replace 'https://demo.example.com/wp-content/uploads' \
'https://www.yoursite.com/wp-content/uploads' --dry-run
# 确认无误后去掉 --dry-run 执行,并跳过序列化字段之外的表
wp search-replace 'https://demo.example.com' 'https://www.yoursite.com' --skip-columns=guid
常见踩坑
- 只 dequeue 不 deregister:
wp_dequeue_style只取消本次输出,主题后续仍可能重新入队。两个一起调用更彻底。 - 优先级不够高:主题以 20 入队,你在 10 就去 dequeue,等于没摘。用 100 这种大优先级。
wp search-replace直接改guid字段:guid是永久标识,改了会导致 RSS 阅读器重复推送。加--skip-columns=guid。- 替换前不备份:序列化数据(小工具、主题选项)替换出错会导致设置全丢,必须
wp db export先备份。 - 导入图片后没有重新生成缩略图:媒体库里的图缺少各尺寸副本,前台仍拉原图。用「媒体 → 重新生成缩略图」或
wp media regenerate。 - 案例:一个外贸站导入演示内容后,PageSpeed 移动端评分 38 分,CLS 高达 0.42。排查发现:页面加载了 4 个 Google Fonts 字重(总计 6 个外部请求),首屏大图来自厂商演示域名且为 2560px 宽的 JPEG。按本文处理——停用外链字体改为自托管(只保留 2 个字重)、演示图下载后压缩到 1600px 并转 WebP、给首屏图补上明确的宽高属性——评分回到 82,CLS 降到 0.05。关键不是换主机,而是把不属于你的请求从页面里拿掉。
- 替换后前台仍有外链:主题选项、构建器数据、小工具里都可能硬编码了演示 URL,替换时要覆盖这些表,做法可参考
WordPress 批量替换内容方法。
总结
导入演示内容后必须做的清理清单:① 摘掉外链字体并自托管;② 把演示图片下载到本地媒体库并批量替换 URL;③ 删除演示视频、演示统计代码与社交脚本;④ 给首屏图片补上宽高属性;⑤ 重新生成缩略图。判断标准很简单:Network 面板里除了你自己的域名和必需的统计/客服脚本,不应出现主题厂商的域名。这一步做完再谈缓存和 CDN,否则就是把慢资源缓存起来而已。
