Skip to content

Commit d4ae881

Browse files
sammy-SCmeta-codesync[bot]
authored andcommitted
Add image request priority debug overlay (#56970)
Summary: Pull Request resolved: #56970 changelog: [internal] Add an opt-in `RCT_IMAGE_REQUEST_PRIORITY_DEBUG_OVERLAY` label for Fabric image component views so local debugging can show whether an image request is using immediate priority or the offscreen prefetch path. Reviewed By: christophpurrer Differential Revision: D106363533 fbshipit-source-id: ae68c9a5849dc6507f7611e02c217b674f899bd6
1 parent 5fbcc6b commit d4ae881

1 file changed

Lines changed: 76 additions & 0 deletions

File tree

packages/react-native/React/Fabric/Mounting/ComponentViews/Image/RCTImageComponentView.mm

Lines changed: 76 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@
1111
#import <React/RCTConversions.h>
1212
#import <React/RCTImageBlurUtils.h>
1313
#import <React/RCTImageResponseObserverProxy.h>
14+
#import <react/featureflags/ReactNativeFeatureFlags.h>
1415
#import <react/renderer/components/image/ImageComponentDescriptor.h>
1516
#import <react/renderer/components/image/ImageEventEmitter.h>
1617
#import <react/renderer/components/image/ImageProps.h>
@@ -19,9 +20,40 @@
1920

2021
using namespace facebook::react;
2122

23+
static NSString *const RCTImageRequestPriorityDebugOverlayEnabledEnvironmentVariable =
24+
@"RCT_IMAGE_REQUEST_PRIORITY_DEBUG_OVERLAY";
25+
26+
static BOOL RCTImageRequestPriorityDebugOverlayEnabled()
27+
{
28+
if (ReactNativeFeatureFlags::enableImageRequestDowngradingForNonVisibleImages()) {
29+
static BOOL enabled = NO;
30+
static dispatch_once_t onceToken;
31+
dispatch_once(&onceToken, ^{
32+
NSDictionary<NSString *, NSString *> *environment = [[NSProcessInfo processInfo] environment];
33+
enabled = [environment[RCTImageRequestPriorityDebugOverlayEnabledEnvironmentVariable] boolValue];
34+
});
35+
return enabled;
36+
} else {
37+
return NO;
38+
}
39+
}
40+
41+
static NSString *RCTImageRequestPriorityDebugLabel(ImageRequestPriority priority)
42+
{
43+
switch (priority) {
44+
case ImageRequestPriority::Immediate:
45+
return @"immediate";
46+
case ImageRequestPriority::Prefetch:
47+
return @"offscreen";
48+
default:
49+
return @"unknown";
50+
}
51+
}
52+
2253
@implementation RCTImageComponentView {
2354
ImageShadowNode::ConcreteState::Shared _state;
2455
std::shared_ptr<RCTImageResponseObserverProxy> _imageResponseObserverProxy;
56+
UILabel *_requestPriorityLabel;
2557
}
2658

2759
- (instancetype)initWithFrame:(CGRect)frame
@@ -85,6 +117,7 @@ - (void)updateState:(const State::Shared &)state oldState:(const State::Shared &
85117
auto newImageState = std::static_pointer_cast<const ImageShadowNode::ConcreteState>(state);
86118

87119
[self _setStateAndResubscribeImageResponseObserver:newImageState];
120+
[self _updateRequestPriorityLabelWithState:newImageState];
88121

89122
bool havePreviousData = oldImageState && oldImageState->getData().getImageSource() != ImageSource{};
90123

@@ -115,10 +148,53 @@ - (void)_setStateAndResubscribeImageResponseObserver:(const ImageShadowNode::Con
115148
}
116149
}
117150

151+
- (UILabel *)_requestPriorityLabel
152+
{
153+
if (!_requestPriorityLabel) {
154+
_requestPriorityLabel = [UILabel new];
155+
_requestPriorityLabel.accessibilityElementsHidden = YES;
156+
_requestPriorityLabel.backgroundColor = [UIColor colorWithWhite:0 alpha:0.65];
157+
_requestPriorityLabel.clipsToBounds = YES;
158+
_requestPriorityLabel.font = [UIFont systemFontOfSize:10 weight:UIFontWeightSemibold];
159+
_requestPriorityLabel.hidden = YES;
160+
_requestPriorityLabel.isAccessibilityElement = NO;
161+
_requestPriorityLabel.layer.cornerRadius = 3;
162+
_requestPriorityLabel.textAlignment = NSTextAlignmentCenter;
163+
_requestPriorityLabel.textColor = UIColor.whiteColor;
164+
[_imageView addSubview:_requestPriorityLabel];
165+
}
166+
167+
return _requestPriorityLabel;
168+
}
169+
170+
- (void)_updateRequestPriorityLabelWithState:(const ImageShadowNode::ConcreteState::Shared &)state
171+
{
172+
if (!state || !RCTImageRequestPriorityDebugOverlayEnabled()) {
173+
if (_requestPriorityLabel) {
174+
_requestPriorityLabel.hidden = YES;
175+
_requestPriorityLabel.text = nil;
176+
}
177+
return;
178+
}
179+
180+
UILabel *requestPriorityLabel = [self _requestPriorityLabel];
181+
requestPriorityLabel.text = RCTImageRequestPriorityDebugLabel(state->getData().getImageRequestParams().priority);
182+
[requestPriorityLabel sizeToFit];
183+
184+
CGRect frame = requestPriorityLabel.frame;
185+
frame.origin = CGPointMake(2, 2);
186+
frame.size.width += 8;
187+
frame.size.height += 4;
188+
requestPriorityLabel.frame = frame;
189+
requestPriorityLabel.hidden = NO;
190+
[_imageView bringSubviewToFront:requestPriorityLabel];
191+
}
192+
118193
- (void)prepareForRecycle
119194
{
120195
[super prepareForRecycle];
121196
[self _setStateAndResubscribeImageResponseObserver:nullptr];
197+
[self _updateRequestPriorityLabelWithState:nullptr];
122198
_imageView.image = nil;
123199
}
124200

0 commit comments

Comments
 (0)