react-native-fast-image 8.30.0 → 8.31.0
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 +457 -210
- package/android/src/main/java/com/dylanvann/fastimage/FastImageApngRenderer.java +12 -1
- package/app.plugin.js +1 -1
- package/dist/index.d.ts +357 -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,8 +1,4 @@
|
|
|
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
|
|
|
@@ -10,61 +6,59 @@ Performant React Native image component.
|
|
|
10
6
|
[![Downloads][downloads-badge]][npmtrends]
|
|
11
7
|
[![Build Status][build-badge]][build]
|
|
12
8
|
|
|
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:
|
|
9
|
+
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
10
|
|
|
45
11
|
- Flickering.
|
|
46
12
|
- Cache misses.
|
|
47
13
|
- Low performance loading from cache.
|
|
48
14
|
- Low performance in general.
|
|
49
15
|
|
|
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).
|
|
16
|
+
`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
17
|
|
|
56
18
|
## Features
|
|
57
19
|
|
|
58
|
-
- [
|
|
59
|
-
- [
|
|
60
|
-
- [
|
|
61
|
-
- [
|
|
62
|
-
- [
|
|
63
|
-
- [
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
20
|
+
- **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.
|
|
21
|
+
- **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)).
|
|
22
|
+
- **Preloading**, with a [result per image](#preloadsources) and the [cached file's path](#getcachepathsource).
|
|
23
|
+
- **Headers**, e.g. for authentication ([`headers`](#sourceheaders)).
|
|
24
|
+
- **Priorities** for which images load first ([`priority`](#sourcepriority)).
|
|
25
|
+
- **Responsive images**: give several sizes, and the one that fits the view loads ([`source`](#source)).
|
|
26
|
+
- **Animated images** (GIF, WebP, APNG and AVIF) that can [loop](#loop) and [pause](#paused).
|
|
27
|
+
- **Fades** in and between images ([`transition`](#transition)).
|
|
28
|
+
- [**SVG**](docs/formats.md#svg-images) and [**photo library**](#photo-library-images-ios) images.
|
|
29
|
+
- [**`FastImageBackground`**](#fastimagebackground) for content over an image.
|
|
30
|
+
- **Expo and web support**, with a [config plugin](#expo-config-plugin) for Expo.
|
|
31
|
+
|
|
32
|
+
## Image formats
|
|
33
|
+
|
|
34
|
+
| Format | iOS | Android |
|
|
35
|
+
| ------ | :---------------: | :---------------: |
|
|
36
|
+
| JPEG | ![Yes][yes] | ![Yes][yes] |
|
|
37
|
+
| PNG | ![Yes][yes] | ![Yes][yes] |
|
|
38
|
+
| APNG | ![Yes][yes] | ![Yes][yes] |
|
|
39
|
+
| GIF | ![Yes][yes] | ![Yes][yes] |
|
|
40
|
+
| WebP | ![Yes][yes] | ![Yes][yes] |
|
|
41
|
+
| AVIF | ![Yes][yes] | ![Yes][yes] |
|
|
42
|
+
| HEIC | ![Yes][yes] | ![Yes][yes] |
|
|
43
|
+
| SVG | ![Yes][yes][^svg] | ![Yes][yes][^svg] |
|
|
44
|
+
| ICO | ![Yes][yes] | ![Yes][yes] |
|
|
45
|
+
| BMP | ![Yes][yes] | ![Yes][yes] |
|
|
46
|
+
| TIFF | ![Yes][yes] | ![No][no] |
|
|
47
|
+
| ICNS | ![Yes][yes] | ![No][no] |
|
|
48
|
+
| PSD | ![Yes][yes][^psd] | ![No][no] |
|
|
49
|
+
|
|
50
|
+
See [Formats](docs/formats.md) for the versions of iOS and Android each format needs, and what decodes it.
|
|
51
|
+
|
|
52
|
+
[yes]: docs/assets/yes.svg
|
|
53
|
+
[no]: docs/assets/no.svg
|
|
54
|
+
|
|
55
|
+
[^svg]: With an SVG library in the app: see [SVG images](docs/formats.md#svg-images).
|
|
56
|
+
|
|
57
|
+
[^psd]: Its composite image (the layers as Photoshop saved them flattened).
|
|
58
|
+
|
|
59
|
+
## Installation
|
|
60
|
+
|
|
61
|
+
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
62
|
|
|
69
63
|
```bash
|
|
70
64
|
npm install react-native-fast-image
|
|
@@ -79,6 +73,12 @@ npx expo install react-native-fast-image
|
|
|
79
73
|
|
|
80
74
|
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
75
|
|
|
76
|
+
To set the cache's size when the app starts, see [Native config](#native-config).
|
|
77
|
+
|
|
78
|
+
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.
|
|
79
|
+
|
|
80
|
+
## Usage
|
|
81
|
+
|
|
82
82
|
```jsx
|
|
83
83
|
import FastImage from 'react-native-fast-image'
|
|
84
84
|
|
|
@@ -88,94 +88,98 @@ const YourImage = () => (
|
|
|
88
88
|
source={{
|
|
89
89
|
uri: 'https://example.com/image.jpg',
|
|
90
90
|
headers: { Authorization: 'someAuthToken' },
|
|
91
|
-
priority:
|
|
91
|
+
priority: 'normal',
|
|
92
92
|
}}
|
|
93
|
-
resizeMode=
|
|
93
|
+
resizeMode="contain"
|
|
94
94
|
/>
|
|
95
95
|
)
|
|
96
96
|
```
|
|
97
97
|
|
|
98
|
-
##
|
|
98
|
+
## Components
|
|
99
99
|
|
|
100
|
-
|
|
100
|
+
### `FastImage`
|
|
101
101
|
|
|
102
|
-
|
|
102
|
+
It also takes React Native's View props, such as accessibility props, `testID`, `nativeID`, `onLayout` and `pointerEvents`.
|
|
103
103
|
|
|
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.
|
|
104
|
+
<!-- api:props start (generated from src/ by website/scripts/generate.mts) -->
|
|
109
105
|
|
|
110
|
-
|
|
106
|
+
#### `source`
|
|
111
107
|
|
|
112
|
-
|
|
108
|
+
**Type:** `number | Source | Source[]`
|
|
113
109
|
|
|
114
|
-
|
|
110
|
+
Source for the remote image to load: a `Source`, a `require()`d image, or an array of the same image at different sizes.
|
|
115
111
|
|
|
116
|
-
|
|
112
|
+
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
113
|
|
|
118
|
-
|
|
114
|
+
**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
115
|
|
|
120
|
-
|
|
116
|
+
```jsx
|
|
117
|
+
<FastImage
|
|
118
|
+
style={{ width: 120, height: 120 }}
|
|
119
|
+
source={[
|
|
120
|
+
{ uri: 'https://example.com/photo-200.jpg', width: 200, height: 200 },
|
|
121
|
+
{ uri: 'https://example.com/photo-800.jpg', width: 800, height: 800 },
|
|
122
|
+
]}
|
|
123
|
+
/>
|
|
124
|
+
```
|
|
121
125
|
|
|
122
|
-
|
|
126
|
+
- The view picks once it has been laid out. One that has no size (e.g. sized from `onLoad`) loads the largest.
|
|
127
|
+
- 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`.
|
|
128
|
+
- 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.
|
|
129
|
+
- `FastImage.preload`, `getCachePath` and `writeToCache` take one size: pass the one a view will show. An array fails with `{ ok: false, error }`.
|
|
130
|
+
- An array of one is the same as that source.
|
|
123
131
|
|
|
124
|
-
|
|
132
|
+
---
|
|
125
133
|
|
|
126
|
-
|
|
127
|
-
# ios/Podfile
|
|
128
|
-
pod 'SDWebImageSVGCoder'
|
|
129
|
-
```
|
|
134
|
+
##### `source.uri`
|
|
130
135
|
|
|
131
|
-
|
|
132
|
-
// android/app/build.gradle
|
|
133
|
-
dependencies {
|
|
134
|
-
implementation 'com.caverock:androidsvg-aar:1.4'
|
|
135
|
-
}
|
|
136
|
-
```
|
|
136
|
+
**Type:** `string`
|
|
137
137
|
|
|
138
|
-
|
|
138
|
+
Remote url to load the image from. e.g. `'https://example.com/image.jpg'`.
|
|
139
139
|
|
|
140
|
-
|
|
140
|
+
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
141
|
|
|
142
142
|
---
|
|
143
143
|
|
|
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.
|
|
144
|
+
##### `source.headers`
|
|
147
145
|
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
### `source.headers?: object`
|
|
146
|
+
**Type:** `{ [key: string]: string }`
|
|
151
147
|
|
|
152
148
|
Headers to load the image with. e.g. `{ Authorization: 'someAuthToken' }`.
|
|
153
149
|
|
|
154
150
|
---
|
|
155
151
|
|
|
156
|
-
|
|
152
|
+
##### `source.priority`
|
|
153
|
+
|
|
154
|
+
**Type:** `Priority` · **Default:** `'normal'`
|
|
157
155
|
|
|
158
|
-
|
|
156
|
+
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
157
|
|
|
160
|
-
- `
|
|
161
|
-
- `
|
|
162
|
-
- `
|
|
158
|
+
- `'low'`: e.g. images further down a list.
|
|
159
|
+
- `'normal'`: the default.
|
|
160
|
+
- `'high'`: e.g. the image the screen is about.
|
|
163
161
|
|
|
164
162
|
---
|
|
165
163
|
|
|
166
|
-
|
|
164
|
+
##### `source.cache`
|
|
165
|
+
|
|
166
|
+
**Type:** `Cache` · **Default:** `'immutable'`
|
|
167
167
|
|
|
168
168
|
How fresh the image must be. See [how caching is handled](docs/how-is-caching-handled.md) for how the options fit together.
|
|
169
169
|
|
|
170
|
-
- `
|
|
171
|
-
- `
|
|
172
|
-
- `
|
|
170
|
+
- `'immutable'`: loads the image once, then shows the cached copy until its url (or `cacheKey`) changes.
|
|
171
|
+
- `'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.
|
|
172
|
+
- `'cacheOnly'`: only shows a cached image, without making a request.
|
|
173
173
|
|
|
174
174
|
---
|
|
175
175
|
|
|
176
|
-
|
|
176
|
+
##### `source.cacheKey`
|
|
177
|
+
|
|
178
|
+
**Type:** `string`
|
|
177
179
|
|
|
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
|
|
180
|
+
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
|
+
|
|
182
|
+
Not used with `cache: 'web'`, which follows the HTTP cache (keyed by url).
|
|
179
183
|
|
|
180
184
|
```jsx
|
|
181
185
|
<FastImage
|
|
@@ -186,52 +190,75 @@ The key the image is cached under, instead of its uri. Use it for urls that chan
|
|
|
186
190
|
/>
|
|
187
191
|
```
|
|
188
192
|
|
|
189
|
-
|
|
193
|
+
---
|
|
194
|
+
|
|
195
|
+
##### `source.memoryCache`
|
|
196
|
+
|
|
197
|
+
**Type:** `boolean` · **Default:** `true`
|
|
198
|
+
|
|
199
|
+
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
200
|
|
|
191
201
|
---
|
|
192
202
|
|
|
193
|
-
|
|
203
|
+
##### `source.width`
|
|
204
|
+
|
|
205
|
+
**Type:** `number`
|
|
194
206
|
|
|
195
|
-
|
|
207
|
+
With several sources (`source` as an array), the image's width at this uri, in pixels (times `scale`, if given).
|
|
196
208
|
|
|
197
209
|
---
|
|
198
210
|
|
|
199
|
-
|
|
211
|
+
##### `source.height`
|
|
200
212
|
|
|
201
|
-
|
|
213
|
+
**Type:** `number`
|
|
202
214
|
|
|
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
|
-
```
|
|
215
|
+
With several sources (`source` as an array), the image's height at this uri, in pixels (times `scale`, if given).
|
|
217
216
|
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
217
|
+
---
|
|
218
|
+
|
|
219
|
+
##### `source.scale`
|
|
220
|
+
|
|
221
|
+
**Type:** `number`
|
|
222
|
+
|
|
223
|
+
With several sources, the scale `width` and `height` are multiplied by.
|
|
224
|
+
|
|
225
|
+
---
|
|
226
|
+
|
|
227
|
+
#### `defaultSource`
|
|
228
|
+
|
|
229
|
+
**Type:** `number`
|
|
230
|
+
|
|
231
|
+
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`).
|
|
232
|
+
|
|
233
|
+
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
234
|
|
|
224
235
|
---
|
|
225
236
|
|
|
226
|
-
|
|
237
|
+
#### `resizeMode`
|
|
238
|
+
|
|
239
|
+
**Type:** `ResizeMode` · **Default:** `'cover'`
|
|
240
|
+
|
|
241
|
+
How the image fills the view.
|
|
227
242
|
|
|
228
|
-
-
|
|
229
|
-
-
|
|
230
|
-
-
|
|
243
|
+
- `'contain'`: scales it uniformly (keeping its aspect ratio) so all of it fits in the view (minus padding).
|
|
244
|
+
- `'cover'`: scales it uniformly (keeping its aspect ratio) so it covers the view (minus padding), cropping what doesn't fit.
|
|
245
|
+
- `'stretch'`: scales its width and height separately to fill the view, which can change its aspect ratio.
|
|
246
|
+
- `'center'`: centers it at its own size, scaled down uniformly to fit if it's larger than the view.
|
|
247
|
+
- `'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
248
|
|
|
232
249
|
---
|
|
233
250
|
|
|
234
|
-
|
|
251
|
+
#### `fallback`
|
|
252
|
+
|
|
253
|
+
**Type:** `boolean`
|
|
254
|
+
|
|
255
|
+
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.
|
|
256
|
+
|
|
257
|
+
---
|
|
258
|
+
|
|
259
|
+
#### `recyclingKey`
|
|
260
|
+
|
|
261
|
+
**Type:** `string | null`
|
|
235
262
|
|
|
236
263
|
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
264
|
|
|
@@ -241,55 +268,46 @@ For views that get reused for other content, such as rows in FlashList or recycl
|
|
|
241
268
|
|
|
242
269
|
---
|
|
243
270
|
|
|
244
|
-
|
|
271
|
+
#### `loop`
|
|
245
272
|
|
|
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.
|
|
273
|
+
**Type:** `number | boolean`
|
|
251
274
|
|
|
252
|
-
|
|
275
|
+
How many times an animated image (GIF, animated WebP, APNG, or animated AVIF) plays:
|
|
253
276
|
|
|
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.
|
|
277
|
+
- Not set: as many times as the file says (like a browser).
|
|
278
|
+
- `true`: forever.
|
|
279
|
+
- `false`: once.
|
|
280
|
+
- A number: that many times.
|
|
262
281
|
|
|
263
282
|
Changing it restarts the animation.
|
|
264
283
|
|
|
265
284
|
---
|
|
266
285
|
|
|
267
|
-
|
|
286
|
+
#### `imageRendering`
|
|
287
|
+
|
|
288
|
+
**Type:** `'auto' | 'smooth' | 'pixelated'` · **Default:** `'auto'`
|
|
268
289
|
|
|
269
290
|
How the image is filtered when it's drawn smaller or larger than its size (like CSS's `image-rendering`):
|
|
270
291
|
|
|
271
|
-
- `'auto'
|
|
272
|
-
- `'smooth'
|
|
273
|
-
- `'pixelated'
|
|
292
|
+
- `'auto'`: the platform's usual filtering.
|
|
293
|
+
- `'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).
|
|
294
|
+
- `'pixelated'`: sharp pixels, without smoothing, e.g. for pixel art drawn larger than its size. On Android, animated images are still smoothed.
|
|
274
295
|
|
|
275
296
|
---
|
|
276
297
|
|
|
277
|
-
|
|
298
|
+
#### `paused`
|
|
278
299
|
|
|
279
|
-
|
|
300
|
+
**Type:** `boolean`
|
|
301
|
+
|
|
302
|
+
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
303
|
|
|
281
304
|
---
|
|
282
305
|
|
|
283
|
-
|
|
306
|
+
#### `transition`
|
|
284
307
|
|
|
285
|
-
|
|
308
|
+
**Type:** `number | boolean | Transition | null` · **Default:** `false`
|
|
286
309
|
|
|
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.
|
|
310
|
+
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
311
|
|
|
294
312
|
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
313
|
|
|
@@ -301,12 +319,14 @@ Downloads, local files (`file://`, `content://`) and bundled images (`require()`
|
|
|
301
319
|
|
|
302
320
|
---
|
|
303
321
|
|
|
304
|
-
|
|
322
|
+
#### `downsample`
|
|
323
|
+
|
|
324
|
+
**Type:** `boolean` · **Default:** `true` · iOS only
|
|
305
325
|
|
|
306
|
-
|
|
326
|
+
Decodes a large image at about the size it's shown at, instead of at full size, so it takes much less memory.
|
|
307
327
|
|
|
308
|
-
- `true
|
|
309
|
-
- `false
|
|
328
|
+
- `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).
|
|
329
|
+
- `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
330
|
|
|
311
331
|
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
332
|
|
|
@@ -314,9 +334,11 @@ If you control the images, serve them at the size they're shown (resized on your
|
|
|
314
334
|
|
|
315
335
|
---
|
|
316
336
|
|
|
317
|
-
|
|
337
|
+
#### `blurRadius`
|
|
318
338
|
|
|
319
|
-
|
|
339
|
+
**Type:** `number` · **Default:** `0`
|
|
340
|
+
|
|
341
|
+
Blurs the image by this radius, in points (the same radius looks about the same on iOS and Android). `0` is no blur.
|
|
320
342
|
|
|
321
343
|
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
344
|
|
|
@@ -330,37 +352,53 @@ To animate a blur, or to blur an animated image, use React Native's `filter` sty
|
|
|
330
352
|
|
|
331
353
|
---
|
|
332
354
|
|
|
333
|
-
|
|
355
|
+
#### `onLoadStart`
|
|
356
|
+
|
|
357
|
+
**Type:** `() => void`
|
|
334
358
|
|
|
335
359
|
Called when the image starts to load.
|
|
336
360
|
|
|
337
361
|
---
|
|
338
362
|
|
|
339
|
-
|
|
363
|
+
#### `onProgress`
|
|
364
|
+
|
|
365
|
+
**Type:** `(event: OnProgressEvent) => void`
|
|
340
366
|
|
|
341
367
|
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
368
|
|
|
343
|
-
|
|
369
|
+
```jsx
|
|
370
|
+
onProgress={e => console.log(e.nativeEvent.progress)}
|
|
371
|
+
```
|
|
344
372
|
|
|
345
373
|
---
|
|
346
374
|
|
|
347
|
-
|
|
375
|
+
#### `onLoad`
|
|
376
|
+
|
|
377
|
+
**Type:** `(event: OnLoadEvent) => void`
|
|
348
378
|
|
|
349
379
|
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
380
|
|
|
351
|
-
|
|
381
|
+
```jsx
|
|
382
|
+
onLoad={e => console.log(e.nativeEvent.width, e.nativeEvent.height)}
|
|
383
|
+
```
|
|
352
384
|
|
|
353
385
|
---
|
|
354
386
|
|
|
355
|
-
|
|
387
|
+
#### `onError`
|
|
388
|
+
|
|
389
|
+
**Type:** `(event: OnErrorEvent) => void`
|
|
356
390
|
|
|
357
391
|
Called on an image fetching error, with a message describing it (e.g. the HTTP status code).
|
|
358
392
|
|
|
359
|
-
|
|
393
|
+
```jsx
|
|
394
|
+
onError={e => console.log(e.nativeEvent.error)}
|
|
395
|
+
```
|
|
360
396
|
|
|
361
397
|
---
|
|
362
398
|
|
|
363
|
-
|
|
399
|
+
#### `onLoadEnd`
|
|
400
|
+
|
|
401
|
+
**Type:** `(result: LoadResult) => void`
|
|
364
402
|
|
|
365
403
|
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
404
|
|
|
@@ -376,23 +414,31 @@ Called when the image finishes loading, whether it was successful or an error, w
|
|
|
376
414
|
|
|
377
415
|
---
|
|
378
416
|
|
|
379
|
-
|
|
417
|
+
#### `style`
|
|
418
|
+
|
|
419
|
+
**Type:** `StyleProp<ImageStyle>`
|
|
380
420
|
|
|
381
|
-
|
|
421
|
+
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
422
|
|
|
383
423
|
---
|
|
384
424
|
|
|
385
|
-
|
|
425
|
+
#### `tintColor`
|
|
386
426
|
|
|
387
|
-
|
|
427
|
+
**Type:** `ColorValue`
|
|
428
|
+
|
|
429
|
+
If supplied, changes the color of all the non-transparent pixels to the given color.
|
|
388
430
|
|
|
389
431
|
---
|
|
390
432
|
|
|
391
|
-
|
|
433
|
+
#### `children`
|
|
392
434
|
|
|
393
|
-
|
|
435
|
+
**Type:** `ReactNode`
|
|
394
436
|
|
|
395
|
-
|
|
437
|
+
Render children within the image. In the next major version, `FastImage` won't render children: use `FastImageBackground`.
|
|
438
|
+
|
|
439
|
+
<!-- api:props end -->
|
|
440
|
+
|
|
441
|
+
### `FastImageBackground`
|
|
396
442
|
|
|
397
443
|
An image with content on top of it: a view that the image fills, with the children on top.
|
|
398
444
|
|
|
@@ -412,14 +458,47 @@ const Banner = () => (
|
|
|
412
458
|
)
|
|
413
459
|
```
|
|
414
460
|
|
|
415
|
-
|
|
416
|
-
|
|
417
|
-
-
|
|
418
|
-
|
|
461
|
+
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).
|
|
462
|
+
|
|
463
|
+
<!-- api:background-props start (generated from src/ by website/scripts/generate.mts) -->
|
|
464
|
+
|
|
465
|
+
#### `style`
|
|
466
|
+
|
|
467
|
+
**Type:** `StyleProp<ViewStyle>`
|
|
468
|
+
|
|
469
|
+
The container's style; the image fills it.
|
|
470
|
+
|
|
471
|
+
---
|
|
472
|
+
|
|
473
|
+
#### `imageStyle`
|
|
474
|
+
|
|
475
|
+
**Type:** `StyleProp<ImageStyle>`
|
|
419
476
|
|
|
420
|
-
|
|
477
|
+
The image's style.
|
|
421
478
|
|
|
422
|
-
|
|
479
|
+
---
|
|
480
|
+
|
|
481
|
+
#### `imageRef`
|
|
482
|
+
|
|
483
|
+
**Type:** `Ref<any>`
|
|
484
|
+
|
|
485
|
+
A ref to the image (the FastImage inside).
|
|
486
|
+
|
|
487
|
+
---
|
|
488
|
+
|
|
489
|
+
#### `children`
|
|
490
|
+
|
|
491
|
+
**Type:** `ReactNode`
|
|
492
|
+
|
|
493
|
+
Content shown on top of the image.
|
|
494
|
+
|
|
495
|
+
<!-- api:background-props end -->
|
|
496
|
+
|
|
497
|
+
## Methods
|
|
498
|
+
|
|
499
|
+
### `preload(sources)`
|
|
500
|
+
|
|
501
|
+
**Parameters:** `sources: Source[]` · **Returns:** `Promise<PreloadResult[]>`
|
|
423
502
|
|
|
424
503
|
Preload images to display later. e.g.
|
|
425
504
|
|
|
@@ -457,15 +536,21 @@ A source with `memoryCache: false` is only downloaded to the disk cache, without
|
|
|
457
536
|
await FastImage.preload(photos.map((uri) => ({ uri, memoryCache: false })))
|
|
458
537
|
```
|
|
459
538
|
|
|
460
|
-
### `
|
|
539
|
+
### `clearMemoryCache()`
|
|
540
|
+
|
|
541
|
+
**Returns:** `Promise<void>`
|
|
542
|
+
|
|
543
|
+
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
544
|
|
|
462
|
-
|
|
545
|
+
### `clearDiskCache()`
|
|
463
546
|
|
|
464
|
-
|
|
547
|
+
**Returns:** `Promise<void>`
|
|
465
548
|
|
|
466
|
-
|
|
549
|
+
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
550
|
|
|
468
|
-
### `
|
|
551
|
+
### `getCachePath(source)`
|
|
552
|
+
|
|
553
|
+
**Parameters:** `source: Source` · **Returns:** `Promise<CachePathResult>`
|
|
469
554
|
|
|
470
555
|
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
556
|
|
|
@@ -481,7 +566,7 @@ With `cache: 'cacheOnly'` it doesn't download: use it to check whether an image
|
|
|
481
566
|
```js
|
|
482
567
|
const { ok } = await FastImage.getCachePath({
|
|
483
568
|
uri: photo.url,
|
|
484
|
-
cache:
|
|
569
|
+
cache: 'cacheOnly',
|
|
485
570
|
})
|
|
486
571
|
```
|
|
487
572
|
|
|
@@ -491,11 +576,13 @@ const { ok } = await FastImage.getCachePath({
|
|
|
491
576
|
- A `file://` source is its own path. Other local images (`require()` in a release build, `content://`) have no file to give.
|
|
492
577
|
- 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
578
|
|
|
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
|
|
579
|
+
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
|
+
|
|
581
|
+
### `writeToCache(source, file)`
|
|
495
582
|
|
|
496
|
-
|
|
583
|
+
**Parameters:** `source: Source`, `file: string` · **Returns:** `Promise<CachePathResult>`
|
|
497
584
|
|
|
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
|
|
585
|
+
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
586
|
|
|
500
587
|
```js
|
|
501
588
|
const result = await FastImage.writeToCache(
|
|
@@ -512,7 +599,9 @@ const result = await FastImage.writeToCache(
|
|
|
512
599
|
- Not for `cache: 'web'` sources, which are kept in an HTTP cache.
|
|
513
600
|
- Like any cached image, it can be removed from the cache later, and then it's downloaded from the source's url.
|
|
514
601
|
|
|
515
|
-
### `
|
|
602
|
+
### `configureCache(limits)`
|
|
603
|
+
|
|
604
|
+
**Parameters:** `limits?: CacheLimits` · **Returns:** `Promise<CacheState>`
|
|
516
605
|
|
|
517
606
|
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
607
|
|
|
@@ -520,17 +609,180 @@ How much the image cache keeps. Set the limits your app starts with in its nativ
|
|
|
520
609
|
| ----------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------ | ---------------------------------------------------------------------------------------------------- |
|
|
521
610
|
| `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
611
|
| `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). |
|
|
612
|
+
| `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
613
|
|
|
525
614
|
`0` means no limit.
|
|
526
615
|
|
|
527
|
-
**Starting limits.**
|
|
616
|
+
**Starting limits.** Set them in the app's [native config](#native-config).
|
|
617
|
+
|
|
618
|
+
**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.
|
|
619
|
+
|
|
620
|
+
```js
|
|
621
|
+
await FastImage.configureCache({ maxDiskSize: 500 * 1024 * 1024 })
|
|
622
|
+
const { maxDiskSize, diskSize } = await FastImage.configureCache()
|
|
623
|
+
```
|
|
624
|
+
|
|
625
|
+
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.
|
|
626
|
+
|
|
627
|
+
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.
|
|
628
|
+
|
|
629
|
+
## Types
|
|
630
|
+
|
|
631
|
+
<!-- api:types start (generated from src/ by website/scripts/generate.mts) -->
|
|
632
|
+
|
|
633
|
+
### `Cache`
|
|
634
|
+
|
|
635
|
+
**Type:** `'immutable' | 'web' | 'cacheOnly'`
|
|
636
|
+
|
|
637
|
+
How fresh an image must be: see [`source.cache`](#sourcecache).
|
|
638
|
+
|
|
639
|
+
---
|
|
640
|
+
|
|
641
|
+
### `CacheLimits`
|
|
642
|
+
|
|
643
|
+
`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`.
|
|
644
|
+
|
|
645
|
+
- `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.
|
|
646
|
+
- `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.
|
|
647
|
+
- `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).
|
|
648
|
+
|
|
649
|
+
---
|
|
650
|
+
|
|
651
|
+
### `CachePathResult`
|
|
652
|
+
|
|
653
|
+
**Type:** `{ ok: true; path: string } | { ok: false; error: string }`
|
|
654
|
+
|
|
655
|
+
`getCachePath`'s and `writeToCache`'s result: `ok` with the file's path, or not `ok` with the error.
|
|
656
|
+
|
|
657
|
+
---
|
|
658
|
+
|
|
659
|
+
### `CacheState`
|
|
660
|
+
|
|
661
|
+
`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`.
|
|
662
|
+
|
|
663
|
+
- `maxDiskSize?` (`number`)
|
|
664
|
+
- `maxDiskAge?` (`number`)
|
|
665
|
+
- `maxMemorySize?` (`number`)
|
|
666
|
+
- `diskSize?` (`number`): The bytes the disk cache uses now.
|
|
667
|
+
|
|
668
|
+
---
|
|
669
|
+
|
|
670
|
+
### `LoadResult`
|
|
671
|
+
|
|
672
|
+
**Type:** `{ ok: true; width: number; height: number } | { ok: false; error: string }`
|
|
673
|
+
|
|
674
|
+
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).
|
|
675
|
+
|
|
676
|
+
---
|
|
677
|
+
|
|
678
|
+
### `OnErrorEvent`
|
|
679
|
+
|
|
680
|
+
`onError`'s event: `nativeEvent.error` says what went wrong, e.g. an HTTP status code or an image that can't be decoded.
|
|
681
|
+
|
|
682
|
+
- `nativeEvent` (`{ error: string }`)
|
|
683
|
+
|
|
684
|
+
---
|
|
685
|
+
|
|
686
|
+
### `OnLoadEvent`
|
|
687
|
+
|
|
688
|
+
`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).
|
|
689
|
+
|
|
690
|
+
- `nativeEvent` (`{ width: number; height: number; target?: number }`)
|
|
691
|
+
|
|
692
|
+
---
|
|
693
|
+
|
|
694
|
+
### `OnProgressEvent`
|
|
695
|
+
|
|
696
|
+
`onProgress`'s event: `nativeEvent` has the bytes `loaded` and the `total`, and `progress`, `loaded / total` from 0 to 1.
|
|
697
|
+
|
|
698
|
+
- `nativeEvent` (`{ loaded: number; total: number; progress: number }`)
|
|
699
|
+
|
|
700
|
+
---
|
|
701
|
+
|
|
702
|
+
### `PreloadFailure`
|
|
703
|
+
|
|
704
|
+
A preloaded source that failed to load.
|
|
705
|
+
|
|
706
|
+
- `uri?` (`string`): The source's uri (none for a source without one, e.g. `null`).
|
|
707
|
+
- `ok` (`false`)
|
|
708
|
+
- `error` (`string`): What went wrong.
|
|
709
|
+
|
|
710
|
+
---
|
|
711
|
+
|
|
712
|
+
### `PreloadResult`
|
|
713
|
+
|
|
714
|
+
**Type:** `PreloadSuccess | PreloadFailure`
|
|
715
|
+
|
|
716
|
+
`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.
|
|
717
|
+
|
|
718
|
+
---
|
|
719
|
+
|
|
720
|
+
### `PreloadSuccess`
|
|
721
|
+
|
|
722
|
+
A preloaded source that loaded (and is now cached).
|
|
723
|
+
|
|
724
|
+
- `uri` (`string`): The source's uri.
|
|
725
|
+
- `ok` (`true`)
|
|
726
|
+
- `width` (`number`): The image's width (as in `onLoad`).
|
|
727
|
+
- `height` (`number`): The image's height (as in `onLoad`).
|
|
728
|
+
|
|
729
|
+
---
|
|
730
|
+
|
|
731
|
+
### `Priority`
|
|
732
|
+
|
|
733
|
+
**Type:** `'low' | 'normal' | 'high'`
|
|
734
|
+
|
|
735
|
+
An image's load priority: see [`source.priority`](#sourcepriority).
|
|
736
|
+
|
|
737
|
+
---
|
|
738
|
+
|
|
739
|
+
### `ResizeMode`
|
|
740
|
+
|
|
741
|
+
**Type:** `'contain' | 'cover' | 'stretch' | 'center' | 'repeat'`
|
|
742
|
+
|
|
743
|
+
How the image fits the view: see [`resizeMode`](#resizemode).
|
|
744
|
+
|
|
745
|
+
---
|
|
746
|
+
|
|
747
|
+
### `Transition`
|
|
748
|
+
|
|
749
|
+
How the image fades in: see [`transition`](#transition).
|
|
750
|
+
|
|
751
|
+
- `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.
|
|
752
|
+
- `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.
|
|
753
|
+
- `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.
|
|
754
|
+
|
|
755
|
+
- `'memory'`: skips it for images from the memory cache.
|
|
756
|
+
- `'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).
|
|
757
|
+
- `'none'`: always fades.
|
|
758
|
+
|
|
759
|
+
Downloads, local files and bundled images (`require()`) fade in.
|
|
760
|
+
|
|
761
|
+
<!-- api:types end -->
|
|
762
|
+
|
|
763
|
+
## Native config
|
|
764
|
+
|
|
765
|
+
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.
|
|
766
|
+
|
|
767
|
+
| Limit | Unit | iOS (`Info.plist`) | Android (`AndroidManifest.xml`) |
|
|
768
|
+
| --------------- | ------- | ------------------------ | --------------------------------------------- |
|
|
769
|
+
| `maxDiskSize` | bytes | `FastImageMaxDiskSize` | `fastimage.MAX_DISK_SIZE` |
|
|
770
|
+
| `maxDiskAge` | seconds | `FastImageMaxDiskAge` | No age limit |
|
|
771
|
+
| `maxMemorySize` | bytes | `FastImageMaxMemorySize` | About two screenfuls of images[^glide-memory] |
|
|
772
|
+
|
|
773
|
+
### Expo config plugin
|
|
774
|
+
|
|
775
|
+
With Expo, FastImage's config plugin sets them, from its options in `app.json` (or `app.config.js`):
|
|
528
776
|
|
|
529
777
|
```json
|
|
530
778
|
"plugins": [["react-native-fast-image", { "maxDiskSize": 209715200, "maxDiskAge": 2592000 }]]
|
|
531
779
|
```
|
|
532
780
|
|
|
533
|
-
|
|
781
|
+
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.
|
|
782
|
+
|
|
783
|
+
### iOS
|
|
784
|
+
|
|
785
|
+
In `ios/<App>/Info.plist`:
|
|
534
786
|
|
|
535
787
|
```xml
|
|
536
788
|
<key>FastImageMaxDiskSize</key>
|
|
@@ -539,22 +791,23 @@ Without Expo, in `ios/<App>/Info.plist`:
|
|
|
539
791
|
<integer>2592000</integer>
|
|
540
792
|
```
|
|
541
793
|
|
|
542
|
-
|
|
794
|
+
### Android
|
|
795
|
+
|
|
796
|
+
In `android/app/src/main/AndroidManifest.xml`, inside `<application>`:
|
|
543
797
|
|
|
544
798
|
```xml
|
|
545
799
|
<meta-data android:name="fastimage.MAX_DISK_SIZE" android:value="209715200" />
|
|
546
800
|
```
|
|
547
801
|
|
|
548
|
-
|
|
802
|
+
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.
|
|
549
803
|
|
|
550
|
-
|
|
551
|
-
await FastImage.configureCache({ maxDiskSize: 500 * 1024 * 1024 })
|
|
552
|
-
const { maxDiskSize, diskSize } = await FastImage.configureCache()
|
|
553
|
-
```
|
|
804
|
+
[^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
805
|
|
|
555
|
-
|
|
806
|
+
## Photo library images (iOS)
|
|
556
807
|
|
|
557
|
-
|
|
808
|
+
A photo library url (`ph://<localIdentifier>`, as camera roll libraries give) loads with SDWebImagePhotosPlugin, which FastImage includes on iOS.
|
|
809
|
+
|
|
810
|
+
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
811
|
|
|
559
812
|
## Web
|
|
560
813
|
|
|
@@ -597,9 +850,3 @@ Thanks to [@mobinni](https://github.com/mobinni) for helping with the conceptual
|
|
|
597
850
|
[npmtrends]: http://www.npmtrends.com/react-native-fast-image
|
|
598
851
|
[package]: https://www.npmjs.com/package/react-native-fast-image
|
|
599
852
|
[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
|