Skip to content

Commit

Permalink
Prefetch images using a lower download priority
Browse files Browse the repository at this point in the history
Reviewed By: fkgozali

Differential Revision: D21881729

fbshipit-source-id: 071a41aef2458df3d9a93a4ab0174af73e85b9fc
  • Loading branch information
p-sun authored and facebook-github-bot committed Jun 6, 2020
1 parent 21d0eb7 commit 058eeb4
Show file tree
Hide file tree
Showing 8 changed files with 99 additions and 28 deletions.
67 changes: 57 additions & 10 deletions Libraries/Image/RCTImageLoader.mm
Original file line number Diff line number Diff line change
Expand Up @@ -146,6 +146,7 @@ - (float)handlerPriority
{
return 2;
}
#pragma mark - RCTImageLoaderProtocol 1/3

- (id<RCTImageCache>)imageCache
{
Expand Down Expand Up @@ -228,6 +229,8 @@ - (void)setImageCache:(id<RCTImageCache>)cache
return nil;
}

# pragma mark - Private Image Decoding & Resizing

- (id<RCTImageDataDecoder>)imageDataDecoderForData:(NSData *)data
{
if (!_maxConcurrentLoadingTasks) {
Expand Down Expand Up @@ -309,24 +312,56 @@ - (void)setImageCache:(id<RCTImageCache>)cache
return image;
}

- (RCTImageLoaderCancellationBlock) loadImageWithURLRequest:(NSURLRequest *)imageURLRequest
callback:(RCTImageLoaderCompletionBlock)callback
#pragma mark - RCTImageLoaderProtocol 2/3

- (RCTImageLoaderCancellationBlock)loadImageWithURLRequest:(NSURLRequest *)imageURLRequest
callback:(RCTImageLoaderCompletionBlock)callback
{
return [self loadImageWithURLRequest:imageURLRequest
priority:RCTImageLoaderPriorityImmediate
callback:callback];
}

- (RCTImageLoaderCancellationBlock)loadImageWithURLRequest:(NSURLRequest *)imageURLRequest
priority:(RCTImageLoaderPriority)priority
callback:(RCTImageLoaderCompletionBlock)callback {
return [self loadImageWithURLRequest:imageURLRequest
size:CGSizeZero
scale:1
clipped:YES
resizeMode:RCTResizeModeStretch
priority:priority
progressBlock:nil
partialLoadBlock:nil
completionBlock:callback];
}

- (RCTImageLoaderCancellationBlock)loadImageWithURLRequest:(NSURLRequest *)imageURLRequest
size:(CGSize)size
scale:(CGFloat)scale
clipped:(BOOL)clipped
resizeMode:(RCTResizeMode)resizeMode
progressBlock:(RCTImageLoaderProgressBlock)progressBlock
partialLoadBlock:(RCTImageLoaderPartialLoadBlock)partialLoadBlock
completionBlock:(RCTImageLoaderCompletionBlock)completionBlock
{
return [self loadImageWithURLRequest:imageURLRequest
size:CGSizeZero
scale:1
clipped:YES
resizeMode:RCTResizeModeStretch
progressBlock:nil
partialLoadBlock:nil
completionBlock:callback];
return [self loadImageWithURLRequest:imageURLRequest
size:size
scale:scale
clipped:clipped
resizeMode:resizeMode
priority:RCTImageLoaderPriorityImmediate
progressBlock:progressBlock
partialLoadBlock:partialLoadBlock
completionBlock:completionBlock];
}

- (RCTImageLoaderCancellationBlock)loadImageWithURLRequest:(NSURLRequest *)imageURLRequest
size:(CGSize)size
scale:(CGFloat)scale
clipped:(BOOL)clipped
resizeMode:(RCTResizeMode)resizeMode
priority:(RCTImageLoaderPriority)priority
progressBlock:(RCTImageLoaderProgressBlock)progressBlock
partialLoadBlock:(RCTImageLoaderPartialLoadBlock)partialLoadBlock
completionBlock:(RCTImageLoaderCompletionBlock)completionBlock
Expand All @@ -336,6 +371,7 @@ - (RCTImageLoaderCancellationBlock)loadImageWithURLRequest:(NSURLRequest *)image
scale:scale
clipped:clipped
resizeMode:resizeMode
priority:priority
attribution:{}
progressBlock:progressBlock
partialLoadBlock:partialLoadBlock
Expand All @@ -345,6 +381,8 @@ - (RCTImageLoaderCancellationBlock)loadImageWithURLRequest:(NSURLRequest *)image
};
}

#pragma mark - Private Downloader Methods

- (void)dequeueTasks
{
dispatch_async(_URLRequestQueue, ^{
Expand Down Expand Up @@ -415,6 +453,7 @@ - (RCTImageURLLoaderRequest *)_loadImageOrDataWithURLRequest:(NSURLRequest *)req
size:(CGSize)size
scale:(CGFloat)scale
resizeMode:(RCTResizeMode)resizeMode
priority:(RCTImageLoaderPriority)priority
attribution:(const ImageURLLoaderAttribution &)attribution
progressBlock:(RCTImageLoaderProgressBlock)progressHandler
partialLoadBlock:(RCTImageLoaderPartialLoadBlock)partialLoadHandler
Expand Down Expand Up @@ -481,6 +520,7 @@ - (RCTImageURLLoaderRequest *)_loadImageOrDataWithURLRequest:(NSURLRequest *)req
scale:scale
resizeMode:resizeMode
requestId:requestId
priority:priority
attribution:attributionCopy
progressHandler:progressHandler
partialLoadHandler:partialLoadHandler
Expand Down Expand Up @@ -520,6 +560,7 @@ - (RCTImageURLLoaderRequest *)_loadImageOrDataWithURLRequest:(NSURLRequest *)req
scale:scale
resizeMode:resizeMode
requestId:requestId
priority:priority
attribution:attributionCopy
progressHandler:progressHandler
partialLoadHandler:partialLoadHandler
Expand Down Expand Up @@ -701,6 +742,7 @@ - (RCTImageURLLoaderRequest *)loadImageWithURLRequest:(NSURLRequest *)imageURLRe
scale:(CGFloat)scale
clipped:(BOOL)clipped
resizeMode:(RCTResizeMode)resizeMode
priority:(RCTImageLoaderPriority)priority
attribution:(const ImageURLLoaderAttribution &)attribution
progressBlock:(RCTImageLoaderProgressBlock)progressBlock
partialLoadBlock:(RCTImageLoaderPartialLoadBlock)partialLoadBlock
Expand Down Expand Up @@ -768,6 +810,7 @@ - (RCTImageURLLoaderRequest *)loadImageWithURLRequest:(NSURLRequest *)imageURLRe
size:size
scale:scale
resizeMode:resizeMode
priority:priority
attribution:attribution
progressBlock:progressBlock
partialLoadBlock:partialLoadBlock
Expand Down Expand Up @@ -825,6 +868,8 @@ - (void)trackURLImageDidDestroy:(RCTImageURLLoaderRequest *)loaderRequest
}
}

#pragma mark - RCTImageLoaderProtocol 3/3

- (RCTImageLoaderCancellationBlock)decodeImageData:(NSData *)data
size:(CGSize)size
scale:(CGFloat)scale
Expand Down Expand Up @@ -976,6 +1021,7 @@ - (RCTImageLoaderCancellationBlock)getImageSizeForURLRequest:(NSURLRequest *)ima
size:CGSizeZero
scale:1
resizeMode:RCTResizeModeStretch
priority: RCTImageLoaderPriorityImmediate
attribution:{}
progressBlock:NULL
partialLoadBlock:NULL
Expand Down Expand Up @@ -1134,6 +1180,7 @@ - (void)cancelRequest:(id)requestToken
{
NSURLRequest *request = [RCTConvert NSURLRequest:uri];
[self loadImageWithURLRequest:request
priority:RCTImageLoaderPriorityPrefetch
callback:^(NSError *error, UIImage *image) {
if (error) {
reject(@"E_PREFETCH_FAILURE", nil, error);
Expand Down
33 changes: 25 additions & 8 deletions Libraries/Image/RCTImageLoaderProtocol.h
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,17 @@

@end

/**
* Image Downloading priority.
* Use PriorityImmediate to download images at the highest priority.
* Use PriorityPrefetch to prefetch images at a lower priority.
* The priority logic is up to each @RCTImageLoaderProtocol implementation
*/
typedef NS_ENUM(NSUInteger, RCTImageLoaderPriority) {
RCTImageLoaderPriorityImmediate,
RCTImageLoaderPriorityPrefetch
};

@protocol RCTImageLoaderProtocol<RCTURLRequestHandler>

/**
Expand Down Expand Up @@ -59,16 +70,22 @@
*/
- (RCTImageLoaderCancellationBlock)loadImageWithURLRequest:(NSURLRequest *)imageURLRequest
callback:(RCTImageLoaderCompletionBlock)callback;

/**
* As above, but includes target `size`, `scale` and `resizeMode`, which are used to
* select the optimal dimensions for the loaded image. The `clipped` option
* controls whether the image will be clipped to fit the specified size exactly,
* or if the original aspect ratio should be retained.
* `partialLoadBlock` is meant for custom image loaders that do not ship with the core RN library.
* It is meant to be called repeatedly while loading the image as higher quality versions are decoded,
* for instance with progressive JPEGs.
* As above, but includes download `priority`.
*/
- (RCTImageLoaderCancellationBlock)loadImageWithURLRequest:(NSURLRequest *)imageURLRequest
priority:(RCTImageLoaderPriority)priority
callback:(RCTImageLoaderCompletionBlock)callback;

/**
* As above, but includes target `size`, `scale` and `resizeMode`, which are used to
* select the optimal dimensions for the loaded image. The `clipped` option
* controls whether the image will be clipped to fit the specified size exactly,
* or if the original aspect ratio should be retained.
* `partialLoadBlock` is meant for custom image loaders that do not ship with the core RN library.
* It is meant to be called repeatedly while loading the image as higher quality versions are decoded,
* for instance with progressive JPEGs.
*/
- (RCTImageLoaderCancellationBlock)loadImageWithURLRequest:(NSURLRequest *)imageURLRequest
size:(CGSize)size
scale:(CGFloat)scale
Expand Down
1 change: 1 addition & 0 deletions Libraries/Image/RCTImageLoaderWithAttributionProtocol.h
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@ RCT_EXTERN void RCTEnableImageLoadingPerfInstrumentation(BOOL enabled);
scale:(CGFloat)scale
clipped:(BOOL)clipped
resizeMode:(RCTResizeMode)resizeMode
priority: (RCTImageLoaderPriority)priority
attribution:(const facebook::react::ImageURLLoaderAttribution &)attribution
progressBlock:(RCTImageLoaderProgressBlock)progressBlock
partialLoadBlock:(RCTImageLoaderPartialLoadBlock)partialLoadBlock
Expand Down
2 changes: 2 additions & 0 deletions Libraries/Image/RCTImageURLLoaderWithAttribution.h
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
*/

#import <React/RCTImageURLLoader.h>
#import <React/RCTImageLoaderProtocol.h>

// TODO (T61325135): Remove C++ checks
#ifdef __cplusplus
Expand Down Expand Up @@ -50,6 +51,7 @@ struct ImageURLLoaderAttribution {
scale:(CGFloat)scale
resizeMode:(RCTResizeMode)resizeMode
requestId:(NSString *)requestId
priority: (RCTImageLoaderPriority)priority
attribution:(const facebook::react::ImageURLLoaderAttribution &)attribution
progressHandler:(RCTImageLoaderProgressBlock)progressHandler
partialLoadHandler:(RCTImageLoaderPartialLoadBlock)partialLoadHandler
Expand Down
1 change: 1 addition & 0 deletions Libraries/Image/RCTImageView.mm
Original file line number Diff line number Diff line change
Expand Up @@ -345,6 +345,7 @@ - (void)reloadImage
scale:imageScale
clipped:NO
resizeMode:_resizeMode
priority:RCTImageLoaderPriorityImmediate
attribution:{
.nativeViewTag = [self.reactTag intValue],
.surfaceId = [self.rootTag intValue],
Expand Down
21 changes: 11 additions & 10 deletions Libraries/Image/RCTImageViewManager.mm
Original file line number Diff line number Diff line change
Expand Up @@ -89,16 +89,17 @@ - (UIView *)view
reject(@"E_INVALID_URI", @"Cannot prefetch an image for an empty URI", nil);
return;
}

[[self.bridge moduleForName:@"ImageLoader" lazilyLoadIfNecessary:YES]
loadImageWithURLRequest:request
callback:^(NSError *error, UIImage *image) {
if (error) {
reject(@"E_PREFETCH_FAILURE", nil, error);
return;
}
resolve(@YES);
}];
id<RCTImageLoaderProtocol> imageLoader = (id<RCTImageLoaderProtocol>)[self.bridge
moduleForName:@"ImageLoader" lazilyLoadIfNecessary:YES];
[imageLoader loadImageWithURLRequest:request
priority:RCTImageLoaderPriorityPrefetch
callback:^(NSError *error, UIImage *image) {
if (error) {
reject(@"E_PREFETCH_FAILURE", nil, error);
return;
}
resolve(@YES);
}];
}

RCT_EXPORT_METHOD(queryCache:(NSArray *)requests
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -90,6 +90,7 @@ - (ImageRequest)requestImage:(ImageSource)imageSource surfaceId:(SurfaceId)surfa
scale:imageSource.scale
clipped:YES
resizeMode:RCTResizeModeStretch
priority:RCTImageLoaderPriorityImmediate
attribution:{
.surfaceId = surfaceId,
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -78,6 +78,7 @@ - (ImageRequest)requestImage:(ImageSource)imageSource surfaceId:(SurfaceId)surfa
scale:imageSource.scale
clipped:YES
resizeMode:RCTResizeModeStretch
priority:RCTImageLoaderPriorityImmediate
attribution:{
.surfaceId = surfaceId,
}
Expand Down

0 comments on commit 058eeb4

Please sign in to comment.