如何实现类似WhatsApp头像加载时先展示模糊占位图的效果?
实现类WhatsApp模糊占位头像加载效果的方案
这种效果本质是低质量图像占位(LQIP, Low Quality Image Placeholders)方案,也是渐进式图片加载的常用实现,具体落地分为服务端和前端/客户端两部分:
1. 服务端前置准备
- 提前为所有头像生成20x20px以内的极低分辨率缩略图,压缩质量调整到10%-20%,最终体积控制在1KB以下,直接转成base64字符串存在用户基础信息库中,随用户信息接口一同返回,不需要单独发起资源请求。
2. Web端实现逻辑
核心思路
- 先渲染固定尺寸的头像容器,默认背景设置为接口返回的低清base64缩略图,给容器加模糊滤镜和轻微放大,避免模糊后边缘出现白边。
- 后台异步加载高清原图,等原图加载完成后替换容器背景,同时移除模糊滤镜,配合过渡动画实现平滑切换。
代码示例
.avatar { width: 64px; height: 64px; border-radius: 50%; overflow: hidden; background-size: cover; background-position: center; /* 占位状态样式 */ filter: blur(8px); transform: scale(1.1); transition: filter 0.3s ease, transform 0.3s ease; } .avatar.loaded { /* 加载完成状态样式 */ filter: blur(0); transform: scale(1); }
// 调用参数:头像DOM节点、低清base64、高清图地址 function initAvatar(avatarDom, lqipBase64, hdUrl) { // 先设置低清占位 avatarDom.style.backgroundImage = `url(${lqipBase64})`; // 异步加载高清图 const hdImg = new Image(); hdImg.src = hdUrl; hdImg.onload = () => { // 加载完成后替换资源、切换状态 avatarDom.style.backgroundImage = `url(${hdUrl})`; avatarDom.classList.add('loaded'); }; }
3. 移动端实现逻辑
安卓、iOS端逻辑和Web端完全一致:
- 先把接口返回的低清缩略图转成Bitmap设置到ImageView,同时添加系统自带的模糊效果(安卓用RenderScript实现,iOS用CoreImage的CIBlur滤镜实现)。
- 异步请求高清原图,请求成功后替换ImageView内容,同时添加0.3s左右的淡入过渡动画即可。
可选优化点
- 如果不想提前生成低清缩略图,可以提取原图主色作为纯色占位,或者生成简单的轮廓SVG占位,视觉过渡效果同样顺滑。
- 对已经加载完成的高清头像做本地缓存,下次展示时直接调用缓存资源,不需要再走占位逻辑。
内容的提问来源于stack exchange,提问作者Harsh Patel
相关产品推荐
相关产品推荐

