我的网站使用了AeroCore主题,发现文章页和列表页有很多图片,都用上了懒加载,包括首屏幕,但首屏幕使用懒加载会影响LCP。
我还用了几个第三方脚本和样式。结果也让首屏加载很慢。LCP 得分也不高。然后我写了一段 PHP 代码。这段代码包含四个部分。
第一部分设置图片的 eager 和 lazy 加载。第二部分给脚本加 defer。第三部分异步加载非关键 CSS。第四部分添加 preconnect。我将代码放到了主题functions.php 文件开头,这个方法提高了首屏加载速度。
PageSpeed Insights的测试效果:


不过这个方案目前不完善,对于部分服务器可能存在性能问题,大家可以酌情参考,我还在研究更高效的方案。
保留functions.php文件中原有代码
<?php
if (!defined('ABSPATH')) exit;
$fun_file = __DIR__ . '/fun.php';
if (is_file($fun_file)) {
require_once $fun_file;
}
1.图片加载优化:动态设置 Eager 和 Lazy
这段代码识别内容图片。它只处理 /wp-content/uploads/ 下的图片。它排除头像、Logo 和备案图标。然后它根据页面类型决定 eager 图片数量。首页、归档页和搜索页是 5 张。文章页是 2 张。其他页面是 3 张。第一张 eager 图片加 fetchpriority="high"。其余图片加 eager 或 lazy。所有图片都加 decoding="async"。这样首屏图片优先加载,LCP 变快。
// 图片加载优化
add_action('template_redirect', function () {
if (is_admin() || wp_doing_ajax() || (defined('REST_REQUEST') && REST_REQUEST)) return;
ob_start('meow_filter_images_by_page');
}, 0);
function meow_filter_images_by_page($html) {
if (stripos($html, '<img') === false) return $html;
$eager_count = meow_get_eager_count();
$is_content_img = function ($tag, &$src_out) {
$src_out = '';
if (!preg_match('/src=["\']([^"\']+)["\']/i', $tag, $s)) return false;
$src = html_entity_decode($s[1], ENT_QUOTES);
if (strpos($src, '/wp-content/uploads/') === false) return false;
if (stripos($src, 'weavatar.com') !== false) return false;
if (stripos($src, 'gravatar.com') !== false) return false;
if (preg_match('/\/(icp|police)\./i', $src)) return false;
if (preg_match('/\bclass=["\']([^"\']*)/i', $tag, $c)) {
$cls = strtolower($c[1]);
foreach (['site-logo', 'avatar', 'trp-flag', 'logo-', 'gravatar'] as $skip) {
if (strpos($cls, $skip) !== false) return false;
}
}
$src_out = $src;
return true;
};
$i = 0;
$html = preg_replace_callback('/<img\b[^>]*>/i', function ($m) use ($is_content_img, $eager_count, &$i) {
$tag = $m[0];
$src = '';
if (!$is_content_img($tag, $src)) return $tag;
$i++;
$tag = preg_replace('/\s+(loading|decoding|fetchpriority)=["\'][^"\']*["\']/i', '', $tag);
if ($i <= $eager_count) {
if ($i === 1) {
$tag = preg_replace('/<img\b/i', '<img fetchpriority="high" loading="eager" decoding="async"', $tag, 1);
} else {
$tag = preg_replace('/<img\b/i', '<img loading="eager" decoding="async"', $tag, 1);
}
} else {
$tag = preg_replace('/<img\b/i', '<img loading="lazy" decoding="async"', $tag, 1);
}
return $tag;
}, $html);
return $html;
}
function meow_get_eager_count() {
if (is_front_page() || is_home() || is_tag() || is_category() || is_author()) {
return (int) apply_filters('meow_archive_eager_count', 5);
}
if (is_search()) {
return (int) apply_filters('meow_search_eager_count', 5);
}
if (is_single()) {
return 2;
}
return (int) apply_filters('meow_default_eager_count', 3);
}
2.JS Defer:让脚本不阻塞渲染
这段代码给前端脚本加 defer 属性。它排除 jQuery 和 jQuery 迁移脚本。因为很多主题用 $() 内联调用。脚本加上 defer 后,浏览器会继续解析 HTML。这样首屏渲染不被 JavaScript 阻塞。LCP 时间会变短。
// JS defer
add_filter('script_loader_tag', function ($tag, $handle, $src) {
if (is_admin()) return $tag;
$exclude = ['jquery', 'jquery-core', 'jquery-migrate'];
if (in_array($handle, $exclude, true)) return $tag;
if (strpos($tag, ' defer') !== false || strpos($tag, ' async') !== false) return $tag;
return str_replace(' src=', ' defer src=', $tag);
}, 10, 3);
3.非关键 CSS 异步加载:减少渲染阻塞
这段代码找到三个非关键样式表。它们不是首屏必需的。代码使用 preload 和 onload 异步加载这些 CSS。不支持 JavaScript 的浏览器使用 noscript 加载。这样浏览器不会等待这些样式表。首屏渲染更快。
// 非关键 CSS 异步
add_filter('style_loader_tag', function ($html, $handle, $href) {
if (is_admin()) return $html;
$async = [
'trp-language-switcher-v2.css',
'bbhcuschma-style.css',
'perf_metrics/style.css',
];
foreach ($async as $p) {
if (strpos($href, $p) !== false) {
return '<link rel="preload" as="style" href="' . esc_url($href)
. '" onload="this.rel=\'stylesheet\'">'
. '<noscript><link rel="stylesheet" href="' . esc_url($href) . '"></noscript>';
}
}
return $html;
}, 10, 3);
4.Preconnect:提前连接第三方域名
这段代码添加三个 preconnect 提示。浏览器提前连接统计、标签管理和头像服务。当页面需要请求这些资源时,连接已经建立。这样后续请求的延迟降低。整体页面加载速度提高。
// preconnect
add_action('wp_head', function () {
echo '<link rel="preconnect" href="https://cloud.umami.is" crossorigin>' . "\n";
echo '<link rel="preconnect" href="https://www.googletagmanager.com" crossorigin>' . "\n";
echo '<link rel="preconnect" href="https://weavatar.com" crossorigin>' . "\n";
}, 1);