<?xml version="1.0" encoding="UTF-8"?><rss xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:content="http://purl.org/rss/1.0/modules/content/" xmlns:atom="http://www.w3.org/2005/Atom" version="2.0" xmlns:cc="http://cyber.law.harvard.edu/rss/creativeCommonsRssModule.html">
    <channel>
        <title><![CDATA[Stories by Minindu Alwis on Medium]]></title>
        <description><![CDATA[Stories by Minindu Alwis on Medium]]></description>
        <link>https://medium.com/@miniduminidu100?source=rss-5ebc298a8654------2</link>
        <image>
            <url>https://cdn-images-1.medium.com/fit/c/150/150/0*mDLYegvYVJfhjuEX</url>
            <title>Stories by Minindu Alwis on Medium</title>
            <link>https://medium.com/@miniduminidu100?source=rss-5ebc298a8654------2</link>
        </image>
        <generator>Medium</generator>
        <lastBuildDate>Thu, 28 May 2026 17:00:41 GMT</lastBuildDate>
        <atom:link href="https://medium.com/@miniduminidu100/feed" rel="self" type="application/rss+xml"/>
        <webMaster><![CDATA[yourfriends@medium.com]]></webMaster>
        <atom:link href="http://medium.superfeedr.com" rel="hub"/>
        <item>
            <title><![CDATA[How React Native Handles Threads ]]></title>
            <link>https://medium.com/@miniduminidu100/how-react-native-handles-threads-8a1f4876e3ca?source=rss-5ebc298a8654------2</link>
            <guid isPermaLink="false">https://medium.com/p/8a1f4876e3ca</guid>
            <category><![CDATA[reactjs]]></category>
            <category><![CDATA[threads]]></category>
            <category><![CDATA[react-native]]></category>
            <category><![CDATA[react-native-threads]]></category>
            <dc:creator><![CDATA[Minindu Alwis]]></dc:creator>
            <pubDate>Fri, 15 May 2026 09:37:29 GMT</pubDate>
            <atom:updated>2026-05-15T09:47:41.683Z</atom:updated>
            <content:encoded><![CDATA[<figure><img alt="" src="https://cdn-images-1.medium.com/max/800/1*9kJvJP782p8r878DIKYlpw.gif" /></figure><p>If you’ve ever wondered why some React Native apps feel smooth and others feel laggy — it all comes down to <strong>how threads work</strong>.</p><p>Let me break it down simply. No jargon. Just the real stuff.</p><h3>First — What is a Thread?</h3><p>Think of a thread like a <strong>worker in a kitchen</strong>.</p><p>Each worker has one job. If one worker gets stuck, the whole kitchen slows down.</p><p>React Native has <strong>3 main workers (threads)</strong>:</p><p>Thread Job <strong>UI Thread</strong> Draws buttons, text, animations on screen <strong>JS Thread</strong> Runs your JavaScript / React code <strong>Native Thread</strong> Handles device features (camera, storage, etc.)</p><p>These 3 threads need to <strong>talk to each other</strong> constantly. And <em>how</em> they talk — that’s where everything changes.</p><h3>The Old Way — The Bridge 🌉</h3><p>In the old React Native architecture, all 3 threads talked through something called the <strong>Bridge</strong>.</p><p>Imagine the Bridge like a <strong>post office</strong>. Every message had to be:</p><ol><li>Packed into a box (serialized to JSON)</li><li>Sent to the post office</li><li>Delivered to the other thread</li><li>Unpacked (deserialized)</li></ol><p>This worked — but it was <strong>slow and heavy</strong>.</p><h3>Old Architecture Example</h3><pre>// OLD WAY — calling a native module through the Bridge</pre><pre>import { NativeModules } from &#39;react-native&#39;;</pre><pre>const getUserData = async () =&gt; {<br>  // This call crosses the Bridge<br>  // JS → serialize to JSON → Bridge → deserialize → Native<br>  // Then Native → serialize → Bridge → deserialize → JS<br>  const user = await NativeModules.UserModule.getUser();<br>  console.log(user);<br>};</pre><p>Every single call had to do this full round trip. If you had 5 calls on one screen — 5 round trips. Slow. Laggy. Frames dropping.</p><h3>The Real Problem</h3><pre>// OLD WAY — scroll animation with the Bridge (bad)</pre><pre>import { Animated } from &#39;react-native&#39;;</pre><pre>const MyScreen = () =&gt; {<br>  const scrollY = new Animated.Value(0);</pre><pre>  const handleScroll = (event) =&gt; {<br>    // Every scroll event → goes to JS thread → crosses Bridge → updates UI<br>    // JS thread busy? Animation freezes. User sees jank. 😬<br>    scrollY.setValue(event.nativeEvent.contentOffset.y);<br>  };</pre><pre>  return (<br>    &lt;ScrollView onScroll={handleScroll} scrollEventThrottle={16}&gt;<br>      &lt;Animated.View style={{ opacity: scrollY }} /&gt;<br>    &lt;/ScrollView&gt;<br>  );<br>};</pre><p>The problem here: <strong>every scroll event goes through JS → Bridge → UI</strong>. If your JS thread is doing anything else (fetching data, rendering) — your animation freezes. That’s the jank you feel.</p><h3>The New Way — JSI (No Bridge!) ⚡</h3><p>The new React Native architecture replaced the Bridge with <strong>JSI</strong> (JavaScript Interface).</p><p>Instead of a post office, JSI is like giving each worker a <strong>direct phone line</strong> to the others.</p><ul><li>No packing boxes ❌</li><li>No post office ❌</li><li>No waiting ❌</li></ul><p>Just a <strong>direct call</strong>. Instant.</p><h3>New Architecture Example</h3><pre>// NEW WAY — TurboModules with JSI (direct call, no bridge)</pre><pre>import { NativeModules } from &#39;react-native&#39;;<br>// TurboModules work the same way in your JS code<br>// but under the hood — NO Bridge, NO JSON, direct C++ call</pre><pre>const getUserData = async () =&gt; {<br>  // Direct call — no serialization, no round trip<br>  // Loads lazily only when you need it (faster app startup too!)<br>  const user = await NativeModules.UserModule.getUser();<br>  console.log(user);<br>};</pre><p>Same code, but 2–3x faster under the hood. The magic happens in the native layer.</p><h3>The Real Fix — Animations on UI Thread</h3><pre>// NEW WAY — Reanimated 2 (animation runs on UI thread directly)</pre><pre>import Animated, {<br>  useSharedValue,<br>  useAnimatedScrollHandler,<br>  useAnimatedStyle,<br>  interpolate,<br>} from &#39;react-native-reanimated&#39;;</pre><pre>const MyScreen = () =&gt; {<br>  const scrollY = useSharedValue(0);</pre><pre>  // &#39;worklet&#39; means this runs ON the UI thread<br>  // JS thread is not involved at all 🔥<br>  const scrollHandler = useAnimatedScrollHandler({<br>    onScroll: (event) =&gt; {<br>      &#39;worklet&#39;;<br>      scrollY.value = event.contentOffset.y;<br>    },<br>  });</pre><pre>  const animatedStyle = useAnimatedStyle(() =&gt; {<br>    &#39;worklet&#39;;<br>    return {<br>      opacity: interpolate(scrollY.value, [0, 300], [1, 0]),<br>    };<br>  });</pre><pre>  return (<br>    &lt;Animated.ScrollView onScroll={scrollHandler}&gt;<br>      &lt;Animated.View style={animatedStyle}&gt;<br>        {/* This fades smoothly even if JS thread is busy */}<br>      &lt;/Animated.View&gt;<br>    &lt;/Animated.ScrollView&gt;<br>  );<br>};</pre><p>See that &#39;worklet&#39; word? That tells React Native: <strong>run this on the UI thread, skip JS entirely</strong>. Your animation is now 60fps no matter what your JS thread is doing.</p><h3>Old vs New — Side by Side</h3><pre>OLD ARCHITECTURE<br>─────────────────────────────────────────────────<br>JS Thread  →  Bridge (JSON)  →  Native Thread<br>                  ↓<br>           Slow. Serialized.<br>           Every call waits in line.</pre><pre>NEW ARCHITECTURE<br>─────────────────────────────────────────────────<br>JS Thread  →  JSI (Direct C++ call)  →  Native Thread<br>                  ↓<br>           Fast. Direct.<br>           No waiting. No packing. No unpacking.</pre><p>Old (Bridge) New (JSI) Communication JSON serialization Direct C++ call Speed Slow (1–2ms per call) Near zero cost Animation Goes through JS + Bridge Runs on UI thread (worklets) Module loading All loaded at startup Lazy loaded when needed App startup Slower Faster</p><h3>The One Rule to Remember</h3><blockquote><strong><em>Keep the UI Thread free. Keep the JS Thread free.</em></strong><em><br> If one gets blocked — your user feels it immediately.</em></blockquote><p>That’s it. Everything in React Native performance comes back to this one rule.</p><p>The new architecture (JSI + Fabric + TurboModules) makes this much easier to achieve — but understanding <em>why</em> is what separates good mobile engineers from great ones.</p><p>I’m learning React Native architecture deeply right now and documenting everything as I go. If you’re on the same journey — let’s connect. 🙌</p><p>Drop a comment if you found this helpful or if anything wasn’t clear. Happy to explain further!</p><p><a href="#ReactNative"><strong>#ReactNative</strong></a><strong> </strong><a href="#MobileDevelopment"><strong>#MobileDevelopment</strong></a><strong> </strong><a href="#JavaScript"><strong>#JavaScript</strong></a><strong> </strong><a href="#AndroidDev"><strong>#AndroidDev</strong></a><strong> </strong><a href="#iOSDev"><strong>#iOSDev</strong></a><strong> </strong><a href="#SoftwareEngineering"><strong>#SoftwareEngineering</strong></a><strong> </strong><a href="#LearningInPublic"><strong>#LearningInPublic</strong></a><strong> </strong><a href="#JSI"><strong>#JSI</strong></a><strong> </strong><a href="#NewArchitecture"><strong>#NewArchitecture</strong></a><strong> </strong><a href="#TechCommunity"><strong>#TechCommunity</strong></a></p><img src="https://medium.com/_/stat?event=post.clientViewed&referrerSource=full_rss&postId=8a1f4876e3ca" width="1" height="1" alt="">]]></content:encoded>
        </item>
    </channel>
</rss>