搜索全站
主题 11 分钟阅读

主题演示内容里的外部资源拖慢速度:图片与外链字体替换

导入演示内容后站点变慢?本文讲清演示图片与外链字体两类外部资源的成本,给出字体本地化、图片批量替换、请求提前连接三步实操与验证方法。

U
UFO_PF 2024-05-24 · 阅读 11 分钟
主题 主题
阅读提示
本文约 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 字体加载优化 是同一条思路,本文聚焦在「演示内容残留」这个特定场景。

保姆级实操

  1. 列出全部外部请求:打开 PageSpeed Insights 或用浏览器开发者工具的 Network 面板,按域名分组,把不属于你自己域名的请求抄下来。这一步给出明确的清理清单。
  2. 停掉主题自带的 Google Fonts:用 wp_enqueue_scripts(优先级要高)配合 wp_dequeue_style / wp_deregister_style 摘掉主题注册的字体句柄。句柄名需要到主题代码里搜 googleapis 确认。
  3. 本地自托管字体:把字体文件(woff2)下载到主题目录,用 @font-face 声明,配合 font-display: swap 避免文字不可见。也可以直接用 OMGF 之类的插件自动完成。
  4. 兜底拦截:用 style_loader_src 过滤器把残留的 fonts.googleapis.com 请求改写到本地路径,防止主题某些位置漏网。
  5. 替换演示图片:用 WP-CLI 把演示图批量导入媒体库,再用 wp search-replace 把旧域名替换成自己的域名。注意备份数据库。
  6. 验证:重新跑 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,否则就是把慢资源缓存起来而已。

U
UFO_PF作者

专注 WordPress 生态的实战作者,内容以「可复制、可验证」为第一原则。

留下你的想法

邮箱地址不会被公开。带 * 的为必填项。