HarmonyOS APP开发---“图迹“旅行相册App,需要用到这个库
HarmonyOS APP开发—"图迹"旅行相册App,需要用到这个库
做一个旅行相册 App,用户上传的几百张旅途照片要瀑布流展示,点击大图要秒开。RN 自带 Image 没缓存、每次重新下载——
@react-native-ohos/react-native-fast-image的二级缓存 + 预加载,让相册体验追平原生。
📦 仓库地址:https://gitcode.com/CPF-RN/rntpc_react-native-fast-image | 安装:
npm install @react-native-ohos/react-native-fast-image
写在前面
“图迹"的核心体验是"滑到就看到”——用户打开某次旅行的相册,几十张照片瀑布流排列,滑到哪里哪里就秒出图。点开大图,几乎无延迟地全屏展示。
这对图片加载的要求极高:
- 缓存是刚需:滑过的图再滑回来不能重新下载,否则流量爆炸 + 体验卡顿
- 大图预加载:用户看缩略图时,大图已经在后台拉好了,点开即出
- 优先级:当前可见区域的图优先加载,不可见区域降级
RN 自带 Image 组件在鸿蒙上没有原生磁盘缓存,每次都要重新下载。react-native-fast-image 底层适配了 HarmonyOS 原生缓存引擎——内存缓存 + 磁盘缓存 + 优先级队列 + 预加载。
这篇文章聊什么
- 瀑布流加载——FastImage + FlatList 瀑布流
- 大图预加载——缩略图加载时预加载高清大图
- 优先级控制——可见区域优先、不可见区域降级
第一步:安装
npm install @react-native-ohos/react-native-fast-image
第二步:瀑布流照片列表
import FastImage from '@react-native-ohos/react-native-fast-image'
import { FlatList, View, Text, Dimensions } from 'react-native'
const { width } = Dimensions.get('window')
const COLUMN_WIDTH = (width - 24) / 2 // 两列瀑布流
interface Photo {
id: string
thumb: string // 缩略图 URL
full: string // 高清大图 URL
title: string
}
function PhotoCard({ photo }: { photo: Photo }) {
return (
<View style={{ width: COLUMN_WIDTH, marginBottom: 12 }}>
<FastImage
style={{ width: '100%', height: COLUMN_WIDTH * 1.3, borderRadius: 8 }}
source={{
uri: photo.thumb,
priority: FastImage.priority.normal,
cache: FastImage.cacheControl.immutable, // 永不重复下载
}}
resizeMode={FastImage.resizeMode.cover}
/>
<Text style={{ fontSize: 13, color: '#666', marginTop: 4 }}>{photo.title}</Text>
</View>
)
}
// 瀑布流列表
<FlatList
data={photos}
numColumns={2}
keyExtractor={(item) => item.id}
renderItem={({ item }) => <PhotoCard photo={item} />}
contentContainerStyle={{ padding: 12 }}
/>
cache: FastImage.cacheControl.immutable 是关键——图片 URL 不变就永不重新请求,旅行照片一旦上传就不会变,完美匹配这个策略。
第三步:大图预加载
用户在看缩略图列表时,提前把当前可见区域相邻的几张高清大图拉进缓存:
import { useEffect, useRef } from 'react'
function usePreloadFullImages(photos: Photo[], visibleStart: number, visibleEnd: number) {
useEffect(() => {
// 预加载当前可见区域 + 前后各 2 张的大图
const toPreload: Array<{ uri: string; priority: any }> = []
for (let i = Math.max(0, visibleStart - 2); i <= Math.min(photos.length - 1, visibleEnd + 2); i++) {
toPreload.push({
uri: photos[i].full,
priority: FastImage.priority.low, // 预加载用低优先级,不抢当前图
})
}
FastImage.preload(toPreload)
}, [visibleStart, visibleEnd])
}
预加载用 priority.low——不抢当前可见缩略图的带宽,等缩略图都加载完了再拉大图。
第四步:点击查看大图(秒开)
function FullScreenViewer({ photo, onClose }: { photo: Photo; onClose: () => void }) {
return (
<View style={{ flex: 1, backgroundColor: '#000' }}>
<FastImage
style={{ flex: 1 }}
source={{
uri: photo.full,
priority: FastImage.priority.high, // 大图用高优先级
cache: FastImage.cacheControl.immutable,
}}
resizeMode={FastImage.resizeMode.contain}
onLoad={(e) => {
console.log(`大图加载完成: ${e.nativeEvent.width}x${e.nativeEvent.height}`)
}}
/>
<TouchableOpacity onPress={onClose} style={{ position: 'absolute', top: 40, right: 20 }}>
<Text style={{ color: '#fff', fontSize: 18 }}>✕</Text>
</TouchableOpacity>
</View>
)
}
因为第三步已经预加载了大图,用户点击时缓存已命中,几乎零延迟秒开。
为什么"图迹"选了 FastImage?
| 需求 | RN Image | @react-native-ohos/react-native-fast-image |
|---|---|---|
| 磁盘缓存 | ❌ | ✅ 二级缓存 |
| 预加载 | ❌ | ✅ preload() |
| 优先级 | ❌ | ✅ low/normal/high |
| 缓存策略 | ❌ | ✅ immutable/web |
| 大图秒开 | ❌ 重新下载 | ✅ 预加载命中缓存 |
| 进度回调 | ❌ | ✅ onProgress |
总结
"图迹"这个场景里,@react-native-ohos/react-native-fast-image 解决了三件事:
- 缓存不重下——
immutable策略 + 二级缓存,滑过的图再滑回来秒出 - 大图秒开——缩略图加载时低优先级预加载大图,点击即出
- 优先级调度——可见区域 normal,预加载 low,大图查看 high,带宽合理分配
如果你也在做相册、电商、社交等大量图片的 RN 鸿蒙应用,react-native-fast-image 是性能体验的底线保障。
更多推荐




所有评论(0)