[Android][Fabric] A decoded local image can miss the current frame during a long mount
Maintainer thường phản hồi trong vòng 2 ngày
Chưa có ai nhận issue này.
Đánh giá
- Độ khó
- 4/5
- Thời gian dự kiến
- 3-5 ngày
- Mức phù hợp với người mới
- 38/100
- Loại issue
- Lỗi
- Độ rõ ràng
- Đặc tả rõ ràng
- Mức độ hoạt động
- Sôi nổi
- Công nghệ
- android, react-native
- Lĩnh vực
- mobile, performance
Hướng nghiên cứu
Start by tracing the named delivery path from AbstractDraweeController.submitRequest through DataSource.subscribe to SettableDraweeHierarchy.setImage, then reproduce on Android with the linked RNTester example. Compare a cold-cache miss with the synchronous cache-hit case while Fabric is mounting. Done means a result ready before drawing appears in that frame rather than a later one.
Do mô hình lập chỉ mục viết ra từ nội dung của issue.
Mô tả
Description
On Android with Fabric, a local Image that misses Fresco's bitmap memory cache can be drawn with its placeholder even when its decoded result is ready before that frame is drawn. The image is applied one or more frames later.
The reproducer mounts two Image components with the same local source in one commit:
- Image A uses
cache: 'reload', which evicts that URI before requesting it. - A small but nested vote-list subtree is mounted between A and B.
- A is decoded on a background thread while the UI thread is processing the mount.
- Image B is submitted later and synchronously hits the bitmap that A has placed in the memory cache.
The first visible frame can therefore contain A's gray placeholder and B's image, even though both use the same source.
The delivery path for A is:
AbstractDraweeController.submitRequest
→ DataSource.subscribe(subscriber, uiThreadExecutor)
→ a Handler message posted to the UI thread
→ SettableDraweeHierarchy.setImage
When the result becomes ready while the UI thread is already inside a long Choreographer.doFrame, the posted message cannot run between Fabric's mount work and traversal/draw because they execute inside the same frame message. The frame is drawn with the placeholder. If another overdue frame starts before the posted result message, the delay is amplified by that frame as well.
sequenceDiagram
participant UI as UI thread
participant BG as Fresco background thread
UI->>BG: Submit A, bitmap memory-cache miss
UI->>UI: Continue Fabric mount work
BG-->>UI: Decode A, post result Handler message
UI->>UI: Submit B, bitmap memory-cache hit
UI->>UI: Draw frame with A placeholder and B image
UI->>UI: Run A result message after the frame
UI->>UI: Draw A image in a later frame
This is intermittent in applications because a bitmap memory-cache hit is delivered synchronously and avoids the problem. A miss occurs on first use, after eviction or cache trimming, and when an app clears Fresco's memory cache. The reproducer uses cache: 'reload' only to make A start cold on every run.
On React Native 0.88.0, screen recording captured the A-placeholder/B-image frame in 10 of 10 runs with the final reproducer on a Vivo V2338A running Android 16 (API 36). The measured B-to-A display delays were:
78, 67, 67, 62, 10, 75, 77, 74, 68, 75 ms
Median: approximately 71 ms. Nine of the ten runs lasted 62–78 ms.
In a production app, the same pattern occurs with a local file:// button image during the first commit of a screen and remains visible for approximately 19–60 ms.
Expected behavior: if an image result is ready before a frame is drawn, that frame should draw the image, matching the behavior of a synchronous bitmap memory-cache hit.
Steps to reproduce
-
Check out React Native
0.88-stableat99d4ed39851392b4c65fd38fe3812669cb493376. -
Replace
packages/rn-tester/js/examples/Playground/RNTesterPlayground.jswith the linked reproducer. -
Build and install the Android release variant so that the JavaScript bundle and local assets are packaged in the APK:
./gradlew --no-daemon --max-workers=1 :packages:rn-tester:android:app:assembleRelease adb install -r packages/rn-tester/android/app/build/outputs/apk/release/app-arm64-v8a-release.apk -
Open the RNTester Playground:
adb shell "am start -a android.intent.action.VIEW -d 'rntester://example/PlaygroundExample' com.facebook.react.uiapp" -
After approximately one second, observe the first frame containing A and B. A shows its gray placeholder while B already shows the same image.
-
Tap Run again to repeat.
The first commit inserts image A, four nested vote-list rows with real local images, and image B. A second commit adds 20 more rows. The list is scrollable.
React Native Version
0.88.0
Tested from 0.88-stable commit:
99d4ed39851392b4c65fd38fe3812669cb493376
The same underlying behavior was also observed on main at:
b8ec87e457c72377dab85599e1ae8c176eb242e7
Affected Platforms
Select:
Runtime - Android
Areas
Select:
Fabric - The New Renderer
Output of npx @react-native-community/cli info
The command was run from the RNTester monorepo checkout. The CLI does not infer RNTester's workspace packages or Gradle architecture setting correctly, so it reports package entries as Not Found and newArchEnabled: false. The actual RNTester Android configuration used for the reproduction has newArchEnabled=true.
System:
OS: macOS 27.0.1
CPU: (10) arm64 Apple M5
Memory: 64.22 MB / 24.00 GB
Shell:
version: 4.9.3
path: /opt/homebrew/bin/fish
Binaries:
Node:
version: 22.22.3
path: ~/.local/state/fnm_multishells/34159_1791960164938/bin/node
Yarn:
version: 1.22.22
path: ~/.local/state/fnm_multishells/34159_1791960164938/bin/yarn
npm:
version: 10.9.8
path: ~/.local/state/fnm_multishells/34159_1791960164938/bin/npm
Watchman:
version: 2026.07.27.00
path: /opt/homebrew/bin/watchman
Managers:
CocoaPods:
version: 1.16.2
path: /Users/admin/.rbenv/shims/pod
SDKs:
iOS SDK:
Platforms:
- DriverKit 27.0
- iOS 27.0
- macOS 27.0
- tvOS 27.0
- visionOS 27.0
- watchOS 27.0
Android SDK: Not Found
IDEs:
Android Studio: 2026.2 AI-262.9437.185.2621.16467767
Xcode:
version: 27.0/27A266a
path: /usr/bin/xcodebuild
Languages:
Java:
version: 17.0.20.1
path: /usr/bin/javac
Ruby:
version: 2.6.10
path: /usr/bin/ruby
npmPackages:
"@react-native-community/cli": Not Found
react: Not Found
react-native: Not Found
react-native-macos: Not Found
npmGlobalPackages:
"*react-native*": Not Found
Android:
hermesEnabled: false
newArchEnabled: false
iOS:
hermesEnabled: true
newArchEnabled: false
Stacktrace or Logs
No crash or JavaScript error is logged.
Final RNTesterPlayground reproduction on React Native 0.88.0:
10/10 screen recordings captured A's placeholder while B already showed the image.
B-to-A display delays:
78, 67, 67, 62, 10, 75, 77, 74, 68, 75 ms
Median: approximately 71 ms; 9/10 runs lasted 62–78 ms.
MANDATORY Reproducer
https://github.com/fairysword/react-native/blob/9bc67419dfbde083cf258af46aa27f504836034c/packages/rn-tester/js/examples/Playground/RNTesterPlayground.js
Screenshots
- Ngôn ngữ chính
- C++
- Star
- 127k
- Fork
- 25.5k
- Merge trung bình
- 3 ngày 18 giờ
- Pull request đã merge (30 ngày)
- 188
Chuẩn bị môi trường
- Không có Dockerfile hay tệp Docker Compose
- Có mẫu pull request
- Đọc hướng dẫn đóng góp
Bắt đầu từ đâu
- Đọc hết issue, rồi đọc hướng dẫn đóng góp của dự án.
- Bình luận trên issue rằng bạn sẽ nhận — tránh hai người làm cùng một việc.
- Fork repository và làm thay đổi trên một nhánh.
- Mở pull request có tham chiếu số hiệu của issue.
Issue khác của react/react-native
-
Độ khó 2/5 1-3 giờ Mức phù hợp với người mới 76/100
react/react-native#59945 ·
Maintainer thường phản hồi trong vòng 2 ngày
-
Độ khó 2/5 1-3 giờ Mức phù hợp với người mới 82/100
react/react-native#59944 ·
Maintainer thường phản hồi trong vòng 2 ngày
-
Độ khó 2/5 1-3 giờ Mức phù hợp với người mới 78/100
react/react-native#59942 ·
Maintainer thường phản hồi trong vòng 2 ngày
-
Độ khó 2/5 1-3 giờ Mức phù hợp với người mới 76/100
react/react-native#59939 ·
Maintainer thường phản hồi trong vòng 2 ngày
-
Độ khó 2/5 1-3 giờ Mức phù hợp với người mới 78/100
react/react-native#59929 · 1 bình luận ·
Maintainer thường phản hồi trong vòng 2 ngày
Tất cả issue của react/react-native
Issue tương tự
-
test(tools): two testkit cache tests fail unless GOCACHE and GOMODCACHE are in the environmentĐang mởbacklog
Độ khó 2/5 1-3 giờ Mức phù hợp với người mới 78/100
EchoTools/nevr-runtime#2385 ·
Maintainer thường phản hồi trong vòng 1 ngày
-
type:bug
Độ khó 2/5 1-3 giờ Mức phù hợp với người mới 65/100
tensorflow/tflite-micro#3995 ·
Maintainer thường phản hồi trong vòng 1 ngày
-
CPU update 1.31xĐang mởspeed-report
Độ khó 1/5 Dưới một giờ Mức phù hợp với người mới 75/100
mw00/project-maya#961 · 1 bình luận ·
Maintainer thường phản hồi trong vòng 1 ngày
-
Độ khó 2/5 1-3 giờ Mức phù hợp với người mới 78/100
-
not for AI lovers
Độ khó 2/5 1-3 giờ Mức phù hợp với người mới 76/100
OSGeo/gdal#15515 · 1 bình luận ·
Maintainer thường phản hồi trong vòng 1 ngày