如何使用react-native-blurhash实现图片加载模糊占位效果?
用react-native-blurhash替换图片加载占位的ActivityIndicator
核心逻辑说明
Blurhash的核心是提前生成图片的哈希字符串,客户端仅负责解码渲染。不建议在客户端实时编码图片(性能开销大),需先让后端对每个feed图片生成对应的blurhash值,作为props传递给Card组件。
1. 安装依赖
先安装react-native-blurhash包:
npm install react-native-blurhash # 或 yarn add react-native-blurhash
iOS项目需额外执行cd ios && pod install,Android项目无需额外配置。
2. 修改Card组件代码
替换原ActivityIndicator为Blurhash组件,调整加载状态逻辑:
import React, { useState, useMemo } from 'react'; import { Text, View, StyleSheet } from 'react-native'; import FastImage from 'react-native-fast-image'; import { Blurhash } from 'react-native-blurhash'; const Card = ({ username, feedImage, blurhash }) => { const [isLoading, setIsLoading] = useState(true); const source = useMemo(() => ({ uri: feedImage }), [feedImage]); return ( <View style={styles.container}> <View style={styles.c1}> <Text style={styles.username}>{username}</Text> </View> <View style={styles.imageContainer}> {/* Blurhash作为加载占位 */} {isLoading && ( <Blurhash hash={blurhash} style={styles.image} decodeWidth={32} decodeHeight={32} decodeAsync={true} /> )} <FastImage source={source} style={styles.image} onLoadEnd={() => setIsLoading(false)} /> </View> </View> ); }; const styles = StyleSheet.create({ container: { marginBottom: 16, borderRadius: 8, overflow: 'hidden', backgroundColor: '#f0f0f0', }, c1: { padding: 12, flexDirection: 'row', alignItems: 'center', }, username: { fontSize: 14, fontWeight: '500', }, imageContainer: { position: 'relative', width: '100%', aspectRatio: 1, // 根据你的图片比例调整 }, image: { position: 'absolute', top: 0, left: 0, width: '100%', height: '100%', }, }); export default Card;
关键细节说明
- Blurhash参数:
hash:后端生成的图片哈希字符串,必须传入decodeWidth/decodeHeight:解码分辨率,数值越小渲染越快、模糊效果越强decodeAsync:开启异步解码,避免阻塞UI线程
- 样式处理:将Blurhash和FastImage设为绝对定位,尺寸与容器一致,加载完成后FastImage会覆盖Blurhash,实现平滑过渡
- 移除顶部ActivityIndicator:顶部加载指示器无保留必要,用户名可直接显示,不影响体验
本地测试编码方法
若需临时生成测试用blurhash,可在Node.js环境用blurhash包编码:
npm install blurhash sharp
编写脚本生成:
const { encode } = require('blurhash'); const fs = require('fs'); const path = require('path'); const sharp = require('sharp'); async function generateBlurhash(imagePath) { const image = await sharp(imagePath).raw().toBuffer(); const { width, height } = await sharp(imagePath).metadata(); const hash = encode(new Uint8ClampedArray(image), width, height, 4, 4); console.log(hash); } generateBlurhash(path.join(__dirname, 'test-image.jpg'));
注意:生产环境务必在后端完成编码,避免客户端处理图片的性能损耗。
内容的提问来源于stack exchange,提问作者user21409384
相关产品推荐
相关产品推荐

