mirror of
https://github.com/status-im/react-native.git
synced 2025-01-10 09:35:48 +00:00
5903949ad6
Summary: This uses `[UIImage imageNamed:]` to load local assets that are bundled using `require('../image/path.png')` and makes sure it is done synchronously on the main queue to prevent images from flickering. This improves user experience a lot when using large local images and prevents icon flickers to match the behaviour of most native apps. This adds to methods to the ImageLoader protocol, one to tell if the image loader must be executed on the url cache queue and one to tell if the result of the image loader should be cached. I then use these to make the LocalImageLoader bypass the url cache queue and avoid caching images twice. Note that this doesn't affect debug builds since images are loaded from the packager. I'm not sure if we want to still support async loading of local images as I'm not sure how much of a perf difference this will make. Maybe someone at fb can benchmark this see how it affects your apps but there wasn't a noticeable one in mine. Also I only enabled this for loading png and jpg im Closes https://github.com/facebook/react-native/pull/8102 Reviewed By: bnham Differential Revision: D3433647 Pulled By: javache fbshipit-source-id: 37bd6aff20c0465c163db3cdbcaeaedff55f7b1f
71 lines
1.9 KiB
Objective-C
71 lines
1.9 KiB
Objective-C
/**
|
|
* Copyright (c) 2015-present, Facebook, Inc.
|
|
* All rights reserved.
|
|
*
|
|
* This source code is licensed under the BSD-style license found in the
|
|
* LICENSE file in the root directory of this source tree. An additional grant
|
|
* of patent rights can be found in the PATENTS file in the same directory.
|
|
*/
|
|
|
|
#import "RCTLocalAssetImageLoader.h"
|
|
|
|
#import <libkern/OSAtomic.h>
|
|
|
|
#import "RCTUtils.h"
|
|
|
|
@implementation RCTLocalAssetImageLoader
|
|
|
|
RCT_EXPORT_MODULE()
|
|
|
|
- (BOOL)canLoadImageURL:(NSURL *)requestURL
|
|
{
|
|
return RCTIsLocalAssetURL(requestURL);
|
|
}
|
|
|
|
- (BOOL)requiresScheduling
|
|
{
|
|
// Don't schedule this loader on the URL queue so we can load the
|
|
// local assets synchronously to avoid flickers.
|
|
return NO;
|
|
}
|
|
|
|
- (BOOL)shouldCacheLoadedImages
|
|
{
|
|
// UIImage imageNamed handles the caching automatically so we don't want
|
|
// to add it to the image cache.
|
|
return NO;
|
|
}
|
|
|
|
- (RCTImageLoaderCancellationBlock)loadImageForURL:(NSURL *)imageURL
|
|
size:(CGSize)size
|
|
scale:(CGFloat)scale
|
|
resizeMode:(RCTResizeMode)resizeMode
|
|
progressHandler:(RCTImageLoaderProgressBlock)progressHandler
|
|
completionHandler:(RCTImageLoaderCompletionBlock)completionHandler
|
|
{
|
|
__block volatile uint32_t cancelled = 0;
|
|
RCTExecuteOnMainQueue(^{
|
|
if (cancelled) {
|
|
return;
|
|
}
|
|
|
|
NSString *imageName = RCTBundlePathForURL(imageURL);
|
|
UIImage *image = [UIImage imageNamed:imageName];
|
|
if (image) {
|
|
if (progressHandler) {
|
|
progressHandler(1, 1);
|
|
}
|
|
completionHandler(nil, image);
|
|
} else {
|
|
NSString *message = [NSString stringWithFormat:@"Could not find image named %@", imageName];
|
|
completionHandler(RCTErrorWithMessage(message), nil);
|
|
}
|
|
});
|
|
|
|
return ^{
|
|
OSAtomicOr32Barrier(1, &cancelled);
|
|
};
|
|
}
|
|
|
|
@end
|