Worklet = block JS code được compile thành standalone function chạy trên UI thread, không cần roundtrip về JS thread.
useSharedValue(initial) tạo object có .value → đọc/ghi từ cả JS thread và UI thread. Internal là object C++ shared memory.
useAnimatedStyle(() => {...}, deps) marker 'worklet' ngầm — function callback được transform thành worklet bởi react-native-reanimated/plugin (Babel plugin). Mỗi frame UI thread gọi worklet → style mới → áp lên Fabric ShadowTree → render.
const progress = useSharedValue(0)
// Worklet — chạy UI thread, đọc shared value sync
const style = useAnimatedStyle(() => {
return {
opacity: progress.value,
transform: [{ scale: 1 + progress.value * 0.5 }],
}
})
// JS thread set value → trigger worklet rerun on UI thread
progress.value = withSpring(1)Why fast:
- Không bridge serialize.
- Không chờ JS thread rảnh.
- 60–120 FPS guaranteed dù JS thread đang busy parse JSON 100MB.
Lưu ý:
- Worklet không access được variable bên ngoài trừ khi capture qua dependency array — closure không hoạt động như JS thường.
- Console.log bên trong worklet không hiện trong JS console (UI thread riêng) — dùng runOnJS(console.log)(value) để log.
- Babel plugin react-native-reanimated/plugin phải là plugin cuối trong babel.config.js.
A worklet is a JS code block compiled into a standalone function that runs on the UI thread without round-tripping to the JS thread.
useSharedValue(initial) creates an object with .value — readable/writable from both the JS thread and the UI thread. Internally a C++ shared-memory object.
useAnimatedStyle(() => {...}, deps) has an implicit 'worklet' marker — the callback is transformed into a worklet by the react-native-reanimated/plugin Babel plugin. Each frame, the UI thread invokes the worklet → produces a new style → applies it to the Fabric ShadowTree → renders.
const progress = useSharedValue(0)
// Worklet — runs on UI thread, reads shared value synchronously
const style = useAnimatedStyle(() => ({
opacity: progress.value,
transform: [{ scale: 1 + progress.value * 0.5 }],
}))
// JS thread sets value → triggers worklet rerun on UI thread
progress.value = withSpring(1)Why it is fast:
- No bridge serialization.
- No waiting on the JS thread to be free.
- 60–120 FPS guaranteed even while the JS thread parses 100 MB of JSON.
Pitfalls:
- A worklet cannot capture outer variables through normal closure — they must be passed via the dependency array.
- console.log inside a worklet does not show in the JS console (different thread) — use runOnJS(console.log)(value) to log.
- The react-native-reanimated/plugin Babel plugin must be last in babel.config.js.