HTML怎么设置图像懒加载占位符_HTML loading skeleton效果教程【性能】

9次阅读

html原生loading属性仅控制加载时机,不提供占位逻辑,需手动实现骨架屏并配合js监听图片加载完成状态来切换显隐。

HTML怎么设置图像懒加载占位符_HTML loading skeleton效果教程【性能】

HTML原生loading属性不支持自定义占位符

浏览器原生的 loading="lazy" 只控制加载时机,不提供任何占位逻辑——它不会自动显示骨架屏、灰色方块或 loading 动画。所谓“懒加载占位符”,其实是你手动实现的视觉层 + 原生加载机制的组合。

常见错误现象:<img src="a.jpg" loading="lazy" alt=""> 在图片未加载时显示空白或塌陷布局,用户感知卡顿甚至误以为失败。

  • 必须自己写占位结构(比如 <div class="skeleton"></div>),再配合 CSS 控制显隐
  • 不能依赖 loading 属性触发占位逻辑,它只影响 fetch 行为,不发事件、不改 dom 状态
  • 若用 IntersectionObserver 手动控制加载,才可能同步更新占位状态;但此时已绕过原生 loading

CSS骨架屏占位要避免布局偏移(layout shift)

骨架屏本质是用纯色块模拟图像尺寸,一旦尺寸不准,图片加载后会把下方内容往下推,触发布局抖动(CLS 指标恶化)。这不是样式“不好看”的问题,而是核心性能指标受损。

  • 占位容器必须有明确宽高(推荐用 aspect-ratiopadding-bottom 百分比方案)
  • 禁用 width: 100%; height: auto 这类依赖内容撑开的写法
  • 如果图宽高不确定,宁可用固定比例(如 aspect-ratio: 4/3)也不留空高
  • 骨架元素建议用 background-color + border-radius 模拟,别用 SVG 占位(体积大、渲染慢)

示例:一个安全的响应式占位容器

立即学习前端免费学习笔记(深入)”;

<div class="img-placeholder" style="aspect-ratio: 16/9; background: #f0f0f0;">   @@##@@ </div>  .img-placeholder img {   width: 100%;   height: 100%;   object-fit: cover;   opacity: 0;   transition: opacity 0.2s; } .img-placeholder img.loaded { opacity: 1; }

监听图片加载完成并切换占位状态得靠onloaddecode()

仅靠 CSS 和 HTML 无法知道图片何时真正可渲染。想让骨架屏在图就绪时淡出,必须介入 JS 生命周期。但要注意:直接绑 onload<img src="real.jpg" loading="lazy" alt="..."> 上,对缓存命中或 Error 状态覆盖不全。

  • 优先用 img.decode()(返回 promise),它确保图像解码完成,比 onload 更可靠
  • 必须同时监听 onerror,否则加载失败时骨架屏永远不消失
  • 不要在 IntersectionObserver 回调里直接设置 src 后就认为“已加载”——那只是开始请求,不是完成
  • 服务端渲染(SSR)场景下,需在客户端补监听,否则首屏骨架不消失

简短实操示意:

const img = document.querySelector('img'); img.addEventListener('load', () => img.classList.add('loaded')); img.addEventListener('error', () => img.classList.add('failed')); // 或更稳一点: img.decode().then(() => img.classList.add('loaded')).catch(() => img.classList.add('failed'));

第三方库如lazysizes默认也不带骨架屏

lazysizeslozad.js 这些懒加载库,专注解决资源延迟加载和 IntersectionObserver 封装,它们不处理视觉占位。所谓“集成骨架屏”,全是项目里自己叠加的 CSS + JS 逻辑。

  • 引入 lazysizes 后仍需手动加 data-src、占位 div、状态 class 和切换逻辑
  • 有些插件(如 lazysizes/plugins/unveilhooks/ls.unveilhooks.min.js)能帮你触发自定义钩子,但骨架显隐仍是你要写的
  • 若用 React/Vue,组件库里的 Suspensev-lazy 同样不内置骨架——那是 ui 框架层该做的事

最容易被忽略的一点:占位逻辑和懒加载逻辑要共用同一套“是否进入视口”的判断依据,否则会出现“图还没进视口,骨架先消失了”这种错乱。

HTML怎么设置图像懒加载占位符_HTML loading skeleton效果教程【性能】

text=ZqhQzanResources