react-native-fast-image 8.30.1 → 8.31.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +460 -210
- package/android/build.gradle +13 -1
- package/android/src/glide-4.15/java/com/dylanvann/fastimage/FastImageAnimated.java +2 -2
- package/android/src/main/java/com/dylanvann/fastimage/FastImageApng.java +2 -2
- package/android/src/main/java/com/dylanvann/fastimage/FastImageGif.java +1 -1
- package/android/src/main/java/com/dylanvann/fastimage/FastImageGlide.java +76 -0
- package/android/src/main/java/com/dylanvann/fastimage/FastImageGlideModule.java +1 -0
- package/android/src/main/java/com/dylanvann/fastimage/FastImageOkHttpProgressGlideModule.java +25 -51
- package/android/src/main/java/com/dylanvann/fastimage/FastImageRequestListener.java +1 -2
- package/android/src/main/java/com/dylanvann/fastimage/FastImageSource.java +1 -1
- package/android/src/main/java/com/dylanvann/fastimage/FastImageSourceSize.java +1 -1
- package/android/src/main/java/com/dylanvann/fastimage/FastImageSvg.java +2 -0
- package/android/src/main/java/com/dylanvann/fastimage/FastImageUrl.java +36 -0
- package/android/src/main/java/com/dylanvann/fastimage/FastImageViewConverter.java +2 -1
- package/android/src/main/java/com/dylanvann/fastimage/FastImageViewManager.java +1 -0
- package/android/src/main/java/com/dylanvann/fastimage/FastImageViewModule.java +13 -10
- package/android/src/main/java/com/dylanvann/fastimage/FastImageWebGlideUrl.java +1 -0
- package/app.plugin.js +1 -1
- package/dist/index.d.ts +358 -63
- package/ios/FastImage/FFFAnimatedAVIFCoder.h +11 -0
- package/ios/FastImage/FFFAnimatedAVIFCoder.m +103 -0
- package/ios/FastImage/FFFastImageSource.h +4 -0
- package/ios/FastImage/FFFastImageSource.m +36 -2
- package/ios/FastImage/FFFastImageViewManager.m +1 -2
- package/package.json +4 -2
package/README.md
CHANGED
|
@@ -1,70 +1,65 @@
|
|
|
1
|
-
|
|
2
|
-
React Native Fast Image
|
|
3
|
-
</h1>
|
|
4
|
-
|
|
5
|
-
<div align="center">
|
|
1
|
+
# React Native Fast Image
|
|
6
2
|
|
|
7
3
|
Performant React Native image component.
|
|
8
4
|
|
|
9
5
|
[![Version][version-badge]][package]
|
|
10
6
|
[![Downloads][downloads-badge]][npmtrends]
|
|
11
7
|
[![Build Status][build-badge]][build]
|
|
8
|
+
[![Docs][docs-badge]][docs]
|
|
12
9
|
|
|
13
|
-
|
|
14
|
-
[![Star on GitHub][github-star-badge]][github-star]
|
|
15
|
-
[![Tweet][twitter-badge]][twitter]
|
|
16
|
-
|
|
17
|
-
</div>
|
|
18
|
-
|
|
19
|
-
<p align="center" >
|
|
20
|
-
<kbd>
|
|
21
|
-
<img
|
|
22
|
-
src="https://github.com/DylanVann/react-native-fast-image/blob/main/docs/assets/scroll.gif?raw=true"
|
|
23
|
-
title="Scroll Demo"
|
|
24
|
-
float="left"
|
|
25
|
-
>
|
|
26
|
-
</kbd>
|
|
27
|
-
<kbd>
|
|
28
|
-
<img
|
|
29
|
-
src="https://github.com/DylanVann/react-native-fast-image/blob/main/docs/assets/priority.gif?raw=true"
|
|
30
|
-
title="Priority Demo"
|
|
31
|
-
float="left"
|
|
32
|
-
>
|
|
33
|
-
</kbd>
|
|
34
|
-
<br>
|
|
35
|
-
<em>FastImage example app.</em>
|
|
36
|
-
</p>
|
|
37
|
-
|
|
38
|
-
React Native's `Image` component handles image caching like browsers
|
|
39
|
-
for the most part.
|
|
40
|
-
If the server is returning proper cache control
|
|
41
|
-
headers for images you'll generally get the sort of built in
|
|
42
|
-
caching behavior you'd have in a browser.
|
|
43
|
-
Even so many people have noticed:
|
|
10
|
+
React Native's `Image` component handles image caching like browsers for the most part. If the server is returning proper cache control headers for images you'll generally get the sort of built in caching behavior you'd have in a browser. Even so, many people have noticed:
|
|
44
11
|
|
|
45
12
|
- Flickering.
|
|
46
13
|
- Cache misses.
|
|
47
14
|
- Low performance loading from cache.
|
|
48
15
|
- Low performance in general.
|
|
49
16
|
|
|
50
|
-
`FastImage` is an `Image` replacement that solves these issues.
|
|
51
|
-
`FastImage` is a wrapper around
|
|
52
|
-
[SDWebImage (iOS)](https://github.com/rs/SDWebImage)
|
|
53
|
-
and
|
|
54
|
-
[Glide (Android)](https://github.com/bumptech/glide).
|
|
17
|
+
`FastImage` is an `Image` replacement that solves these issues. `FastImage` is a wrapper around [SDWebImage (iOS)](https://github.com/SDWebImage/SDWebImage) and [Glide (Android)](https://github.com/bumptech/glide).
|
|
55
18
|
|
|
56
19
|
## Features
|
|
57
20
|
|
|
58
|
-
- [
|
|
59
|
-
- [
|
|
60
|
-
- [
|
|
61
|
-
- [
|
|
62
|
-
- [
|
|
63
|
-
- [
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
21
|
+
- **Performance**, with images [decoded at the size they're shown](#downsample): in [benchmarks](docs/benchmarks.md), FastImage shows images about as fast as other React Native image components and uses among the least memory for large photos.
|
|
22
|
+
- **Aggressive caching**: an image downloads once, then shows from disk or memory until its url changes, without flickering ([freshness](#sourcecache), [cache keys](#sourcecachekey), [size limits](#configurecachelimits)).
|
|
23
|
+
- **Preloading**, with a [result per image](#preloadsources) and the [cached file's path](#getcachepathsource).
|
|
24
|
+
- **Headers**, e.g. for authentication ([`headers`](#sourceheaders)).
|
|
25
|
+
- **Priorities** for which images load first ([`priority`](#sourcepriority)).
|
|
26
|
+
- **Responsive images**: give several sizes, and the one that fits the view loads ([`source`](#source)).
|
|
27
|
+
- **Animated images** (GIF, WebP, APNG and AVIF) that can [loop](#loop) and [pause](#paused).
|
|
28
|
+
- **Fades** in and between images ([`transition`](#transition)).
|
|
29
|
+
- [**SVG**](docs/formats.md#svg-images) and [**photo library**](#photo-library-images-ios) images.
|
|
30
|
+
- [**`FastImageBackground`**](#fastimagebackground) for content over an image.
|
|
31
|
+
- **Expo and web support**, with a [config plugin](#expo-config-plugin) for Expo.
|
|
32
|
+
|
|
33
|
+
## Image formats
|
|
34
|
+
|
|
35
|
+
| Format | iOS | Android |
|
|
36
|
+
| ------ | :---------------: | :---------------: |
|
|
37
|
+
| JPEG | ![Yes][yes] | ![Yes][yes] |
|
|
38
|
+
| PNG | ![Yes][yes] | ![Yes][yes] |
|
|
39
|
+
| APNG | ![Yes][yes] | ![Yes][yes] |
|
|
40
|
+
| GIF | ![Yes][yes] | ![Yes][yes] |
|
|
41
|
+
| WebP | ![Yes][yes] | ![Yes][yes] |
|
|
42
|
+
| AVIF | ![Yes][yes] | ![Yes][yes] |
|
|
43
|
+
| HEIC | ![Yes][yes] | ![Yes][yes] |
|
|
44
|
+
| SVG | ![Yes][yes][^svg] | ![Yes][yes][^svg] |
|
|
45
|
+
| ICO | ![Yes][yes] | ![Yes][yes] |
|
|
46
|
+
| BMP | ![Yes][yes] | ![Yes][yes] |
|
|
47
|
+
| TIFF | ![Yes][yes] | ![No][no] |
|
|
48
|
+
| ICNS | ![Yes][yes] | ![No][no] |
|
|
49
|
+
| PSD | ![Yes][yes][^psd] | ![No][no] |
|
|
50
|
+
|
|
51
|
+
See [Formats](docs/formats.md) for the versions of iOS and Android each format needs, and what decodes it.
|
|
52
|
+
|
|
53
|
+
[yes]: docs/assets/yes.svg
|
|
54
|
+
[no]: docs/assets/no.svg
|
|
55
|
+
|
|
56
|
+
[^svg]: With an SVG library in the app: see [SVG images](docs/formats.md#svg-images).
|
|
57
|
+
|
|
58
|
+
[^psd]: Its composite image (the layers as Photoshop saved them flattened).
|
|
59
|
+
|
|
60
|
+
## Installation
|
|
61
|
+
|
|
62
|
+
Works with React Native 0.60 and later, with the New Architecture (through React Native's interop layer) and the legacy architecture, and with Expo. It's tested on React Native 0.87 with the New Architecture, 0.73 with the legacy architecture, and Expo SDK 57. A native New Architecture component is planned for a future major version.
|
|
68
63
|
|
|
69
64
|
```bash
|
|
70
65
|
npm install react-native-fast-image
|
|
@@ -79,6 +74,12 @@ npx expo install react-native-fast-image
|
|
|
79
74
|
|
|
80
75
|
It has native code, so it needs a [development build](https://docs.expo.dev/develop/development-builds/introduction/) (e.g. `npx expo run:ios`), not Expo Go.
|
|
81
76
|
|
|
77
|
+
To set the cache's size when the app starts, see [Native config](#native-config).
|
|
78
|
+
|
|
79
|
+
If your Android app has its own Glide `AppGlideModule`, read [using FastImage with an AppGlideModule](docs/android-build-settings.md#if-your-app-has-its-own-appglidemodule) first, or FastImage may not work.
|
|
80
|
+
|
|
81
|
+
## Usage
|
|
82
|
+
|
|
82
83
|
```jsx
|
|
83
84
|
import FastImage from 'react-native-fast-image'
|
|
84
85
|
|
|
@@ -88,94 +89,98 @@ const YourImage = () => (
|
|
|
88
89
|
source={{
|
|
89
90
|
uri: 'https://example.com/image.jpg',
|
|
90
91
|
headers: { Authorization: 'someAuthToken' },
|
|
91
|
-
priority:
|
|
92
|
+
priority: 'normal',
|
|
92
93
|
}}
|
|
93
|
-
resizeMode=
|
|
94
|
+
resizeMode="contain"
|
|
94
95
|
/>
|
|
95
96
|
)
|
|
96
97
|
```
|
|
97
98
|
|
|
98
|
-
##
|
|
99
|
+
## Components
|
|
99
100
|
|
|
100
|
-
|
|
101
|
+
### `FastImage`
|
|
101
102
|
|
|
102
|
-
|
|
103
|
+
It also takes React Native's View props, such as accessibility props, `testID`, `nativeID`, `onLayout` and `pointerEvents`.
|
|
103
104
|
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
Source for the remote image to load.
|
|
107
|
-
|
|
108
|
-
When `source` changes, the image that's showing stays until the new one has loaded. In views that get reused for other content, such as rows in FlashList or recyclerlistview, set `recyclingKey` so a reused row doesn't show the previous row's image.
|
|
105
|
+
<!-- api:props start (generated from src/ by website/scripts/generate.mts) -->
|
|
109
106
|
|
|
110
|
-
|
|
107
|
+
#### `source`
|
|
111
108
|
|
|
112
|
-
|
|
109
|
+
**Type:** `number | Source | Source[]`
|
|
113
110
|
|
|
114
|
-
|
|
111
|
+
Source for the remote image to load: a `Source`, a `require()`d image, or an array of the same image at different sizes.
|
|
115
112
|
|
|
116
|
-
|
|
113
|
+
When `source` changes, the image that's showing stays until the new one has loaded. In views that get reused for other content, such as rows in FlashList or recyclerlistview, set `recyclingKey` so a reused row doesn't show the previous row's image.
|
|
117
114
|
|
|
118
|
-
|
|
115
|
+
**Several sizes of an image.** `source` can also be an array of the same image at different sizes, each with its `width` and `height` in pixels (times `scale`, if it has one). The view loads the one whose size is closest to its own, in pixels, so a small view downloads a small image:
|
|
119
116
|
|
|
120
|
-
|
|
117
|
+
```jsx
|
|
118
|
+
<FastImage
|
|
119
|
+
style={{ width: 120, height: 120 }}
|
|
120
|
+
source={[
|
|
121
|
+
{ uri: 'https://example.com/photo-200.jpg', width: 200, height: 200 },
|
|
122
|
+
{ uri: 'https://example.com/photo-800.jpg', width: 800, height: 800 },
|
|
123
|
+
]}
|
|
124
|
+
/>
|
|
125
|
+
```
|
|
121
126
|
|
|
122
|
-
|
|
127
|
+
- The view picks once it has been laid out. One that has no size (e.g. sized from `onLoad`) loads the largest.
|
|
128
|
+
- When the view's size changes so that another size fits better, it loads that one (with its load events), and keeps showing the current image until then, without a `transition`.
|
|
129
|
+
- Each size is cached separately. A `cacheKey` applies to its own entry: give each size its own key (or none), or the sizes would replace each other in the cache.
|
|
130
|
+
- `FastImage.preload`, `getCachePath` and `writeToCache` take one size: pass the one a view will show. An array fails with `{ ok: false, error }`.
|
|
131
|
+
- An array of one is the same as that source.
|
|
123
132
|
|
|
124
|
-
|
|
133
|
+
---
|
|
125
134
|
|
|
126
|
-
|
|
127
|
-
# ios/Podfile
|
|
128
|
-
pod 'SDWebImageSVGCoder'
|
|
129
|
-
```
|
|
135
|
+
##### `source.uri`
|
|
130
136
|
|
|
131
|
-
|
|
132
|
-
// android/app/build.gradle
|
|
133
|
-
dependencies {
|
|
134
|
-
implementation 'com.caverock:androidsvg-aar:1.4'
|
|
135
|
-
}
|
|
136
|
-
```
|
|
137
|
+
**Type:** `string`
|
|
137
138
|
|
|
138
|
-
|
|
139
|
+
Remote url to load the image from. e.g. `'https://example.com/image.jpg'`.
|
|
139
140
|
|
|
140
|
-
|
|
141
|
+
Also loads local files (`file://`, and on Android `content://`), photo library images on iOS (`ph://`, see [Photo library images](#photo-library-images-ios)) and SVG images (see [SVG images](docs/formats.md#svg-images)).
|
|
141
142
|
|
|
142
143
|
---
|
|
143
144
|
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
APNG (animated PNG) images animate on Android with [APNG4Android](https://github.com/penfeizhou/APNG4Android), which FastImage includes when the app's `minSdkVersion` is 21 or later (React Native 0.64 and later by default). With an older `minSdkVersion` they show their first frame.
|
|
145
|
+
##### `source.headers`
|
|
147
146
|
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
### `source.headers?: object`
|
|
147
|
+
**Type:** `{ [key: string]: string }`
|
|
151
148
|
|
|
152
149
|
Headers to load the image with. e.g. `{ Authorization: 'someAuthToken' }`.
|
|
153
150
|
|
|
154
151
|
---
|
|
155
152
|
|
|
156
|
-
|
|
153
|
+
##### `source.priority`
|
|
154
|
+
|
|
155
|
+
**Type:** `Priority` · **Default:** `'normal'`
|
|
157
156
|
|
|
158
|
-
|
|
157
|
+
A hint for which images to start loading first when several are waiting: `'high'` ones before `'normal'` ones, and `'low'` ones after. It's best effort, not an order: several images load at once, and when each finishes depends on its size and the network.
|
|
159
158
|
|
|
160
|
-
- `
|
|
161
|
-
- `
|
|
162
|
-
- `
|
|
159
|
+
- `'low'`: e.g. images further down a list.
|
|
160
|
+
- `'normal'`: the default.
|
|
161
|
+
- `'high'`: e.g. the image the screen is about.
|
|
163
162
|
|
|
164
163
|
---
|
|
165
164
|
|
|
166
|
-
|
|
165
|
+
##### `source.cache`
|
|
166
|
+
|
|
167
|
+
**Type:** `Cache` · **Default:** `'immutable'`
|
|
167
168
|
|
|
168
169
|
How fresh the image must be. See [how caching is handled](docs/how-is-caching-handled.md) for how the options fit together.
|
|
169
170
|
|
|
170
|
-
- `
|
|
171
|
-
- `
|
|
172
|
-
- `
|
|
171
|
+
- `'immutable'`: loads the image once, then shows the cached copy until its url (or `cacheKey`) changes.
|
|
172
|
+
- `'web'`: follows the server's HTTP cache headers, as a browser does, checking with the server when it loads. These responses are kept in their own HTTP cache (50 MB on each platform), which `clearDiskCache` also clears.
|
|
173
|
+
- `'cacheOnly'`: only shows a cached image, without making a request.
|
|
173
174
|
|
|
174
175
|
---
|
|
175
176
|
|
|
176
|
-
|
|
177
|
+
##### `source.cacheKey`
|
|
178
|
+
|
|
179
|
+
**Type:** `string`
|
|
177
180
|
|
|
178
|
-
The key the image is cached under, instead of its uri. Use it for urls that change while the image stays the same, e.g. signed urls with a token or an expiry. Use something that identifies the image, and change it when the image changes (e.g. include a version or the time it was updated), or the old image keeps showing
|
|
181
|
+
The key the image is cached under, instead of its uri. Use it for urls that change while the image stays the same, e.g. signed urls with a token or an expiry. Use something that identifies the image, and change it when the image changes (e.g. include a version or the time it was updated), or the old image keeps showing.
|
|
182
|
+
|
|
183
|
+
Not used with `cache: 'web'`, which follows the HTTP cache (keyed by url).
|
|
179
184
|
|
|
180
185
|
```jsx
|
|
181
186
|
<FastImage
|
|
@@ -186,52 +191,75 @@ The key the image is cached under, instead of its uri. Use it for urls that chan
|
|
|
186
191
|
/>
|
|
187
192
|
```
|
|
188
193
|
|
|
189
|
-
|
|
194
|
+
---
|
|
195
|
+
|
|
196
|
+
##### `source.memoryCache`
|
|
197
|
+
|
|
198
|
+
**Type:** `boolean` · **Default:** `true`
|
|
199
|
+
|
|
200
|
+
Whether the decoded image is kept in the memory cache. With `false` it's only kept on disk: a view doesn't leave it in memory once it stops showing it, and `FastImage.preload` downloads it without decoding it. Use it for large images that are shown once or rarely, like a full-screen photo: a decoded photo can take tens of MB of memory. Images shown again, like a list scrolled back, are decoded from disk again.
|
|
190
201
|
|
|
191
202
|
---
|
|
192
203
|
|
|
193
|
-
|
|
204
|
+
##### `source.width`
|
|
205
|
+
|
|
206
|
+
**Type:** `number`
|
|
194
207
|
|
|
195
|
-
|
|
208
|
+
With several sources (`source` as an array), the image's width at this uri, in pixels (times `scale`, if given).
|
|
196
209
|
|
|
197
210
|
---
|
|
198
211
|
|
|
199
|
-
|
|
212
|
+
##### `source.height`
|
|
200
213
|
|
|
201
|
-
|
|
214
|
+
**Type:** `number`
|
|
202
215
|
|
|
203
|
-
|
|
204
|
-
<FastImage
|
|
205
|
-
style={{ width: 120, height: 120 }}
|
|
206
|
-
source={[
|
|
207
|
-
{ uri: 'https://example.com/photo-200.jpg', width: 200, height: 200 },
|
|
208
|
-
{ uri: 'https://example.com/photo-800.jpg', width: 800, height: 800 },
|
|
209
|
-
{
|
|
210
|
-
uri: 'https://example.com/photo-2000.jpg',
|
|
211
|
-
width: 2000,
|
|
212
|
-
height: 2000,
|
|
213
|
-
},
|
|
214
|
-
]}
|
|
215
|
-
/>
|
|
216
|
-
```
|
|
216
|
+
With several sources (`source` as an array), the image's height at this uri, in pixels (times `scale`, if given).
|
|
217
217
|
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
218
|
+
---
|
|
219
|
+
|
|
220
|
+
##### `source.scale`
|
|
221
|
+
|
|
222
|
+
**Type:** `number`
|
|
223
|
+
|
|
224
|
+
With several sources, the scale `width` and `height` are multiplied by.
|
|
225
|
+
|
|
226
|
+
---
|
|
227
|
+
|
|
228
|
+
#### `defaultSource`
|
|
229
|
+
|
|
230
|
+
**Type:** `number`
|
|
231
|
+
|
|
232
|
+
An asset loaded with `require(...)`, shown while the first image loads, and if an image fails to load. When `source` changes, the previous image shows while the new one loads instead (see `source` and `recyclingKey`).
|
|
233
|
+
|
|
234
|
+
On Android, `defaultSource` doesn't show in debug builds: there the dev server serves `require()`d images, and `defaultSource` is only loaded from the app's resources.
|
|
223
235
|
|
|
224
236
|
---
|
|
225
237
|
|
|
226
|
-
|
|
238
|
+
#### `resizeMode`
|
|
239
|
+
|
|
240
|
+
**Type:** `ResizeMode` · **Default:** `'cover'`
|
|
241
|
+
|
|
242
|
+
How the image fills the view.
|
|
227
243
|
|
|
228
|
-
-
|
|
229
|
-
-
|
|
230
|
-
-
|
|
244
|
+
- `'contain'`: scales it uniformly (keeping its aspect ratio) so all of it fits in the view (minus padding).
|
|
245
|
+
- `'cover'`: scales it uniformly (keeping its aspect ratio) so it covers the view (minus padding), cropping what doesn't fit.
|
|
246
|
+
- `'stretch'`: scales its width and height separately to fill the view, which can change its aspect ratio.
|
|
247
|
+
- `'center'`: centers it at its own size, scaled down uniformly to fit if it's larger than the view.
|
|
248
|
+
- `'repeat'`: repeats it to cover the view, from its top-left corner, at the image's own size in pixels (a bundled image at its size in points), scaled down to fit if it's larger than the view. An animated image repeats its first frame, and `defaultSource` repeats too.
|
|
231
249
|
|
|
232
250
|
---
|
|
233
251
|
|
|
234
|
-
|
|
252
|
+
#### `fallback`
|
|
253
|
+
|
|
254
|
+
**Type:** `boolean`
|
|
255
|
+
|
|
256
|
+
If true, the image is shown with React Native's `Image` instead, styled and laid out the same way. FastImage's own features, such as its caching options, `priority` and `transition`, don't apply.
|
|
257
|
+
|
|
258
|
+
---
|
|
259
|
+
|
|
260
|
+
#### `recyclingKey`
|
|
261
|
+
|
|
262
|
+
**Type:** `string | null`
|
|
235
263
|
|
|
236
264
|
For views that get reused for other content, such as rows in FlashList or recyclerlistview. Set it to something that identifies the content, e.g. the item's id. When it changes, the image is cleared right away (to `defaultSource`, or blank) instead of staying until the new one has loaded. Unlike changing `key`, this keeps the view, which is what list recycling is for.
|
|
237
265
|
|
|
@@ -241,55 +269,46 @@ For views that get reused for other content, such as rows in FlashList or recycl
|
|
|
241
269
|
|
|
242
270
|
---
|
|
243
271
|
|
|
244
|
-
|
|
272
|
+
#### `loop`
|
|
245
273
|
|
|
246
|
-
|
|
247
|
-
- `FastImage.resizeMode.cover` **(Default)** - Scale the image uniformly (maintain the image's aspect ratio) so that both dimensions (width and height) of the image will be equal to or larger than the corresponding dimension of the view (minus padding).
|
|
248
|
-
- `FastImage.resizeMode.stretch` - Scale width and height independently, This may change the aspect ratio of the src.
|
|
249
|
-
- `FastImage.resizeMode.center` - Center the image at its own size, scaled down uniformly to fit if it's larger than the view.
|
|
250
|
-
- `FastImage.resizeMode.repeat` - Repeat the image to cover the view, from its top-left corner, at the image's own size in pixels (a bundled image at its size in points), scaled down to fit if it's larger than the view. An animated image repeats its first frame, and `defaultSource` repeats too.
|
|
274
|
+
**Type:** `number | boolean`
|
|
251
275
|
|
|
252
|
-
|
|
276
|
+
How many times an animated image (GIF, animated WebP, APNG, or animated AVIF) plays:
|
|
253
277
|
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
|
|
258
|
-
- Not set **(Default)** - As many times as the file says (like a browser).
|
|
259
|
-
- `true` - Loop forever.
|
|
260
|
-
- `false` - Play once.
|
|
261
|
-
- A number - Play that many times.
|
|
278
|
+
- Not set: as many times as the file says (like a browser).
|
|
279
|
+
- `true`: forever.
|
|
280
|
+
- `false`: once.
|
|
281
|
+
- A number: that many times.
|
|
262
282
|
|
|
263
283
|
Changing it restarts the animation.
|
|
264
284
|
|
|
265
285
|
---
|
|
266
286
|
|
|
267
|
-
|
|
287
|
+
#### `imageRendering`
|
|
288
|
+
|
|
289
|
+
**Type:** `'auto' | 'smooth' | 'pixelated'` · **Default:** `'auto'`
|
|
268
290
|
|
|
269
291
|
How the image is filtered when it's drawn smaller or larger than its size (like CSS's `image-rendering`):
|
|
270
292
|
|
|
271
|
-
- `'auto'
|
|
272
|
-
- `'smooth'
|
|
273
|
-
- `'pixelated'
|
|
293
|
+
- `'auto'`: the platform's usual filtering.
|
|
294
|
+
- `'smooth'`: iOS only. Keeps a large image drawn much smaller than its size (e.g. a big photo as a thumbnail, or fine lines and text) from looking jagged or noisy. Such an image is already decoded at about the view's size by default (see `downsample`), so this is for images shown at less than half their size with `downsample={false}`, or a little smaller than their size. **It uses more memory:** the image is also kept at smaller sizes for drawing, about a third more than the decoded image. On Android it's the same as `'auto'` (images are always decoded at about the view's size there).
|
|
295
|
+
- `'pixelated'`: sharp pixels, without smoothing, e.g. for pixel art drawn larger than its size. On Android, animated images are still smoothed.
|
|
274
296
|
|
|
275
297
|
---
|
|
276
298
|
|
|
277
|
-
|
|
299
|
+
#### `paused`
|
|
278
300
|
|
|
279
|
-
|
|
301
|
+
**Type:** `boolean`
|
|
302
|
+
|
|
303
|
+
Pauses an animated image (GIF, animated WebP, APNG, or animated AVIF) on the frame it's showing; `false` plays it again from there (on Android, an animated WebP or AVIF plays again from its first frame: Android can't resume one). Each image animates on its own, so pausing one doesn't pause others showing the same file.
|
|
280
304
|
|
|
281
305
|
---
|
|
282
306
|
|
|
283
|
-
|
|
307
|
+
#### `transition`
|
|
284
308
|
|
|
285
|
-
|
|
309
|
+
**Type:** `number | boolean | Transition | null` · **Default:** `false`
|
|
286
310
|
|
|
287
|
-
|
|
288
|
-
- `betweenImages` (default `false`): also fade between images. By default an image fades in when it appears over nothing (or over `defaultSource`), and a new `source` replaces the image that's showing at once, once it has loaded. With `true`, the new image cross-dissolves from the one showing (for a gallery or an avatar that changes, say).
|
|
289
|
-
- `skipOnCacheHit`: which images show at once, without the fade:
|
|
290
|
-
- `'memory'` (default): images from the memory cache, so a list scrolled back up shows images it already loaded at once. Images from the disk cache fade in.
|
|
291
|
-
- `'all'`: images from the memory or disk cache: images that download fade in, and local files and bundled images usually only the first time they load (the disk cache usually keeps them too).
|
|
292
|
-
- `'none'`: every image fades in.
|
|
311
|
+
Fades the image in when it loads. `true` uses the platform's usual fade, a number is the duration in milliseconds, or pass a `Transition`.
|
|
293
312
|
|
|
294
313
|
Downloads, local files (`file://`, `content://`) and bundled images (`require()`) fade in. In lists that reuse views (e.g. FlashList), set `recyclingKey`, so a reused view starts empty and its image fades in, instead of showing the previous item's image until it loads.
|
|
295
314
|
|
|
@@ -301,12 +320,14 @@ Downloads, local files (`file://`, `content://`) and bundled images (`require()`
|
|
|
301
320
|
|
|
302
321
|
---
|
|
303
322
|
|
|
304
|
-
|
|
323
|
+
#### `downsample`
|
|
324
|
+
|
|
325
|
+
**Type:** `boolean` · **Default:** `true` · iOS only
|
|
305
326
|
|
|
306
|
-
|
|
327
|
+
Decodes a large image at about the size it's shown at, instead of at full size, so it takes much less memory.
|
|
307
328
|
|
|
308
|
-
- `true
|
|
309
|
-
- `false
|
|
329
|
+
- `true`: an image at least twice the size its view needs is decoded at about the view's size. If the view grows, the image is decoded again for its new size (from the disk cache).
|
|
330
|
+
- `false`: images are decoded at full size, e.g. for an image that's zoomed in on with a transform (a pinch-to-zoom viewer), which would otherwise show the smaller copy enlarged.
|
|
310
331
|
|
|
311
332
|
It doesn't change `onLoad`'s width and height (the image's own size) or the cached file. Needs SDWebImage 5.19.7 or later: before 5.19 images are decoded at full size, and 5.19.0 to 5.19.6 show photos stored sideways with an EXIF orientation (most phone photos) sideways. Photo library images are always decoded this way, and on Android images are always decoded at about the view's size (but Android 16 and later decode animated WebP at full size, and scale it as they draw it).
|
|
312
333
|
|
|
@@ -314,9 +335,11 @@ If you control the images, serve them at the size they're shown (resized on your
|
|
|
314
335
|
|
|
315
336
|
---
|
|
316
337
|
|
|
317
|
-
|
|
338
|
+
#### `blurRadius`
|
|
318
339
|
|
|
319
|
-
|
|
340
|
+
**Type:** `number` · **Default:** `0`
|
|
341
|
+
|
|
342
|
+
Blurs the image by this radius, in points (the same radius looks about the same on iOS and Android). `0` is no blur.
|
|
320
343
|
|
|
321
344
|
It's for still images, or a radius that changes now and then (e.g. blurring a photo behind a sheet). Each change blurs the image again on the CPU, so don't animate it.
|
|
322
345
|
|
|
@@ -330,37 +353,53 @@ To animate a blur, or to blur an animated image, use React Native's `filter` sty
|
|
|
330
353
|
|
|
331
354
|
---
|
|
332
355
|
|
|
333
|
-
|
|
356
|
+
#### `onLoadStart`
|
|
357
|
+
|
|
358
|
+
**Type:** `() => void`
|
|
334
359
|
|
|
335
360
|
Called when the image starts to load.
|
|
336
361
|
|
|
337
362
|
---
|
|
338
363
|
|
|
339
|
-
|
|
364
|
+
#### `onProgress`
|
|
365
|
+
|
|
366
|
+
**Type:** `(event: OnProgressEvent) => void`
|
|
340
367
|
|
|
341
368
|
Called while the image downloads, with the bytes `loaded` so far, the `total`, and `progress` (`loaded / total`, from 0 to 1; the last event has 1). Not called while the total is unknown (a response without a `Content-Length`).
|
|
342
369
|
|
|
343
|
-
|
|
370
|
+
```jsx
|
|
371
|
+
onProgress={e => console.log(e.nativeEvent.progress)}
|
|
372
|
+
```
|
|
344
373
|
|
|
345
374
|
---
|
|
346
375
|
|
|
347
|
-
|
|
376
|
+
#### `onLoad`
|
|
377
|
+
|
|
378
|
+
**Type:** `(event: OnLoadEvent) => void`
|
|
348
379
|
|
|
349
380
|
Called on a successful image fetch. Called with the width and height of the image itself, not of the view (on iOS, in points: an `@2x` asset reports half its pixel size).
|
|
350
381
|
|
|
351
|
-
|
|
382
|
+
```jsx
|
|
383
|
+
onLoad={e => console.log(e.nativeEvent.width, e.nativeEvent.height)}
|
|
384
|
+
```
|
|
352
385
|
|
|
353
386
|
---
|
|
354
387
|
|
|
355
|
-
|
|
388
|
+
#### `onError`
|
|
389
|
+
|
|
390
|
+
**Type:** `(event: OnErrorEvent) => void`
|
|
356
391
|
|
|
357
392
|
Called on an image fetching error, with a message describing it (e.g. the HTTP status code).
|
|
358
393
|
|
|
359
|
-
|
|
394
|
+
```jsx
|
|
395
|
+
onError={e => console.log(e.nativeEvent.error)}
|
|
396
|
+
```
|
|
360
397
|
|
|
361
398
|
---
|
|
362
399
|
|
|
363
|
-
|
|
400
|
+
#### `onLoadEnd`
|
|
401
|
+
|
|
402
|
+
**Type:** `(result: LoadResult) => void`
|
|
364
403
|
|
|
365
404
|
Called when the image finishes loading, whether it was successful or an error, with the result: `{ ok: true, width, height }` (the image's size, as `onLoad` gets it) or `{ ok: false, error }` (as `onError` gets it). TypeScript makes you check `ok` before reading the size or the error.
|
|
366
405
|
|
|
@@ -376,23 +415,31 @@ Called when the image finishes loading, whether it was successful or an error, w
|
|
|
376
415
|
|
|
377
416
|
---
|
|
378
417
|
|
|
379
|
-
|
|
418
|
+
#### `style`
|
|
419
|
+
|
|
420
|
+
**Type:** `StyleProp<ImageStyle>`
|
|
380
421
|
|
|
381
|
-
|
|
422
|
+
The image's style: View's style props (`borderRadius` clips the image), and `tintColor`, as with React Native's `Image` (the `tintColor` prop wins).
|
|
382
423
|
|
|
383
424
|
---
|
|
384
425
|
|
|
385
|
-
|
|
426
|
+
#### `tintColor`
|
|
386
427
|
|
|
387
|
-
|
|
428
|
+
**Type:** `ColorValue`
|
|
429
|
+
|
|
430
|
+
If supplied, changes the color of all the non-transparent pixels to the given color.
|
|
388
431
|
|
|
389
432
|
---
|
|
390
433
|
|
|
391
|
-
|
|
434
|
+
#### `children`
|
|
392
435
|
|
|
393
|
-
|
|
436
|
+
**Type:** `ReactNode`
|
|
394
437
|
|
|
395
|
-
|
|
438
|
+
Render children within the image. In the next major version, `FastImage` won't render children: use `FastImageBackground`.
|
|
439
|
+
|
|
440
|
+
<!-- api:props end -->
|
|
441
|
+
|
|
442
|
+
### `FastImageBackground`
|
|
396
443
|
|
|
397
444
|
An image with content on top of it: a view that the image fills, with the children on top.
|
|
398
445
|
|
|
@@ -412,14 +459,47 @@ const Banner = () => (
|
|
|
412
459
|
)
|
|
413
460
|
```
|
|
414
461
|
|
|
415
|
-
|
|
416
|
-
|
|
417
|
-
-
|
|
418
|
-
|
|
462
|
+
Its own props are below; the others are `FastImage`'s and go to the image. Its ref is the view's (`imageRef` is the image's).
|
|
463
|
+
|
|
464
|
+
<!-- api:background-props start (generated from src/ by website/scripts/generate.mts) -->
|
|
465
|
+
|
|
466
|
+
#### `style`
|
|
467
|
+
|
|
468
|
+
**Type:** `StyleProp<ViewStyle>`
|
|
469
|
+
|
|
470
|
+
The container's style; the image fills it.
|
|
471
|
+
|
|
472
|
+
---
|
|
473
|
+
|
|
474
|
+
#### `imageStyle`
|
|
475
|
+
|
|
476
|
+
**Type:** `StyleProp<ImageStyle>`
|
|
419
477
|
|
|
420
|
-
|
|
478
|
+
The image's style.
|
|
421
479
|
|
|
422
|
-
|
|
480
|
+
---
|
|
481
|
+
|
|
482
|
+
#### `imageRef`
|
|
483
|
+
|
|
484
|
+
**Type:** `Ref<any>`
|
|
485
|
+
|
|
486
|
+
A ref to the image (the FastImage inside).
|
|
487
|
+
|
|
488
|
+
---
|
|
489
|
+
|
|
490
|
+
#### `children`
|
|
491
|
+
|
|
492
|
+
**Type:** `ReactNode`
|
|
493
|
+
|
|
494
|
+
Content shown on top of the image.
|
|
495
|
+
|
|
496
|
+
<!-- api:background-props end -->
|
|
497
|
+
|
|
498
|
+
## Methods
|
|
499
|
+
|
|
500
|
+
### `preload(sources)`
|
|
501
|
+
|
|
502
|
+
**Parameters:** `sources: Source[]` · **Returns:** `Promise<PreloadResult[]>`
|
|
423
503
|
|
|
424
504
|
Preload images to display later. e.g.
|
|
425
505
|
|
|
@@ -457,15 +537,21 @@ A source with `memoryCache: false` is only downloaded to the disk cache, without
|
|
|
457
537
|
await FastImage.preload(photos.map((uri) => ({ uri, memoryCache: false })))
|
|
458
538
|
```
|
|
459
539
|
|
|
460
|
-
### `
|
|
540
|
+
### `clearMemoryCache()`
|
|
541
|
+
|
|
542
|
+
**Returns:** `Promise<void>`
|
|
543
|
+
|
|
544
|
+
Removes every image from the memory cache, e.g. to free memory. They're decoded from the disk cache again when they're next shown.
|
|
461
545
|
|
|
462
|
-
|
|
546
|
+
### `clearDiskCache()`
|
|
463
547
|
|
|
464
|
-
|
|
548
|
+
**Returns:** `Promise<void>`
|
|
465
549
|
|
|
466
|
-
|
|
550
|
+
Removes every image from the disk cache, including the HTTP cache of `cache: 'web'` images, e.g. when a user logs out. They're downloaded again when they're next shown. There's no way to remove a single image: to load one again after it changed, change its [`cacheKey`](#sourcecachekey).
|
|
467
551
|
|
|
468
|
-
### `
|
|
552
|
+
### `getCachePath(source)`
|
|
553
|
+
|
|
554
|
+
**Parameters:** `source: Source` · **Returns:** `Promise<CachePathResult>`
|
|
469
555
|
|
|
470
556
|
The path of the source's downloaded file in the disk cache, e.g. to share, save or upload an image without downloading it again. If the file isn't there, it's downloaded first, without decoding the image or keeping it in memory. Resolves with `{ ok: true, path }`, or `{ ok: false, error }` if it can't be downloaded. Never rejects.
|
|
471
557
|
|
|
@@ -481,7 +567,7 @@ With `cache: 'cacheOnly'` it doesn't download: use it to check whether an image
|
|
|
481
567
|
```js
|
|
482
568
|
const { ok } = await FastImage.getCachePath({
|
|
483
569
|
uri: photo.url,
|
|
484
|
-
cache:
|
|
570
|
+
cache: 'cacheOnly',
|
|
485
571
|
})
|
|
486
572
|
```
|
|
487
573
|
|
|
@@ -491,11 +577,13 @@ const { ok } = await FastImage.getCachePath({
|
|
|
491
577
|
- A `file://` source is its own path. Other local images (`require()` in a release build, `content://`) have no file to give.
|
|
492
578
|
- With `cache: 'web'`, Android only keeps the file if the server allows caching it (in an HTTP cache), and returns `ok: false` otherwise. If the server compressed the image with `Content-Encoding` (rare for images), that file is compressed.
|
|
493
579
|
|
|
494
|
-
There's no way to remove a single image from the cache. To load an image again after it changed on the server, change its [`cacheKey`](#sourcecachekey
|
|
580
|
+
There's no way to remove a single image from the cache. To load an image again after it changed on the server, change its [`cacheKey`](#sourcecachekey).
|
|
581
|
+
|
|
582
|
+
### `writeToCache(source, file)`
|
|
495
583
|
|
|
496
|
-
|
|
584
|
+
**Parameters:** `source: Source`, `file: string` · **Returns:** `Promise<CachePathResult>`
|
|
497
585
|
|
|
498
|
-
Stores a local image file as the source's image in the disk cache, so views and preloads of the source show it without downloading it. For example, after a user uploads a new avatar, store the photo they picked under the avatar's new url or [`cacheKey`](#sourcecachekey
|
|
586
|
+
Stores a local image file as the source's image in the disk cache, so views and preloads of the source show it without downloading it. For example, after a user uploads a new avatar, store the photo they picked under the avatar's new url or [`cacheKey`](#sourcecachekey), and it shows at once. `file` is a `file://` uri or a path (or on Android a `content://` uri, as image pickers often return). A source with a `cacheKey` doesn't need a `uri`, so the image can be stored before its url is known. Resolves with `{ ok: true, path }` (the cached file) or `{ ok: false, error }`. Never rejects.
|
|
499
587
|
|
|
500
588
|
```js
|
|
501
589
|
const result = await FastImage.writeToCache(
|
|
@@ -512,7 +600,9 @@ const result = await FastImage.writeToCache(
|
|
|
512
600
|
- Not for `cache: 'web'` sources, which are kept in an HTTP cache.
|
|
513
601
|
- Like any cached image, it can be removed from the cache later, and then it's downloaded from the source's url.
|
|
514
602
|
|
|
515
|
-
### `
|
|
603
|
+
### `configureCache(limits)`
|
|
604
|
+
|
|
605
|
+
**Parameters:** `limits?: CacheLimits` · **Returns:** `Promise<CacheState>`
|
|
516
606
|
|
|
517
607
|
How much the image cache keeps. Set the limits your app starts with in its native config, so they're in effect from the first image, and change them while the app runs with `configureCache`, e.g. from a storage setting. Runtime changes are saved, and used on the next launches too.
|
|
518
608
|
|
|
@@ -520,17 +610,180 @@ How much the image cache keeps. Set the limits your app starts with in its nativ
|
|
|
520
610
|
| ----------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------ | ---------------------------------------------------------------------------------------------------- |
|
|
521
611
|
| `maxDiskSize`: the most bytes of images kept on disk. When it's over, the least recently used images are removed. | Changes apply at once (the cache is trimmed to half the limit). Default: no limit. | Changes apply from the next launch (Glide's disk cache size is set when it starts). Default: 250 MB. |
|
|
522
612
|
| `maxDiskAge`: seconds an image is kept on disk after it was last used. | Default: 1 week (counted from when it was stored before SDWebImage 5.21, unless it's set). | No age limit. |
|
|
523
|
-
| `maxMemorySize`: the most bytes of decoded images kept in memory. | Default: no limit (they're removed when the system is low on memory). |
|
|
613
|
+
| `maxMemorySize`: the most bytes of decoded images kept in memory. | Default: no limit (they're removed when the system is low on memory). | About two screenfuls of images.[^glide-memory] |
|
|
524
614
|
|
|
525
615
|
`0` means no limit.
|
|
526
616
|
|
|
527
|
-
**Starting limits.**
|
|
617
|
+
**Starting limits.** Set them in the app's [native config](#native-config).
|
|
618
|
+
|
|
619
|
+
**Changing them at runtime.** Pass the limits to change; `null` goes back to the native config's (or the default). It resolves with the limits in effect and `diskSize`, the bytes the image disk cache uses now. Call it without limits to see them.
|
|
620
|
+
|
|
621
|
+
```js
|
|
622
|
+
await FastImage.configureCache({ maxDiskSize: 500 * 1024 * 1024 })
|
|
623
|
+
const { maxDiskSize, diskSize } = await FastImage.configureCache()
|
|
624
|
+
```
|
|
625
|
+
|
|
626
|
+
On Android, if your app has its own `AppGlideModule` (see [using FastImage with an AppGlideModule](docs/android-build-settings.md#if-your-app-has-its-own-appglidemodule)), set the disk cache size there instead: `maxDiskSize` isn't applied or reported. Likewise in an app with [expo-image](docs/android-build-settings.md#with-expo-image), whose Glide setup sets the disk cache.
|
|
627
|
+
|
|
628
|
+
Images with `cache: 'web'` are kept in their own HTTP cache instead, up to 50 MB on each platform, which these limits don't change.
|
|
629
|
+
|
|
630
|
+
## Types
|
|
631
|
+
|
|
632
|
+
<!-- api:types start (generated from src/ by website/scripts/generate.mts) -->
|
|
633
|
+
|
|
634
|
+
### `Cache`
|
|
635
|
+
|
|
636
|
+
**Type:** `'immutable' | 'web' | 'cacheOnly'`
|
|
637
|
+
|
|
638
|
+
How fresh an image must be: see [`source.cache`](#sourcecache).
|
|
639
|
+
|
|
640
|
+
---
|
|
641
|
+
|
|
642
|
+
### `CacheLimits`
|
|
643
|
+
|
|
644
|
+
`configureCache`'s changes: a number (0 for no limit), or `null` to go back to the app's native config (Info.plist, AndroidManifest.xml) or the platform's default. Leave one out to keep it. Changes are saved, and used on the next launches too. Android only has `maxDiskSize`.
|
|
645
|
+
|
|
646
|
+
- `maxDiskSize?` (`number | null`): The most bytes of images kept on disk. When it's over, the least recently used are removed (on iOS, until it's half this size). Default: no limit on iOS, 250 MB on Android.
|
|
647
|
+
- `maxDiskAge?` (`number | null`): iOS: the seconds an image is kept on disk after it was last used, or 0 to keep them until `maxDiskSize` removes them. Default: 1 week.
|
|
648
|
+
- `maxMemorySize?` (`number | null`): iOS: the most bytes of decoded images kept in memory. Default: no limit (they're removed when the system is low on memory).
|
|
649
|
+
|
|
650
|
+
---
|
|
651
|
+
|
|
652
|
+
### `CachePathResult`
|
|
653
|
+
|
|
654
|
+
**Type:** `{ ok: true; path: string } | { ok: false; error: string }`
|
|
655
|
+
|
|
656
|
+
`getCachePath`'s and `writeToCache`'s result: `ok` with the file's path, or not `ok` with the error.
|
|
657
|
+
|
|
658
|
+
---
|
|
659
|
+
|
|
660
|
+
### `CacheState`
|
|
661
|
+
|
|
662
|
+
`configureCache`'s result: the limits in effect (0 for no limit), and the bytes the disk cache uses now. Android only has `maxDiskSize` and `diskSize`, and neither if the app has its own `AppGlideModule` (or expo-image, which has one).
|
|
663
|
+
|
|
664
|
+
- `maxDiskSize?` (`number`)
|
|
665
|
+
- `maxDiskAge?` (`number`)
|
|
666
|
+
- `maxMemorySize?` (`number`)
|
|
667
|
+
- `diskSize?` (`number`): The bytes the disk cache uses now.
|
|
668
|
+
|
|
669
|
+
---
|
|
670
|
+
|
|
671
|
+
### `LoadResult`
|
|
672
|
+
|
|
673
|
+
**Type:** `{ ok: true; width: number; height: number } | { ok: false; error: string }`
|
|
674
|
+
|
|
675
|
+
A load's result, as `onLoadEnd` gets it: `ok` with the image's size, or not `ok` with the error (as `onLoad` and `onError` get them).
|
|
676
|
+
|
|
677
|
+
---
|
|
678
|
+
|
|
679
|
+
### `OnErrorEvent`
|
|
680
|
+
|
|
681
|
+
`onError`'s event: `nativeEvent.error` says what went wrong, e.g. an HTTP status code or an image that can't be decoded.
|
|
682
|
+
|
|
683
|
+
- `nativeEvent` (`{ error: string }`)
|
|
684
|
+
|
|
685
|
+
---
|
|
686
|
+
|
|
687
|
+
### `OnLoadEvent`
|
|
688
|
+
|
|
689
|
+
`onLoad`'s event: `nativeEvent` has the image's `width` and `height`, in pixels, and `target`, the view's React tag (missing on Android with the legacy architecture).
|
|
690
|
+
|
|
691
|
+
- `nativeEvent` (`{ width: number; height: number; target?: number }`)
|
|
692
|
+
|
|
693
|
+
---
|
|
694
|
+
|
|
695
|
+
### `OnProgressEvent`
|
|
696
|
+
|
|
697
|
+
`onProgress`'s event: `nativeEvent` has the bytes `loaded` and the `total`, and `progress`, `loaded / total` from 0 to 1.
|
|
698
|
+
|
|
699
|
+
- `nativeEvent` (`{ loaded: number; total: number; progress: number }`)
|
|
700
|
+
|
|
701
|
+
---
|
|
702
|
+
|
|
703
|
+
### `PreloadFailure`
|
|
704
|
+
|
|
705
|
+
A preloaded source that failed to load.
|
|
706
|
+
|
|
707
|
+
- `uri?` (`string`): The source's uri (none for a source without one, e.g. `null`).
|
|
708
|
+
- `ok` (`false`)
|
|
709
|
+
- `error` (`string`): What went wrong.
|
|
710
|
+
|
|
711
|
+
---
|
|
712
|
+
|
|
713
|
+
### `PreloadResult`
|
|
714
|
+
|
|
715
|
+
**Type:** `PreloadSuccess | PreloadFailure`
|
|
716
|
+
|
|
717
|
+
`preload`'s result for a source. Check `ok` to tell which it is: e.g. `if (result.ok)` narrows it to a `PreloadSuccess`, with its size. Reading `width` or `error` without checking is a type error.
|
|
718
|
+
|
|
719
|
+
---
|
|
720
|
+
|
|
721
|
+
### `PreloadSuccess`
|
|
722
|
+
|
|
723
|
+
A preloaded source that loaded (and is now cached).
|
|
724
|
+
|
|
725
|
+
- `uri` (`string`): The source's uri.
|
|
726
|
+
- `ok` (`true`)
|
|
727
|
+
- `width` (`number`): The image's width (as in `onLoad`).
|
|
728
|
+
- `height` (`number`): The image's height (as in `onLoad`).
|
|
729
|
+
|
|
730
|
+
---
|
|
731
|
+
|
|
732
|
+
### `Priority`
|
|
733
|
+
|
|
734
|
+
**Type:** `'low' | 'normal' | 'high'`
|
|
735
|
+
|
|
736
|
+
An image's load priority: see [`source.priority`](#sourcepriority).
|
|
737
|
+
|
|
738
|
+
---
|
|
739
|
+
|
|
740
|
+
### `ResizeMode`
|
|
741
|
+
|
|
742
|
+
**Type:** `'contain' | 'cover' | 'stretch' | 'center' | 'repeat'`
|
|
743
|
+
|
|
744
|
+
How the image fits the view: see [`resizeMode`](#resizemode).
|
|
745
|
+
|
|
746
|
+
---
|
|
747
|
+
|
|
748
|
+
### `Transition`
|
|
749
|
+
|
|
750
|
+
How the image fades in: see [`transition`](#transition).
|
|
751
|
+
|
|
752
|
+
- `duration?` (`number`): How long the fade takes, in milliseconds; 0 means no fade. Defaults to the platform's usual length: 300 ms on Android, 250 ms on iOS.
|
|
753
|
+
- `betweenImages?` (`boolean`, default `false`): Also fades between images: a new `source` replacing an image that's showing cross-dissolves from it. Otherwise only an image that appears over nothing (or over `defaultSource`) fades in, and a new source replaces the image showing at once, once it has loaded.
|
|
754
|
+
- `skipOnCacheHit?` (`'none' | 'memory' | 'all' | null`, default `'memory'`): Skips the fade for an image from a cache, so images already loaded show at once, e.g. in a list scrolled back up or a reused row.
|
|
755
|
+
|
|
756
|
+
- `'memory'`: skips it for images from the memory cache.
|
|
757
|
+
- `'all'`: skips it for images from the memory or disk cache too, so images that download fade in, and local files and bundled images usually only the first time (the disk cache usually keeps them too).
|
|
758
|
+
- `'none'`: always fades.
|
|
759
|
+
|
|
760
|
+
Downloads, local files and bundled images (`require()`) fade in.
|
|
761
|
+
|
|
762
|
+
<!-- api:types end -->
|
|
763
|
+
|
|
764
|
+
## Native config
|
|
765
|
+
|
|
766
|
+
The cache's limits the app starts with, read from its native projects so they're in effect from the first image. [`configureCache`](#configurecachelimits) says what each one does and its default, and changes them while the app runs. `0` means no limit.
|
|
767
|
+
|
|
768
|
+
| Limit | Unit | iOS (`Info.plist`) | Android (`AndroidManifest.xml`) |
|
|
769
|
+
| --------------- | ------- | ------------------------ | --------------------------------------------- |
|
|
770
|
+
| `maxDiskSize` | bytes | `FastImageMaxDiskSize` | `fastimage.MAX_DISK_SIZE` |
|
|
771
|
+
| `maxDiskAge` | seconds | `FastImageMaxDiskAge` | No age limit |
|
|
772
|
+
| `maxMemorySize` | bytes | `FastImageMaxMemorySize` | About two screenfuls of images[^glide-memory] |
|
|
773
|
+
|
|
774
|
+
### Expo config plugin
|
|
775
|
+
|
|
776
|
+
With Expo, FastImage's config plugin sets them, from its options in `app.json` (or `app.config.js`):
|
|
528
777
|
|
|
529
778
|
```json
|
|
530
779
|
"plugins": [["react-native-fast-image", { "maxDiskSize": 209715200, "maxDiskAge": 2592000 }]]
|
|
531
780
|
```
|
|
532
781
|
|
|
533
|
-
|
|
782
|
+
It writes the native settings below when Expo generates the native projects (`npx expo prebuild`), so run that again after changing them. An app that keeps its own `ios/` and `android/` projects sets them there instead.
|
|
783
|
+
|
|
784
|
+
### iOS
|
|
785
|
+
|
|
786
|
+
In `ios/<App>/Info.plist`:
|
|
534
787
|
|
|
535
788
|
```xml
|
|
536
789
|
<key>FastImageMaxDiskSize</key>
|
|
@@ -539,22 +792,23 @@ Without Expo, in `ios/<App>/Info.plist`:
|
|
|
539
792
|
<integer>2592000</integer>
|
|
540
793
|
```
|
|
541
794
|
|
|
542
|
-
|
|
795
|
+
### Android
|
|
796
|
+
|
|
797
|
+
In `android/app/src/main/AndroidManifest.xml`, inside `<application>`:
|
|
543
798
|
|
|
544
799
|
```xml
|
|
545
800
|
<meta-data android:name="fastimage.MAX_DISK_SIZE" android:value="209715200" />
|
|
546
801
|
```
|
|
547
802
|
|
|
548
|
-
|
|
803
|
+
If your app has its own `AppGlideModule` (see [using FastImage with an AppGlideModule](docs/android-build-settings.md#if-your-app-has-its-own-appglidemodule)), set the disk cache size there instead. In an app with [expo-image](docs/android-build-settings.md#with-expo-image), expo-image's Glide setup sets it.
|
|
549
804
|
|
|
550
|
-
|
|
551
|
-
await FastImage.configureCache({ maxDiskSize: 500 * 1024 * 1024 })
|
|
552
|
-
const { maxDiskSize, diskSize } = await FastImage.configureCache()
|
|
553
|
-
```
|
|
805
|
+
[^glide-memory]: Glide's default, which FastImage keeps: room for two screenfuls of decoded images (2 × the screen's width × height × 4 bytes, about 20 MB on a 1080 × 2400 screen), plus a pool of bitmaps to reuse (one screenful on Android 8 and later, four before). Together they're limited to 40% of the memory Android gives the app (33% on low-memory devices), and both shrink to fit.
|
|
554
806
|
|
|
555
|
-
|
|
807
|
+
## Photo library images (iOS)
|
|
556
808
|
|
|
557
|
-
|
|
809
|
+
A photo library url (`ph://<localIdentifier>`, as camera roll libraries give) loads with SDWebImagePhotosPlugin, which FastImage includes on iOS.
|
|
810
|
+
|
|
811
|
+
The app needs access to the photo library, which it has if it got the url from there. A photo library image is decoded at about the view's size, since photos are large and usually shown small; `onLoad` still reports the photo's own size. `FastImage.preload` of a `ph://` source loads the full-size photo (there's no view to size it for), which doesn't make a view's smaller copy load faster, so preloading photo library images usually isn't worth it. `assets-library://` urls aren't supported. On Android, photo pickers give `content://` urls, which load as they are.
|
|
558
812
|
|
|
559
813
|
## Web
|
|
560
814
|
|
|
@@ -593,13 +847,9 @@ Thanks to [@mobinni](https://github.com/mobinni) for helping with the conceptual
|
|
|
593
847
|
|
|
594
848
|
[build-badge]: https://github.com/DylanVann/react-native-fast-image/actions/workflows/ci.yml/badge.svg
|
|
595
849
|
[build]: https://github.com/DylanVann/react-native-fast-image/actions/workflows/ci.yml
|
|
850
|
+
[docs-badge]: https://img.shields.io/badge/docs-website-blue.svg
|
|
851
|
+
[docs]: https://react-native-fast-image.dylanvann.workers.dev
|
|
596
852
|
[downloads-badge]: https://img.shields.io/npm/dm/react-native-fast-image.svg
|
|
597
853
|
[npmtrends]: http://www.npmtrends.com/react-native-fast-image
|
|
598
854
|
[package]: https://www.npmjs.com/package/react-native-fast-image
|
|
599
855
|
[version-badge]: https://img.shields.io/npm/v/react-native-fast-image.svg
|
|
600
|
-
[twitter]: https://twitter.com/home?status=Check%20out%20react-native-fast-image%20by%20%40atomarranger%20https%3A//github.com/DylanVann/react-native-fast-image
|
|
601
|
-
[twitter-badge]: https://img.shields.io/twitter/url/https/github.com/DylanVann/react-native-fast-image.svg?style=social
|
|
602
|
-
[github-watch-badge]: https://img.shields.io/github/watchers/dylanvann/react-native-fast-image.svg?style=social
|
|
603
|
-
[github-watch]: https://github.com/dylanvann/react-native-fast-image/watchers
|
|
604
|
-
[github-star-badge]: https://img.shields.io/github/stars/dylanvann/react-native-fast-image.svg?style=social
|
|
605
|
-
[github-star]: https://github.com/dylanvann/react-native-fast-image/stargazers
|