blur-up核心HTML结构为,需分离占位图与高清图路径,确保src≤2KB、data-src不参与初始请求。

直接用 img 标签加 JS 监听加载 + CSS 过渡就能实现,不需要框架或复杂构建流程。关键不是“怎么写”,而是“怎么避免两次请求白屏、怎么控制模糊时机、怎么兼容懒加载”。
blur-up 的核心 HTML 结构怎么写
必须分离「占位图」和「高清图」的加载路径,否则浏览器会提前预加载 src 导致失效。
-
src放极小尺寸图(如thumb-20x15.jpg),确保体积 ≤ 2 KB;不能是 base64(部分 iOS Safari 对长 base64 解码卡顿) - 高清图地址存进
data-src,不参与初始请求 - 加
class="blur-up"控制样式,加载完成再移除 - 如果配合懒加载,
loading="lazy"只能加在占位图上——否则高清图可能被提前 fetch
示例:
<img src="photo-thumb.jpg" class="blur-up" alt="风景" loading="lazy" />
CSS 模糊过渡为什么经常失效
常见问题不是代码写错,而是 blur 和 scale 同时触发导致渲染冲突,或 transition 没绑定到正确状态。
立即学习“前端免费学习笔记(深入)”;
- 必须用
filter: blur(20px)+transform: scale(1.1)组合,单用 blur 容易出现边缘锯齿 -
transition要写全:只写transition: filter 400ms不够,得加上transform,否则 scale 突变 - 加载完成后要同时移除
blur-up类并设置filter: none; transform: none;,否则某些安卓 WebView 会残留模糊态 - 别对父容器设
overflow: hidden——它会裁掉 blur 溢出区域,在 Safari 中表现为“突然清晰”,失去渐进感
JS 加载逻辑怎么防崩
不能只依赖 img.onload,它不保证图像已解码完成;也不能在 IntersectionObserver 回调里直接赋值 src,否则可能触发竞态。
- 推荐用
img.decode()+Promise封装:等解码完成再替换 DOM,避免闪动 - 监听
error事件并 fallback 到占位图,否则网络失败时留白 - 如果页面有多个 blur-up 图,建议节流
decode调用,防止低端机卡顿(尤其 Android 旧版 Chrome) - 慎用
requestIdleCallback延迟执行——它可能被系统丢弃,导致图片长期不加载
简易可靠片段:
const img = document.querySelector('img.blur-up');
img.addEventListener('load', () => {
img.decode().then(() => {
img.classList.remove('blur-up');
}).catch(() => {
img.src = img.dataset.src;
});
});
和现代 lazy loading 共存要注意什么
Chrome 76+ 原生 loading="lazy" 和 blur-up 是正交能力,但默认行为会干扰加载顺序。
- 原生 lazy 仅对
src生效,所以高清图必须用data-src,否则会被提前拉取 - Safari 目前不支持
loading="lazy"对 background-image 或picture的懒加载,blur-up 是更稳妥的选择 - 如果用了
IntersectionObserver手动控制,记得在isIntersecting为 true 时才调用img.src = img.dataset.src,否则滚动过快时会漏掉 - 服务端渲染(SSR)场景下,首次 HTML 必须包含占位图
src,否则爬虫看不到图,SEO 掉权
最常被忽略的一点:blur-up 的视觉价值只在「首屏不可见图」上成立。首屏关键图建议直接用渐进式 JPEG,而不是 JS 驱动的 blur-up——后者多一次 JS 解析、多一次 HTTP 请求、多一次重绘,纯亏性能。



















