You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Side-by-side dev builds (expo run:ios --device / mobile:ios:device) on the same iPhone 17 Pro, same hesprs-demo fixture, same SDK 55 stack, the Workspace mobile app feels very slightly snappier than our playground. No dropped frames in Workspace; occasional minor hitching in the playground.
Release builds (ios:run:device:release) are exponentially better in the playground and at least at parity, plausibly faster, than Workspace mobile. So the gap is dev-mode specific.
What we already aligned (this is why the gap is small)
Same renderer source (verified byte-identical via diff)
Same SDK (Expo 55)
Same React (19.2.0), RN (0.83.x patch only)
Same Skia, Reanimated, Worklets, Gesture-Handler versions
Same babel pattern (worklets plugin loaded via Node resolution, preset auto-detect disabled)
Same expo-dev-client
Same experiments.reactCompiler: true
Same react-native-safe-area-context
What we did NOT replicate (because none should plausibly affect canvas dev perf)
expo-router + react-native-screens (no navigation in playground)
expo-image, expo-symbols, expo-glass-effect (cosmetic, not on the render path)
expo-splash-screen (launch-time only)
zustand state management (no app state)
react-native-enriched-markdown (renderMarkdown is vestigial — TextNodeContent returns null and text always renders via Skia)
iOS infoPlist UTI registration for .canvas (we load from inline fixture)
with-canvas-uti Expo config plugin
Theories not investigated
Stable component-instance identity. Workspace's screen lives under expo-router's Stack.Screen which provides a stable parent instance; our App.tsx is the root component re-rendering on every setLastAction. React Compiler should mostly handle this, but possibly not perfectly.
Native-thread scheduling differences from expo-router. Router-rendered screens get screen-stack native rendering on iOS via react-native-screens — could change CoreAnimation scheduling priorities.
Hermes snapshot differences. The two apps have different module graphs; Hermes' inline cache hit/miss patterns differ.
Metro fast-refresh module-id stability. Workspace's larger bundle may produce more stable module IDs across reloads, reducing HMR churn.
Why this is parking-lot
The gap is sub-perception in the conversation that produced it ("ever so slightly snappier") and is dev-mode only.
Release-build perf is what ships and that's at or above parity.
Profiling would be required to characterise the gap concretely; gut estimates are not reliable here.
Every alignment we tried that could plausibly close it has been applied. Further chasing is yak-shaving until there's a concrete bottleneck to point at.
When to revisit
If a real consumer of @workspace.sh/react-native-jsoncanvas reports a similar dev-mode perf issue
Observation
Side-by-side dev builds (
expo run:ios --device/mobile:ios:device) on the same iPhone 17 Pro, same hesprs-demo fixture, same SDK 55 stack, the Workspace mobile app feels very slightly snappier than our playground. No dropped frames in Workspace; occasional minor hitching in the playground.Release builds (
ios:run:device:release) are exponentially better in the playground and at least at parity, plausibly faster, than Workspace mobile. So the gap is dev-mode specific.What we already aligned (this is why the gap is small)
expo-dev-clientexperiments.reactCompiler: truereact-native-safe-area-contextWhat we did NOT replicate (because none should plausibly affect canvas dev perf)
expo-router+react-native-screens(no navigation in playground)expo-image,expo-symbols,expo-glass-effect(cosmetic, not on the render path)expo-splash-screen(launch-time only)zustandstate management (no app state)react-native-enriched-markdown(renderMarkdownis vestigial —TextNodeContentreturns null and text always renders via Skia)infoPlistUTI registration for.canvas(we load from inline fixture)with-canvas-utiExpo config pluginTheories not investigated
Stack.Screenwhich provides a stable parent instance; ourApp.tsxis the root component re-rendering on everysetLastAction. React Compiler should mostly handle this, but possibly not perfectly.expo-router. Router-rendered screens get screen-stack native rendering on iOS viareact-native-screens— could change CoreAnimation scheduling priorities.Why this is parking-lot
When to revisit
@workspace.sh/react-native-jsoncanvasreports a similar dev-mode perf issueHow to investigate if revisited
expo run:ios --configuration Debugwith profiler enabled) to capture JS-thread time per appRefs
Surfaced during PR #22 (Expo playground). Mentioned in commit 4b7f127's body.