Shopify / Shopify/react-native-skia
Canvas renders transparent after resuming app from long background on iOS
Nobody has claimed this yet.
- Dominant language
- TypeScript
- Stars
- 8.6k
- Forks
- 647
- Avg merge
- 1d 17h
- Merged PRs (30d)
- 35
Description
Description
Our app uses multiple Skia Canvas components as cards / discs backgrounds across the home screen.
After the app has been in the background for an extended period on iOS (e.g. overnight), bringing it back to the foreground results in Canvas components rendering as completely transparent (black is the default background color of the large cards in the attached videos), as if the rendering context was lost or invalidated during background suspension and not recovered by Skia on resume.
Key observations:
- Only reproduced on real iOS device builds so far. We have not been able to reproduce on the iOS Simulator, though we haven't tested leaving a simulator in the background for hours — it's possible the simulator simply doesn't suspend the app as aggressively as a real device.
- Only happens when the app resumes from background (no splash screen shown). When iOS fully kills the app and shows the splash screen on relaunch, the Canvas renders correctly because everything initializes fresh.
- Not confirmed on Android. Android tends to trigger full reloads more often when returning from a long background, which avoids the issue entirely. We haven't tested extensively enough to confirm.
- This may be related to Metal context invalidation during long background suspension, but we haven't confirmed the exact native-level cause.
React Native Skia Version
2.4.7
React Native Version
0.81.5 (Expo SDK 54)
Using New Architecture
- Enabled
Steps to Reproduce
- Build and install the app on a real iOS device
- Open the app and navigate to a screen with a Skia
Canvascomponent rendering visual elements (e.g. a background fill, shapes, etc.) - Confirm the Canvas renders correctly
- Put the app in the background
- Wait for an extended period (we reliably see this after leaving the app in background overnight — shorter durations may not trigger it)
- Bring the app back to the foreground (the app must resume without a full reload — i.e. no splash screen)
- Observe: Canvas renders as black/transparent, content is missing
Snack, Code Example, Screenshot, or Link to Repository
Attempted workaround (exploratory)
As an exploration to understand the issue, we created a RemountedCanvasOnForeground wrapper that listens to AppState changes and forces a remount of the Canvas (via a key increment) when the app returns to foreground after being in background for more than 30 seconds:
// RemountedCanvasOnForeground.tsx
import { Canvas, type CanvasProps } from "@shopify/react-native-skia";
export const RemountedCanvasOnForeground = (props: CanvasProps) => {
const key = useForegroundRemountKey();
return <Canvas key={key} {...props} />;
};
// useForegroundRemountKey.ts
export const useForegroundRemountKey = () => {
const [key, setKey] = useState(0);
const backgroundTimestamp = useRef<number | null>(null);
useAppStateListener({
onBackground: () => {
backgroundTimestamp.current = Date.now();
},
onForeground: () => {
if (Platform.OS !== "ios") {
backgroundTimestamp.current = null;
return;
}
const wasInBackgroundLongEnough =
backgroundTimestamp.current &&
Date.now() - backgroundTimestamp.current > 30000;
if (wasInBackgroundLongEnough) {
setKey((prev) => prev + 1);
}
backgroundTimestamp.current = null;
},
});
return key;
};
This partially works — when the key increment triggers a re-render, the Canvas remounts and renders correctly. However, the re-render is not always triggered on the first foreground event after a long background. When opening the app a second time shortly after, the remount works correctly.
This is not a solution we intend to ship — it's a JS-side workaround we used to confirm that the issue lies in the native rendering layer. Ideally, Skia should automatically recover its rendering context when the app returns to foreground, without requiring a full component remount from the React side.
Screenshots / Videos
Video 1 — Canvas recovering after a second foreground (black rectangles are visible before content properly re-render):
https://github.com/user-attachments/assets/652ef9b0-5e1f-4f84-906a-8bb1e39feb90
Video 2 — Canvas NOT recovering on first foreground (stays black):
https://github.com/user-attachments/assets/d7af6665-e247-4d98-aac7-7e8fd5aa4e8b
Contributor guide
No contributing guide indexed for this repository
First steps
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up — it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- Open a pull request that references the issue number.
Research direction
Use the real-device reproduction with React Native Skia 2.4.7 and the examples in RemountedCanvasOnForeground.tsx and useForegroundRemountKey.ts as a reference. Then trace the native iOS rendering lifecycle around foregrounding and Metal context recovery. Done means Canvas content reliably returns on the first foreground after an extended background period without a React-side remount.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- ios, react-native, typescript
- Domain
- computer-graphics, mobile
- Issue type
- Bug
- Difficulty
- 4/5
- Estimated time
- 3-5 days
- Activity status
- Quiet
- Clarity
- Mostly clear
- Newbie friendliness
- 45/100