搜索全站
性能优化 9 分钟阅读

WordPress 图片懒加载怎么选:原生 loading 属性优于插件

懒加载插件反而拖慢首屏?本文对比原生 loading 属性与 JS 懒加载插件的实现差异,讲清为什么首屏图必须排除,并给出可直接用的排除代码与验证方法。

U
UFO_PF 2022-03-13 · 阅读 9 分钟
Wo 性能优化
阅读提示
本文约 3,554 字,预计阅读 9 分钟。文中命令与配置均经过实测,可直接参考执行。

引言:为了提速装的插件,可能正是拖慢首屏的原因

「给站点加个懒加载」几乎成了性能优化的标配动作。但不少人在装完懒加载插件后发现,PageSpeed Insights 分数没涨反跌,还多了一条刺眼的提示:Largest Contentful Paint 图片被延迟加载了。原因是,很多懒加载插件的工作方式是「把 src 换成占位符,滚动到视口附近再用 JS 写回真实地址」。对首屏那张最大的图来说,这套流程意味着浏览器必须先下载并执行 JS,才知道要去下载图片——白白多了一个往返。

而原生的 loading="lazy" 完全不是这个逻辑。它由浏览器在布局阶段直接决策,不依赖任何脚本,首屏之外的图片会被推迟,首屏之内的图片正常加载。WordPress 从 5.5 起已经默认给内容里的图片加上这个属性,换句话说,大多数站点根本不需要再装懒加载插件。

原理分析:两种实现路径的差异

WordPress 5.5 引入的懒加载发生在内容输出阶段:wp_filter_content_tags() 会遍历正文里的 img 标签,通过 wp_img_tag_add_loading_attr() 为其添加 loading="lazy",同时加上 decoding="async" 提升解码效率。整个过程在服务端完成,输出的 HTML 里就已经带上了属性,浏览器拿到即可生效。

维度 原生 loading="lazy" JS 懒加载插件
触发方式 浏览器原生调度 监听滚动 + JS 改写 src
是否依赖 JS 否 是,脚本失败则图片不显示
首屏风险 由开发者控制排除 容易把首屏图一并延迟
爬虫可见性 HTML 里有真实 src 只有 data-src,需 noscript 兜底
额外开销 近乎为零 需加载一个 JS 文件

关键点在于:原生方案是「默认全部懒加载,需要你主动排除首屏」。WordPress 并没有智能到能判断哪张图在首屏,它会给所有正文图片都加上 loading="lazy",包括第一张。因此使用原生方案时,你的核心工作从「装插件」变成了「把首屏图排除掉」。

具体钩子有三个,作用各不相同:wp_lazy_loading_enabled 控制某个标签是否启用懒加载(默认针对 img、iframe),wp_img_tag_add_loading_attr 可以修改最终写入的属性值,wp_get_attachment_image_attributes 则用于在输出附件图片时直接指定属性。

保姆级实操:把懒加载交给浏览器

步骤1:确认站点当前是谁在做懒加载。 打开前台页面源码,搜索 loading= 和 data-src。如果同时看到两者,说明原生和插件在重复工作,先关掉插件的懒加载功能(很多插件的设置页里就叫「Lazy Load」或「延期加载图片」)。

步骤2:全局梳理,只保留一种方案。 若主题或某些插件强制注入 JS 懒加载,可以在主题里直接关掉原生方案做对照测试,但更推荐的做法是反过来——保留原生,停用插件。

<?php
// 极端情况下才用:彻底关闭 WordPress 原生懒加载
add_filter( 'wp_lazy_loading_enabled', '__return_false' );

步骤3:让首屏图片立即加载。 这一步是提升 LCP 的关键。对特色图、首屏 banner,显式声明 loading="eager" 与 fetchpriority="high",让浏览器把它排进最高优先级。

<?php
// 主题模板中输出特色图时指定加载属性
echo wp_get_attachment_image( get_post_thumbnail_id(), 'large', false, array(
    'loading'       => 'eager',
    'fetchpriority' => 'high',
    'decoding'      => 'sync',
) );

步骤4:把正文里的第一张图从懒加载中摘出来。 下面的过滤器只对正文(the_content 上下文)生效,把第一张出现的图片改成立即加载,其余保持懒加载。

<?php
// 正文第一张图不做懒加载,避免 LCP 被推迟
add_filter( 'wp_img_tag_add_loading_attr', function ( $value, $image, $context ) {
    static $first_done = false;
    if ( 'the_content' === $context && ! $first_done ) {
        $first_done = true;
        return 'eager';
    }
    return $value;
}, 10, 3 );

步骤5:处理 iframe 与视频。 嵌入的地图、YouTube 播放器同样会拖慢首屏。原生方案对 iframe 也生效,更好的做法是使用「封面图 + 点击加载」的 facade 方案,把几十 KB 的封面换成几百 KB 的播放器资源。

步骤6:给懒加载图片补齐尺寸属性。 懒加载本身不产生 CLS,但缺 width/height 会。WordPress 通常会自动补上,若用了自定义 HTML 模块,请手动写明,或用 CSS aspect-ratio 占位。

/* 为懒加载图片预留空间,避免布局跳动 */
.entry-content img {
    max-width: 100%;
    height: auto;
    aspect-ratio: attr(width) / attr(height);
}

步骤7:验证结果。 用 Chrome DevTools 的 Network 面板滚动页面,观察图片请求的发起时机;再跑一次 Lighthouse,重点看是否还有「Largest Contentful Paint image was lazily loaded」这条审计项。

常见踩坑

  1. 首屏图被懒加载是最常见的错误,表现就是 LCP 时间莫名多出几百毫秒。用上面的步骤3、步骤4 处理。
  2. 两套懒加载叠加。插件把 src 换成占位符,原生的 loading="lazy" 又加在占位图上,结果是图片永远不加载——页面滚动到底还是灰块。
  3. noscript 缺失影响收录。JS 方案下爬虫只能看到 data-src,Google 图片搜索可能抓不到图。原生方案不存在这个问题,这也是推荐它的重要原因之一。
  4. 页面缓存把改写后的 HTML 缓存死。使用 JS 方案时,如果缓存插件缓存了「尚未加载」状态的 HTML,用户可能拿到不完整的页面。
  5. 懒加载救不了尺寸问题。一张 2560px 的图即便懒加载,滚动到它时依然要下载完整体积。真正的解法是配合 srcset 输出合适尺寸,这一点在用插件实现图片 CDN 加速与自适应尺寸里有详细说明。
  6. 案例:某企业站启用某缓存插件自带的懒加载后,首页轮播首图被换成了 1×1 灰色占位 SVG,LCP 从 1.9s 恶化到 4.3s,客户反馈「首页打开一片灰」。排查时先用源码确认存在 data-src,再在插件设置里把「Skip first images」设为 2,最后干脆停用插件懒加载、改用原生属性并把首图设为 eager,LCP 回落到 1.4s。
  7. loading="lazy" 在极老的 Safari 上不生效,但会安全降级为立即加载(不会导致图片不显示),这是原生方案相对 JS 方案的又一个优势。
  8. 后台编辑器里的图片也会被加属性。若在后台发现异常,可用 wp_lazy_loading_enabled 按上下文判断跳过。

总结

选型结论很明确:能用原生 loading="lazy" 就不要再装 JS 懒加载插件。原生方案零脚本开销、爬虫可见、失败可降级,唯一需要你动手的是「把首屏那几张图摘出来」。行动清单:停用插件懒加载 → 确认源码里只有 loading= 没有 data-src → 首图设 eager + fetchpriority="high" → 补齐宽高 → 用 Lighthouse 复核。做完这五步,懒加载这块基本不会再出问题。若你还想进一步压缩图片体积,可先看ShortPixel/Imagify/Smush 图片压缩插件对比。

U
UFO_PF作者

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

留下你的想法

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