mirror of
https://github.com/facebook/react-native.git
synced 2025-11-01 09:14:26 +00:00
iOS Fabric: added support for image instrumentation [1]
Summary: Added basic hook to enable image instrumentation. The hook passes information to the existing image loader, where instrumentation is done, specific for each app, if any. Changelog: [Internal] Reviewed By: mdvacca Differential Revision: D19047899 fbshipit-source-id: 6c013806cce98bcf1ea240d696a7ede9697e5cd9
This commit is contained in:
committed by
Facebook Github Bot
parent
743074d09c
commit
55142efd3a
@@ -16,11 +16,6 @@
|
||||
#import <React/RCTImageCache.h>
|
||||
#import <React/RCTImageLoaderProtocol.h>
|
||||
|
||||
RCT_EXTERN BOOL RCTImageLoadingInstrumentationEnabled(void);
|
||||
RCT_EXTERN BOOL RCTImageLoadingPerfInstrumentationEnabled(void);
|
||||
RCT_EXTERN void RCTEnableImageLoadingInstrumentation(BOOL enabled);
|
||||
RCT_EXTERN void RCTEnableImageLoadingPerfInstrumentation(BOOL enabled);
|
||||
|
||||
@interface RCTImageLoader : NSObject <RCTBridgeModule, RCTImageLoaderProtocol>
|
||||
- (instancetype)init;
|
||||
- (instancetype)initWithRedirectDelegate:(id<RCTImageRedirectProtocol>)redirectDelegate NS_DESIGNATED_INITIALIZER;
|
||||
|
||||
@@ -10,6 +10,11 @@
|
||||
#import <React/RCTImageLoaderProtocol.h>
|
||||
#import <React/RCTImageURLLoaderWithAttribution.h>
|
||||
|
||||
RCT_EXTERN BOOL RCTImageLoadingInstrumentationEnabled(void);
|
||||
RCT_EXTERN BOOL RCTImageLoadingPerfInstrumentationEnabled(void);
|
||||
RCT_EXTERN void RCTEnableImageLoadingInstrumentation(BOOL enabled);
|
||||
RCT_EXTERN void RCTEnableImageLoadingPerfInstrumentation(BOOL enabled);
|
||||
|
||||
@protocol RCTImageLoaderWithAttributionProtocol<RCTImageLoaderProtocol>
|
||||
|
||||
/**
|
||||
|
||||
@@ -13,7 +13,9 @@
|
||||
#import <react/components/image/ImageEventEmitter.h>
|
||||
#import <react/components/image/ImageLocalData.h>
|
||||
#import <react/components/image/ImageProps.h>
|
||||
#import <react/imagemanager/ImageInstrumentation.h>
|
||||
#import <react/imagemanager/ImageRequest.h>
|
||||
#import <react/imagemanager/RCTImageInstrumentationProxy.h>
|
||||
#import <react/imagemanager/RCTImagePrimitivesConversions.h>
|
||||
|
||||
#import "RCTConversions.h"
|
||||
@@ -100,6 +102,12 @@
|
||||
// Loading actually starts a little before this, but this is the first time we know
|
||||
// the image is loading and can fire an event from this component
|
||||
std::static_pointer_cast<ImageEventEmitter const>(_eventEmitter)->onLoadStart();
|
||||
|
||||
// TODO (T58941612): Tracking for visibility should be done directly on this class.
|
||||
// For now, we consolidate instrumentation logic in the image loader, so that pre-Fabric gets the same treatment.
|
||||
auto instrumentation = std::static_pointer_cast<const RCTImageInstrumentationProxy>(
|
||||
_imageLocalData->getImageRequest().getSharedImageInstrumentation());
|
||||
instrumentation->trackNativeImageView(self);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -161,6 +169,8 @@
|
||||
// Apply trilinear filtering to smooth out mis-sized images.
|
||||
self->_imageView.layer.minificationFilter = kCAFilterTrilinear;
|
||||
self->_imageView.layer.magnificationFilter = kCAFilterTrilinear;
|
||||
|
||||
_imageLocalData->getImageRequest().getImageInstrumentation().didSetImage();
|
||||
}
|
||||
|
||||
- (void)didReceiveProgress:(float)progress fromObserver:(void const *)observer
|
||||
|
||||
@@ -64,6 +64,7 @@ rn_xplat_cxx_library(
|
||||
ios_exported_headers = subdir_glob(
|
||||
[
|
||||
("", "*.h"),
|
||||
("platform/ios", "RCTImageInstrumentationProxy.h"),
|
||||
("platform/ios", "RCTImagePrimitivesConversions.h"),
|
||||
],
|
||||
prefix = "react/imagemanager",
|
||||
|
||||
@@ -0,0 +1,40 @@
|
||||
/*
|
||||
* Copyright (c) Facebook, Inc. and its affiliates.
|
||||
*
|
||||
* This source code is licensed under the MIT license found in the
|
||||
* LICENSE file in the root directory of this source tree.
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <react/core/ReactPrimitives.h>
|
||||
|
||||
namespace facebook {
|
||||
namespace react {
|
||||
|
||||
/*
|
||||
* A base class for performing image loading instrumentation.
|
||||
* The actual instrumentation is app, platform, and image loader-specific.
|
||||
*/
|
||||
class ImageInstrumentation {
|
||||
public:
|
||||
virtual ~ImageInstrumentation() noexcept = default;
|
||||
|
||||
/**
|
||||
* Mark that the image content is set on the native image component on screen.
|
||||
*/
|
||||
virtual void didSetImage() const = 0;
|
||||
|
||||
/**
|
||||
* Mark that the image view starts to be visible on screen.
|
||||
*/
|
||||
virtual void didEnterVisibilityRange() const = 0;
|
||||
|
||||
/**
|
||||
* Mark that the image view is no longer visible on screen.
|
||||
*/
|
||||
virtual void didExitVisibilityRange() const = 0;
|
||||
};
|
||||
|
||||
} // namespace react
|
||||
} // namespace facebook
|
||||
@@ -7,6 +7,7 @@
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <react/imagemanager/ImageInstrumentation.h>
|
||||
#include <react/imagemanager/ImageResponse.h>
|
||||
#include <react/imagemanager/ImageResponseObserver.h>
|
||||
#include <react/imagemanager/ImageResponseObserverCoordinator.h>
|
||||
@@ -24,11 +25,12 @@ namespace react {
|
||||
*/
|
||||
class ImageRequest final {
|
||||
public:
|
||||
|
||||
/*
|
||||
* The default constructor
|
||||
*/
|
||||
ImageRequest(const ImageSource &imageSource);
|
||||
ImageRequest(
|
||||
const ImageSource &imageSource,
|
||||
std::shared_ptr<const ImageInstrumentation> instrumentation);
|
||||
|
||||
/*
|
||||
* The move constructor.
|
||||
@@ -61,6 +63,20 @@ class ImageRequest final {
|
||||
*/
|
||||
const ImageResponseObserverCoordinator &getObserverCoordinator() const;
|
||||
|
||||
/*
|
||||
* Returns stored image instrumentation object as a shared pointer.
|
||||
* Retain this *or* `ImageRequest` to ensure a correct lifetime of the object.
|
||||
*/
|
||||
const std::shared_ptr<const ImageInstrumentation>
|
||||
&getSharedImageInstrumentation() const;
|
||||
|
||||
/*
|
||||
* Returns the image instrumentation object specific to this request.
|
||||
* Use this if a correct lifetime of the object is ensured in some other way
|
||||
* (e.g. by retaining an `ImageRequest`).
|
||||
*/
|
||||
const ImageInstrumentation &getImageInstrumentation() const;
|
||||
|
||||
private:
|
||||
/*
|
||||
* Image source associated with the request.
|
||||
@@ -72,6 +88,11 @@ class ImageRequest final {
|
||||
*/
|
||||
std::shared_ptr<const ImageResponseObserverCoordinator> coordinator_{};
|
||||
|
||||
/*
|
||||
* Image instrumentation specific to the request.
|
||||
*/
|
||||
std::shared_ptr<const ImageInstrumentation> instrumentation_;
|
||||
|
||||
/*
|
||||
* Function we can call to cancel image request (see destructor).
|
||||
*/
|
||||
|
||||
@@ -24,7 +24,7 @@ ImageRequest ImageManager::requestImage(
|
||||
const ImageSource &imageSource,
|
||||
SurfaceId surfaceId) const {
|
||||
// Not implemented.
|
||||
return ImageRequest(imageSource);
|
||||
return ImageRequest(imageSource, nullptr);
|
||||
}
|
||||
|
||||
} // namespace react
|
||||
|
||||
@@ -10,8 +10,10 @@
|
||||
namespace facebook {
|
||||
namespace react {
|
||||
|
||||
ImageRequest::ImageRequest(const ImageSource &imageSource)
|
||||
: imageSource_(imageSource) {
|
||||
ImageRequest::ImageRequest(
|
||||
const ImageSource &imageSource,
|
||||
std::shared_ptr<const ImageInstrumentation> instrumentation)
|
||||
: imageSource_(imageSource), instrumentation_(instrumentation) {
|
||||
// Not implemented.
|
||||
}
|
||||
|
||||
|
||||
@@ -10,17 +10,21 @@
|
||||
namespace facebook {
|
||||
namespace react {
|
||||
|
||||
ImageRequest::ImageRequest(const ImageSource &imageSource)
|
||||
: imageSource_(imageSource) {
|
||||
ImageRequest::ImageRequest(
|
||||
const ImageSource &imageSource,
|
||||
std::shared_ptr<const ImageInstrumentation> instrumentation)
|
||||
: imageSource_(imageSource), instrumentation_(instrumentation) {
|
||||
coordinator_ = std::make_shared<ImageResponseObserverCoordinator>();
|
||||
}
|
||||
|
||||
ImageRequest::ImageRequest(ImageRequest &&other) noexcept
|
||||
: imageSource_(std::move(other.imageSource_)),
|
||||
coordinator_(std::move(other.coordinator_)) {
|
||||
coordinator_(std::move(other.coordinator_)),
|
||||
instrumentation_(std::move(other.instrumentation_)) {
|
||||
other.moved_ = true;
|
||||
other.coordinator_ = nullptr;
|
||||
other.cancelRequest_ = nullptr;
|
||||
other.instrumentation_ = nullptr;
|
||||
}
|
||||
|
||||
ImageRequest::~ImageRequest() {
|
||||
@@ -44,5 +48,14 @@ const std::shared_ptr<const ImageResponseObserverCoordinator>
|
||||
return coordinator_;
|
||||
}
|
||||
|
||||
const std::shared_ptr<const ImageInstrumentation>
|
||||
&ImageRequest::getSharedImageInstrumentation() const {
|
||||
return instrumentation_;
|
||||
}
|
||||
|
||||
const ImageInstrumentation &ImageRequest::getImageInstrumentation() const {
|
||||
return *instrumentation_;
|
||||
}
|
||||
|
||||
} // namespace react
|
||||
} // namespace facebook
|
||||
|
||||
@@ -0,0 +1,37 @@
|
||||
/*
|
||||
* Copyright (c) Facebook, Inc. and its affiliates.
|
||||
*
|
||||
* This source code is licensed under the MIT license found in the
|
||||
* LICENSE file in the root directory of this source tree.
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <React/RCTImageLoaderWithAttributionProtocol.h>
|
||||
|
||||
#include <react/core/ReactPrimitives.h>
|
||||
#include <react/imagemanager/ImageInstrumentation.h>
|
||||
|
||||
NS_ASSUME_NONNULL_BEGIN
|
||||
|
||||
namespace facebook {
|
||||
namespace react {
|
||||
|
||||
class RCTImageInstrumentationProxy final : public ImageInstrumentation {
|
||||
public:
|
||||
RCTImageInstrumentationProxy(id<RCTImageLoaderWithAttributionProtocol> imageLoader);
|
||||
|
||||
void didSetImage() const override;
|
||||
void didEnterVisibilityRange() const override;
|
||||
void didExitVisibilityRange() const override;
|
||||
|
||||
void trackNativeImageView(UIView *imageView) const;
|
||||
|
||||
private:
|
||||
__weak id<RCTImageLoaderWithAttributionProtocol> imageLoader_;
|
||||
};
|
||||
|
||||
} // namespace react
|
||||
} // namespace facebook
|
||||
|
||||
NS_ASSUME_NONNULL_END
|
||||
@@ -0,0 +1,57 @@
|
||||
/*
|
||||
* Copyright (c) Facebook, Inc. and its affiliates.
|
||||
*
|
||||
* This source code is licensed under the MIT license found in the
|
||||
* LICENSE file in the root directory of this source tree.
|
||||
*/
|
||||
|
||||
#import "RCTImageInstrumentationProxy.h"
|
||||
|
||||
namespace facebook {
|
||||
namespace react {
|
||||
|
||||
RCTImageInstrumentationProxy::RCTImageInstrumentationProxy(id<RCTImageLoaderWithAttributionProtocol> imageLoader)
|
||||
: imageLoader_(imageLoader)
|
||||
{
|
||||
}
|
||||
|
||||
void RCTImageInstrumentationProxy::didSetImage() const
|
||||
{
|
||||
if (!RCTImageLoadingPerfInstrumentationEnabled()) {
|
||||
return;
|
||||
}
|
||||
|
||||
// TODO (T58941612): Not yet supported.
|
||||
if (imageLoader_) {
|
||||
}
|
||||
}
|
||||
|
||||
void RCTImageInstrumentationProxy::didEnterVisibilityRange() const
|
||||
{
|
||||
if (!RCTImageLoadingPerfInstrumentationEnabled()) {
|
||||
return;
|
||||
}
|
||||
|
||||
// TODO (T58941612): Not yet supported.
|
||||
}
|
||||
|
||||
void RCTImageInstrumentationProxy::didExitVisibilityRange() const
|
||||
{
|
||||
if (!RCTImageLoadingPerfInstrumentationEnabled()) {
|
||||
return;
|
||||
}
|
||||
|
||||
// TODO (T58941612): Not yet supported.
|
||||
}
|
||||
|
||||
void RCTImageInstrumentationProxy::trackNativeImageView(UIView *imageView) const
|
||||
{
|
||||
if (!RCTImageLoadingPerfInstrumentationEnabled()) {
|
||||
return;
|
||||
}
|
||||
|
||||
// TODO (T58941612): Not yet supported.
|
||||
}
|
||||
|
||||
} // namespace react
|
||||
} // namespace facebook
|
||||
@@ -12,9 +12,11 @@
|
||||
#import <react/utils/SharedFunction.h>
|
||||
|
||||
#import <React/RCTImageLoaderWithAttributionProtocol.h>
|
||||
|
||||
#import <react/imagemanager/ImageResponse.h>
|
||||
#import <react/imagemanager/ImageResponseObserver.h>
|
||||
|
||||
#import "RCTImageInstrumentationProxy.h"
|
||||
#import "RCTImagePrimitivesConversions.h"
|
||||
|
||||
using namespace facebook::react;
|
||||
@@ -39,7 +41,7 @@ using namespace facebook::react;
|
||||
{
|
||||
SystraceSection s("RCTImageManager::requestImage");
|
||||
|
||||
auto imageRequest = ImageRequest(imageSource);
|
||||
auto imageRequest = ImageRequest(imageSource, std::make_unique<RCTImageInstrumentationProxy>(_imageLoader));
|
||||
auto weakObserverCoordinator =
|
||||
(std::weak_ptr<const ImageResponseObserverCoordinator>)imageRequest.getSharedObserverCoordinator();
|
||||
|
||||
|
||||
Reference in New Issue
Block a user