<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: Md Enayetur Rahman</title>
    <description>The latest articles on DEV Community by Md Enayetur Rahman (@md_enayeturrahman_2560e3).</description>
    <link>https://dev.to/md_enayeturrahman_2560e3</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F1601584%2F84f7c0e4-33bd-47f4-9270-6746ea824d8f.png</url>
      <title>DEV Community: Md Enayetur Rahman</title>
      <link>https://dev.to/md_enayeturrahman_2560e3</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/md_enayeturrahman_2560e3"/>
    <language>en</language>
    <item>
      <title>Optimize Loading Sequence (Part 2)</title>
      <dc:creator>Md Enayetur Rahman</dc:creator>
      <pubDate>Sat, 13 Dec 2025 09:55:12 +0000</pubDate>
      <link>https://dev.to/md_enayeturrahman_2560e3/optimize-loading-sequence-part-2-1n96</link>
      <guid>https://dev.to/md_enayeturrahman_2560e3/optimize-loading-sequence-part-2-1n96</guid>
      <description>&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;#LearningPatterns52&lt;/strong&gt; | &lt;em&gt;Based on “Learning Patterns” (v1.1) by Lydia Hallie &amp;amp; Addy Osmani&lt;/em&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;&lt;em&gt;This article continues the &lt;strong&gt;Optimize Loading Sequence&lt;/strong&gt; pattern. Part 1 covered why sequencing is hard and which metrics matter. Here in Part 2 we move from diagnosis ➜ prescription.&lt;/em&gt;&lt;/p&gt;




&lt;h2&gt;
  
  
  Introduction
&lt;/h2&gt;

&lt;p&gt;The book frames loading as &lt;strong&gt;a queue‐management problem&lt;/strong&gt;: which byte hits the wire first, and why?&lt;br&gt;&lt;br&gt;
The browser already has heuristics, but you — not the network stack — know what the user must see &amp;amp; use first.&lt;br&gt;&lt;br&gt;
Your job: &lt;strong&gt;override defaults&lt;/strong&gt; with hints that pull critical assets forward and push distractions back.&lt;/p&gt;




&lt;h2&gt;
  
  
  1 · Critical CSS
&lt;/h2&gt;

&lt;p&gt;&lt;em&gt;Learning Patterns&lt;/em&gt; defines &lt;strong&gt;critical CSS&lt;/strong&gt; as the minimal style‑set required to paint above‑the‑fold content.&lt;br&gt;&lt;br&gt;
The recommended flow:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Inline&lt;/strong&gt; ≤ 15 KB of critical rules in the &lt;code&gt;&amp;lt;head&amp;gt;&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;Mark the remainder with &lt;code&gt;rel="preload"&lt;/code&gt; &amp;amp; &lt;code&gt;as="style"&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;Defer non‑render‑blocking styles via &lt;code&gt;media="print"&lt;/code&gt; → &lt;code&gt;onload&lt;/code&gt; swap&lt;/li&gt;
&lt;/ol&gt;

&lt;blockquote&gt;
&lt;p&gt;The book’s Lighthouse trace shows a &lt;strong&gt;31 % LCP improvement&lt;/strong&gt; simply by isolating 5.8 KB of hero styles.&lt;/p&gt;
&lt;/blockquote&gt;




&lt;h2&gt;
  
  
  2 · Fonts
&lt;/h2&gt;

&lt;p&gt;Fonts block text render. The pattern suggests:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;preload&lt;/code&gt; the most‑used weight (&lt;code&gt;woff2&lt;/code&gt;)&lt;/li&gt;
&lt;li&gt;Combine &lt;code&gt;font-display: swap&lt;/code&gt; &lt;strong&gt;plus&lt;/strong&gt; a 3 s FOIT timeout&lt;/li&gt;
&lt;li&gt;Scope icon fonts to subsets or shift them to SVG sprites&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Example: a P75 mobile session saw CLS drop from &lt;strong&gt;0.23 ➜ 0.04&lt;/strong&gt; after the fallback/swap approach.&lt;/p&gt;




&lt;h2&gt;
  
  
  3 · Images
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Above‑the‑Fold
&lt;/h3&gt;

&lt;p&gt;&lt;em&gt;Learning Patterns&lt;/em&gt; advises:&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Step&lt;/th&gt;
&lt;th&gt;Tactic&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;1&lt;/td&gt;
&lt;td&gt;Use a &lt;strong&gt;low‑quality placeholder&lt;/strong&gt; (&lt;code&gt;lqip&lt;/code&gt;, SVG blur)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;2&lt;/td&gt;
&lt;td&gt;Send the hero via &lt;code&gt;fetchpriority="high"&lt;/code&gt; or HTTP/2 push&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;3&lt;/td&gt;
&lt;td&gt;Serve modern formats (AVIF, WebP)&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;h3&gt;
  
  
  Below‑the‑Fold
&lt;/h3&gt;

&lt;p&gt;Mark with &lt;code&gt;loading="lazy"&lt;/code&gt; and, if bandwidth is tight, wrap in an &lt;code&gt;IntersectionObserver&lt;/code&gt; to delay even the request creation.&lt;/p&gt;




&lt;h2&gt;
  
  
  4 · Scripts
&lt;/h2&gt;

&lt;h3&gt;
  
  
  First‑Party JS
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Split&lt;/strong&gt;: isolate hydration logic required for the initial route
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Defer&lt;/strong&gt; modules that act post‑interactive
&lt;/li&gt;
&lt;li&gt;Move expensive polyfills behind feature detection&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Third‑Party JS
&lt;/h3&gt;

&lt;p&gt;The authors label them &lt;strong&gt;“performance dark matter.”&lt;/strong&gt; Recommendations:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Convert blocking &lt;code&gt;&amp;lt;script&amp;gt;&lt;/code&gt; tags to &lt;code&gt;async&lt;/code&gt; or delayed import&lt;/li&gt;
&lt;li&gt;Stub APIs until after TTI (e.g., push calls into a queue)&lt;/li&gt;
&lt;li&gt;Load via a single proxy host to reuse TCP/QUIC connections&lt;/li&gt;
&lt;/ol&gt;




&lt;h2&gt;
  
  
  5 · How Chrome Prioritises Resources (Book Table)
&lt;/h2&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Priority Bucket&lt;/th&gt;
&lt;th&gt;Examples&lt;/th&gt;
&lt;th&gt;TLS Handshake?&lt;/th&gt;
&lt;th&gt;Queue Age Limit&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Highest&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;In‑document CSS, critical &lt;code&gt;preload&lt;/code&gt;
&lt;/td&gt;
&lt;td&gt;Yes&lt;/td&gt;
&lt;td&gt;Immediate&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;High&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Images with &lt;code&gt;fetchpriority="high"&lt;/code&gt;; JS in &lt;code&gt;&amp;lt;head&amp;gt;&lt;/code&gt;
&lt;/td&gt;
&lt;td&gt;Yes&lt;/td&gt;
&lt;td&gt;5 round‑trips&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Medium&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Deferred/async scripts; fonts&lt;/td&gt;
&lt;td&gt;If needed&lt;/td&gt;
&lt;td&gt;10 round‑trips&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Low&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Lazy images, &lt;code&gt;rel="prefetch"&lt;/code&gt;
&lt;/td&gt;
&lt;td&gt;If idle&lt;/td&gt;
&lt;td&gt;Infinite&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Lowest&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;rel="prerender"&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Only when idle&lt;/td&gt;
&lt;td&gt;Infinite&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;&lt;em&gt;(Table reproduced from *Learning Patterns&lt;/em&gt;, ch. “Optimize Loading Sequence”)*&lt;/p&gt;




&lt;h2&gt;
  
  
  6 · Case Study — Next.js SSR (Before Optimisation)
&lt;/h2&gt;

&lt;blockquote&gt;
&lt;p&gt;“Even modern SSR frameworks &lt;strong&gt;can ship bytes in the wrong order&lt;/strong&gt;.” — &lt;em&gt;Learning Patterns&lt;/em&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h3&gt;
  
  
  Default Sequence
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;1. _app.js (159 KB)       ← blocking
2. vendors.js (321 KB)    ← blocking
3. route page.js (71 KB)
4. main.css (34 KB)
5. hero.jpg (1.2 MB)
6. webfont.woff2 (96 KB)
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Impact:&lt;/strong&gt;  &lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;LCP (mobile): &lt;strong&gt;4.8 s&lt;/strong&gt;
&lt;/li&gt;
&lt;li&gt;TBT: &lt;strong&gt;620 ms&lt;/strong&gt; (main thread busy parsing JS)
&lt;/li&gt;
&lt;li&gt;CLS: &lt;strong&gt;0.19&lt;/strong&gt; (font &amp;amp; image late)
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The book’s flame chart shows the browser idle for 200 ms waiting on &lt;strong&gt;main.css&lt;/strong&gt; that arrived after two big JS bundles.&lt;/p&gt;




&lt;h2&gt;
  
  
  7 · Proposed Sequence (No 3rd‑Party)
&lt;/h2&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;1. critical.css (inline)                    ← paints header
2. hero.jpg?width=560&amp;amp;format=avif          ← fetched with fetchpriority=high
3. font.woff2 (preload)                    ← text remains stable
4. route page.js (hydration + suspense)
5. vendors.js (chunked + deferred)
6. rest.css (preloaded; onload rel=stylesheet)
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Reasons
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Inline critical CSS&lt;/strong&gt; unblocks first paint.
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Hero image&lt;/strong&gt; early fetch secures LCP.
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Font preload&lt;/strong&gt; prevents FOUT/CLS.
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Code‑split hydration chunk&lt;/strong&gt; cuts TBT by trimming unused routes.
&lt;/li&gt;
&lt;/ul&gt;




&lt;h2&gt;
  
  
  8 · Proposed Sequence (With 3rd‑Party)
&lt;/h2&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;1‒4. Same as above
5. stub-analytics.js (1 KB inline)          ← captures events in queue
6. thirdparty.js (async, after load)         ← executes post‑TTI
7. chat-widget.css (preload, media=print)   ← swapped on scroll
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Reasons
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;A &lt;strong&gt;1 KB stub&lt;/strong&gt; guarantees data isn’t lost but doesn’t block painting.
&lt;/li&gt;
&lt;li&gt;Full analytics, A/B test, or chat scripts run &lt;strong&gt;after TTI&lt;/strong&gt;, avoiding TBT spikes.
&lt;/li&gt;
&lt;li&gt;Widget styles load off‑screen, so they’re quarantined from first paint.&lt;/li&gt;
&lt;/ul&gt;




&lt;h2&gt;
  
  
  Conclusion
&lt;/h2&gt;

&lt;p&gt;&lt;em&gt;Learning Patterns&lt;/em&gt;’ big takeaway: &lt;strong&gt;ordering beats bandwidth&lt;/strong&gt;.&lt;br&gt;&lt;br&gt;
By nudging the browser’s queue, you can often shave &lt;strong&gt;&amp;gt;30 %&lt;/strong&gt; off LCP without new servers or CDNs.  &lt;/p&gt;

&lt;p&gt;Happy shipping! 🚀&lt;/p&gt;




&lt;p&gt;&lt;em&gt;All figures &amp;amp; workflow steps are reproduced or summarised from “Learning Patterns” (v1.1).&lt;/em&gt;&lt;/p&gt;

</description>
    </item>
    <item>
      <title>Optimize Loading Sequence (Part 1) – Metrics &amp; Challenges</title>
      <dc:creator>Md Enayetur Rahman</dc:creator>
      <pubDate>Sat, 13 Dec 2025 09:53:41 +0000</pubDate>
      <link>https://dev.to/md_enayeturrahman_2560e3/optimize-loading-sequence-part-1-metrics-challenges-1e1a</link>
      <guid>https://dev.to/md_enayeturrahman_2560e3/optimize-loading-sequence-part-1-metrics-challenges-1e1a</guid>
      <description>&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Series:&lt;/strong&gt; #LearningPatterns51   |   &lt;em&gt;Based on “Learning Patterns” by Lydia Hallie &amp;amp; Addy Osmani&lt;/em&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h2&gt;
  
  
  Table of Contents
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;Why Loading Sequence Matters&lt;/li&gt;
&lt;li&gt;Key Metrics to Track&lt;/li&gt;
&lt;li&gt;
Why True Optimization Is Tricky

&lt;ul&gt;
&lt;li&gt;1 · Sub‑optimal Sequencing&lt;/li&gt;
&lt;li&gt;2 · Network &amp;amp; CPU Utilization&lt;/li&gt;
&lt;li&gt;3 · Third‑Party Products&lt;/li&gt;
&lt;li&gt;4 · Platform Quirks&lt;/li&gt;
&lt;li&gt;5 · HTTP/2 Prioritization Pitfalls&lt;/li&gt;
&lt;li&gt;6 · Resource‑Level Optimization Gaps&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;

&lt;li&gt;Conclusion&lt;/li&gt;

&lt;/ul&gt;




&lt;h2&gt;
  
  
  Why Loading Sequence Matters
&lt;/h2&gt;

&lt;p&gt;The &lt;em&gt;Loading Sequence&lt;/em&gt; pattern in &lt;strong&gt;Learning Patterns&lt;/strong&gt; reminds us that a page’s &lt;em&gt;perceived&lt;/em&gt; speed depends less on raw bandwidth and more on &lt;strong&gt;which bytes arrive first&lt;/strong&gt;. Smart sequencing lets users interact sooner and search engines rank us higher.&lt;/p&gt;

&lt;h2&gt;
  
  
  Key Metrics to Track
&lt;/h2&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Metric&lt;/th&gt;
&lt;th&gt;What It Measures&lt;/th&gt;
&lt;th&gt;Why It Matters&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;
&lt;strong&gt;TTFB&lt;/strong&gt; (Time To First Byte)&lt;/td&gt;
&lt;td&gt;Server → client latency before first byte&lt;/td&gt;
&lt;td&gt;Shows back‑end speed &amp;amp; CDN reach&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;
&lt;strong&gt;FCP&lt;/strong&gt; (First Contentful Paint)&lt;/td&gt;
&lt;td&gt;When any DOM content paints&lt;/td&gt;
&lt;td&gt;First visual feedback&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;
&lt;strong&gt;LCP&lt;/strong&gt; (Largest Contentful Paint)&lt;/td&gt;
&lt;td&gt;Render time of the hero element&lt;/td&gt;
&lt;td&gt;Core Web Vitals ranking signal&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;
&lt;strong&gt;TBT&lt;/strong&gt; (Total Blocking Time)&lt;/td&gt;
&lt;td&gt;Main‑thread blocking between FCP &amp;amp; TTI&lt;/td&gt;
&lt;td&gt;CPU hogs that delay interactivity&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;
&lt;strong&gt;CLS&lt;/strong&gt; (Cumulative Layout Shift)&lt;/td&gt;
&lt;td&gt;Unexpected layout movement&lt;/td&gt;
&lt;td&gt;UX stability, ad/script impacts&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Speed Index&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Visual completeness over time&lt;/td&gt;
&lt;td&gt;Overall perceived speed&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;em&gt;The book recommends baselining at least FCP, LCP, and TBT before optimizing so you can verify real‑world wins.&lt;/em&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h2&gt;
  
  
  Why True Optimization Is Tricky
&lt;/h2&gt;

&lt;h3&gt;
  
  
  1 · Sub‑optimal Sequencing
&lt;/h3&gt;

&lt;p&gt;Even small order mistakes—e.g. loading a &lt;strong&gt;carousel script before the CSS&lt;/strong&gt; that hides its overflow—force the browser to repaint.&lt;br&gt;&lt;br&gt;
&lt;strong&gt;Example:&lt;/strong&gt; A hero image &lt;code&gt;&amp;lt;img&amp;gt;&lt;/code&gt; lazy‑loaded &lt;em&gt;after&lt;/em&gt; below‑the‑fold ads can push LCP &amp;gt; 3 s. Fix by preloading the hero image and deferring ad scripts.&lt;/p&gt;

&lt;h3&gt;
  
  
  2 · Network &amp;amp; CPU Utilization
&lt;/h3&gt;

&lt;p&gt;High‑end dev machines rarely replicate &lt;strong&gt;mid‑tier phone&lt;/strong&gt; realities. Mobile radios add ~300 ms RTT and CPUs throttle under thermal limits.&lt;br&gt;&lt;br&gt;
&lt;strong&gt;Example:&lt;/strong&gt; A bundle that gzips to 150 kB may parse/run in 40 ms on desktop but &lt;strong&gt;250 ms on a Moto G&lt;/strong&gt;—enough to spike TBT.&lt;/p&gt;

&lt;h3&gt;
  
  
  3 · Third‑Party Products
&lt;/h3&gt;

&lt;p&gt;Analytics, ads, chat widgets — the &lt;em&gt;“unbudgeted bytes”&lt;/em&gt; of every sprint. They often ship un‑minified or run expensive polling loops.&lt;br&gt;&lt;br&gt;
&lt;strong&gt;Example:&lt;/strong&gt; One AB‑testing SDK injected 17 extra &lt;code&gt;&amp;lt;script&amp;gt;&lt;/code&gt; tags, delaying FCP by 800 ms. The book suggests &lt;strong&gt;“performance budgets per supplier”&lt;/strong&gt; and using &lt;code&gt;async defer&lt;/code&gt; by default.&lt;/p&gt;

&lt;h3&gt;
  
  
  4 · Platform Quirks
&lt;/h3&gt;

&lt;p&gt;Browsers implement standards differently. Safari blocks font preloads older than 2 weeks in cache; Chrome preload scanner ignores &lt;code&gt;media&lt;/code&gt; predicates.&lt;br&gt;&lt;br&gt;
&lt;strong&gt;Example:&lt;/strong&gt; An &lt;code&gt;@font-face&lt;/code&gt; swap that’s near‑instant in Chrome flashes unstyled text (FOUT) in Firefox because of its &lt;strong&gt;font‑loading timeout heuristic&lt;/strong&gt;.&lt;/p&gt;

&lt;h3&gt;
  
  
  5 · HTTP/2 Prioritization Pitfalls
&lt;/h3&gt;

&lt;p&gt;HTTP/2 multiplexes requests, but &lt;strong&gt;priority inheritance&lt;/strong&gt; varies by server. If your hero image is listed after a 1 MB analytics JSON, it can still starve.&lt;br&gt;&lt;br&gt;
&lt;strong&gt;Example:&lt;/strong&gt; Switching from Apache to &lt;strong&gt;nghttpx&lt;/strong&gt; with correct weight settings cut LCP from 4.1 s to 2.3 s in the book’s case study.&lt;/p&gt;

&lt;h3&gt;
  
  
  6 · Resource‑Level Optimization Gaps
&lt;/h3&gt;

&lt;p&gt;Image compression, SVG clean‑up, tree‑shaking — each resource has its own optimal path. Miss one and you give back hard‑won gains.&lt;br&gt;&lt;br&gt;
&lt;strong&gt;Example:&lt;/strong&gt; A React app that treeshook but forgot to strip &lt;code&gt;moment.js&lt;/code&gt; locales shipped +280 kB of unused data.&lt;/p&gt;

&lt;h2&gt;
  
  
  Conclusion
&lt;/h2&gt;

&lt;p&gt;Optimizing loading isn’t a one‑time tweak; it’s a &lt;strong&gt;cross‑discipline negotiation&lt;/strong&gt; between design, back‑end, DevOps, and third‑party vendors. Part 1 laid out &lt;em&gt;what to measure&lt;/em&gt; and &lt;em&gt;why perfection is elusive&lt;/em&gt;.&lt;br&gt;&lt;br&gt;
In &lt;strong&gt;Part 2&lt;/strong&gt; we’ll dive into prescriptive techniques: critical CSS extraction, priority hints, server push best practices, and more.&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Inspired by the Loading Sequence insights from **Learning Patterns&lt;/em&gt;* by Lydia Hallie &amp;amp; Addy Osmani.* &lt;/p&gt;

</description>
    </item>
    <item>
      <title>Islands Architecture in Practice – A Deep Dive</title>
      <dc:creator>Md Enayetur Rahman</dc:creator>
      <pubDate>Sat, 13 Dec 2025 09:41:25 +0000</pubDate>
      <link>https://dev.to/md_enayeturrahman_2560e3/islands-architecture-in-practice-a-deep-dive-28c2</link>
      <guid>https://dev.to/md_enayeturrahman_2560e3/islands-architecture-in-practice-a-deep-dive-28c2</guid>
      <description>&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;#LearningPatterns50&lt;/strong&gt;   |   &lt;em&gt;Based on “Learning Patterns” by Lydia Hallie &amp;amp; Addy Osmani&lt;/em&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h2&gt;
  
  
  Table of Contents
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;Table of Contents&lt;/li&gt;
&lt;li&gt;What Sparked Islands Architecture?&lt;/li&gt;
&lt;li&gt;Islands of Dynamic Components Explained&lt;/li&gt;
&lt;li&gt;Implementing Islands — The Core Mechanics&lt;/li&gt;
&lt;li&gt;Ecosystem &amp;amp; Framework Support&lt;/li&gt;
&lt;li&gt;
DIY: A Minimal Islands Implementation

&lt;ul&gt;
&lt;li&gt;1 · Install Astro&lt;/li&gt;
&lt;li&gt;2 · Create an Island Component (&lt;code&gt;src/components/Counter.jsx&lt;/code&gt;)&lt;/li&gt;
&lt;li&gt;3 · Use the Island in a Page (&lt;code&gt;src/pages/index.astro&lt;/code&gt;)&lt;/li&gt;
&lt;li&gt;Vanilla Roll‑Your‑Own (Optional)&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;

&lt;li&gt;Pros &amp;amp; Cons&lt;/li&gt;

&lt;li&gt;Conclusion&lt;/li&gt;

&lt;/ul&gt;




&lt;h2&gt;
  
  
  What Sparked Islands Architecture?
&lt;/h2&gt;

&lt;p&gt;Single‑Page Applications (SPAs) gave us fluid UX but at a heavy cost: large JS bundles, hydration delays, and poor first‑page performance. Islands Architecture emerged as a &lt;strong&gt;middle path&lt;/strong&gt;:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;MPA ergonomics&lt;/strong&gt; – ship mostly static HTML for fast TTFB and reliable SEO.
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Targeted interactivity&lt;/strong&gt; – hydrate only the parts that &lt;em&gt;need&lt;/em&gt; it, shrinking JS and CPU usage.
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The term was popularized by &lt;a href="https://web.dev/javascript-cost/" rel="noopener noreferrer"&gt;Addy Osmani’s 2019 post “The Cost Of JavaScript Frameworks”&lt;/a&gt; and later formalized in &lt;em&gt;Learning Patterns&lt;/em&gt;.&lt;/p&gt;




&lt;h2&gt;
  
  
  Islands of Dynamic Components Explained
&lt;/h2&gt;

&lt;p&gt;An &lt;strong&gt;island&lt;/strong&gt; is a &lt;em&gt;self‑contained, interactive component&lt;/em&gt; surrounded by inert, static HTML (the “ocean”).&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;+--------------------------------------------------------+
|             Static hero section (pure HTML)            |
|  +-----------------------------------------------+     |
|  |  &amp;lt;SearchBox/&amp;gt;   ← interactive island (hydrated) |   |
|  +-----------------------------------------------+     |
|      Static marketing copy (no client JS)            |
|  +-----------------------------------------------+     |
|  |  &amp;lt;SubscribeForm/&amp;gt;  ← another island             |   |
|  +-----------------------------------------------+     |
+--------------------------------------------------------+
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Only the &lt;strong&gt;SearchBox&lt;/strong&gt; and &lt;strong&gt;SubscribeForm&lt;/strong&gt; download/execute JS; everything else remains lightweight markup.&lt;/p&gt;




&lt;h2&gt;
  
  
  Implementing Islands — The Core Mechanics
&lt;/h2&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Server renders full HTML&lt;/strong&gt; for the page.
&lt;/li&gt;
&lt;li&gt;Interactive components embed a tiny marker (e.g. &lt;code&gt;data-island="ComponentName"&lt;/code&gt;) plus their serialized props.
&lt;/li&gt;
&lt;li&gt;On the client, a micro‑runtime scans the DOM, lazy‑loads each component bundle, and mounts it into its placeholder.
&lt;/li&gt;
&lt;li&gt;Each island runs in isolation; no global SPA router required.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;This is essentially &lt;strong&gt;partial hydration&lt;/strong&gt;.&lt;/p&gt;




&lt;h2&gt;
  
  
  Ecosystem &amp;amp; Framework Support
&lt;/h2&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Framework&lt;/th&gt;
&lt;th&gt;Islands Support&lt;/th&gt;
&lt;th&gt;Notes&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Astro&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;✅ Built‑in (&lt;code&gt;client:only&lt;/code&gt;, &lt;code&gt;client:visible&lt;/code&gt;, etc.)&lt;/td&gt;
&lt;td&gt;Zero JS by default&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Qwik&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;✅ Resumability + island hydration (&lt;code&gt;q:scoped&lt;/code&gt;)&lt;/td&gt;
&lt;td&gt;Ultra‑deferred execution&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Slinkity&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;✅ Islands on top of Eleventy&lt;/td&gt;
&lt;td&gt;Great for static sites&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Marko 6&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;✅ Streaming islands (&lt;code&gt;&amp;lt;client&amp;gt;&lt;/code&gt; tag)&lt;/td&gt;
&lt;td&gt;Hydrates only when needed&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Fresh (Deno)&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;✅ Per‑component islands&lt;/td&gt;
&lt;td&gt;Runs on Deno Deploy&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;




&lt;h2&gt;
  
  
  DIY: A Minimal Islands Implementation
&lt;/h2&gt;

&lt;p&gt;Below is a &lt;strong&gt;tiny proof‑of‑concept&lt;/strong&gt; with &lt;strong&gt;Astro&lt;/strong&gt;.&lt;/p&gt;

&lt;h3&gt;
  
  
  1 · Install Astro
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;npm create astro@latest my‑islands‑demo
&lt;span class="nb"&gt;cd &lt;/span&gt;my‑islands‑demo &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt; npm i
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  2 · Create an Island Component (&lt;code&gt;src/components/Counter.jsx&lt;/code&gt;)
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight jsx"&gt;&lt;code&gt;&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;useState&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;react&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="k"&gt;default&lt;/span&gt; &lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;Counter&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt; &lt;span class="nx"&gt;initial&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt; &lt;span class="p"&gt;})&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;count&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;setCount&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;useState&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;initial&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="k"&gt;return &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nt"&gt;button&lt;/span&gt;
      &lt;span class="na"&gt;className&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;"px-3 py-2 rounded bg-blue-600 text-white"&lt;/span&gt;
      &lt;span class="na"&gt;onClick&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nf"&gt;setCount&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;c&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nx"&gt;c&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;
    &lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
      Count: &lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;count&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;
    &lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nt"&gt;button&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
  &lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  3 · Use the Island in a Page (&lt;code&gt;src/pages/index.astro&lt;/code&gt;)
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;---
import Counter from "../components/Counter.jsx";
---

&amp;lt;html lang="en"&amp;gt;
  &amp;lt;body&amp;gt;
    &amp;lt;h1&amp;gt;Islands Demo&amp;lt;/h1&amp;gt;

    &amp;lt;!-- 👇 Hydrate this component only when it becomes visible --&amp;gt;
    &amp;lt;Counter client:visible initial={5} /&amp;gt;

    &amp;lt;p&amp;gt;No other JS was shipped!&amp;lt;/p&amp;gt;
  &amp;lt;/body&amp;gt;
&amp;lt;/html&amp;gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Run &lt;code&gt;npm run dev&lt;/code&gt; and inspect the network tab—only ~1 KB of JS for the counter.&lt;/p&gt;

&lt;h3&gt;
  
  
  Vanilla Roll‑Your‑Own (Optional)
&lt;/h3&gt;

&lt;p&gt;If you can’t switch frameworks, you can sprinkle islands into any SSR stack:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight html"&gt;&lt;code&gt;&lt;span class="c"&gt;&amp;lt;!-- server‑rendered --&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;div&lt;/span&gt; &lt;span class="na"&gt;id=&lt;/span&gt;&lt;span class="s"&gt;"search"&lt;/span&gt; &lt;span class="na"&gt;data-props=&lt;/span&gt;&lt;span class="s"&gt;'{"term": ""}'&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&amp;lt;/div&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;script &lt;/span&gt;&lt;span class="na"&gt;type=&lt;/span&gt;&lt;span class="s"&gt;"module"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
  &lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="nx"&gt;SearchBox&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;/static/search.js&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;el&lt;/span&gt;   &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nb"&gt;document&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;getElementById&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;search&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;props&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;JSON&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;parse&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;el&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;dataset&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;props&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="nx"&gt;SearchBox&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;mount&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;el&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;props&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;      &lt;span class="c1"&gt;// your own mini runtime&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;/script&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h2&gt;
  
  
  Pros &amp;amp; Cons
&lt;/h2&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;✅ Pros&lt;/th&gt;
&lt;th&gt;❌ Cons&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;
&lt;strong&gt;Lower JS payloads&lt;/strong&gt; – only hydrate what’s necessary.&lt;/td&gt;
&lt;td&gt;
&lt;strong&gt;Mental model shift&lt;/strong&gt; – designers/devs must think in islands.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;
&lt;strong&gt;Great Core Web Vitals&lt;/strong&gt; – faster FCP, TTI.&lt;/td&gt;
&lt;td&gt;
&lt;strong&gt;State sharing&lt;/strong&gt; between islands can be tricky (requires events or server).&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;
&lt;strong&gt;Progressive enhancement out of the box&lt;/strong&gt;.&lt;/td&gt;
&lt;td&gt;
&lt;strong&gt;Tooling lock‑in&lt;/strong&gt; if you lean on a specific island framework.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;
&lt;strong&gt;SEO‑friendly&lt;/strong&gt; – full HTML delivered up front.&lt;/td&gt;
&lt;td&gt;
&lt;strong&gt;Not a silver bullet&lt;/strong&gt; for highly interactive dashboards (might still need SPA techniques).&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;




&lt;h2&gt;
  
  
  Conclusion
&lt;/h2&gt;

&lt;p&gt;Islands Architecture re‑balances the SPA/MPA spectrum: deliver static HTML for speed, sprinkle interactivity where it actually adds value. Frameworks such as &lt;strong&gt;Astro&lt;/strong&gt; and &lt;strong&gt;Qwik&lt;/strong&gt; automate the heavy lifting, but you can experiment with your own mini‑runtime today.&lt;/p&gt;

&lt;p&gt;If your next project is content‑heavy with just a few interactive widgets, give islands a try—you might never look back at full‑page hydration.&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Happy shipping, and see you in the next pattern!&lt;/em&gt; 🚀&lt;/p&gt;

</description>
    </item>
    <item>
      <title>Optimizing Core Web Vitals in the *Next.js Movies* App – A Full Playbook</title>
      <dc:creator>Md Enayetur Rahman</dc:creator>
      <pubDate>Sat, 13 Dec 2025 09:39:11 +0000</pubDate>
      <link>https://dev.to/md_enayeturrahman_2560e3/optimizing-core-web-vitals-in-the-nextjs-movies-app-a-full-playbook-5dl3</link>
      <guid>https://dev.to/md_enayeturrahman_2560e3/optimizing-core-web-vitals-in-the-nextjs-movies-app-a-full-playbook-5dl3</guid>
      <description>&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;#LearningPatterns49&lt;/strong&gt;   |   &lt;em&gt;Source: “Learning Patterns” by Lydia Hallie &amp;amp; Addy Osmani&lt;/em&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h2&gt;
  
  
  Table of Contents
&lt;/h2&gt;

&lt;ol&gt;
&lt;li&gt;Why Core Web Vitals?&lt;/li&gt;
&lt;li&gt;Benchmark: Next.js Movies&lt;/li&gt;
&lt;li&gt;Cumulative Results&lt;/li&gt;
&lt;li&gt;Optimization Checklist – 11 Changes&lt;/li&gt;
&lt;li&gt;Conclusion &amp;amp; Key Take‑aways&lt;/li&gt;
&lt;/ol&gt;




&lt;h2&gt;
  
  
  Why Core Web Vitals?
&lt;/h2&gt;

&lt;p&gt;Google’s &lt;strong&gt;Largest Contentful Paint (LCP)&lt;/strong&gt;, &lt;strong&gt;Interaction to Next Paint (INP)&lt;/strong&gt; and &lt;strong&gt;Cumulative Layout Shift (CLS)&lt;/strong&gt; map directly to &lt;em&gt;perceived&lt;/em&gt; speed, responsiveness and stability. The authors dedicated an entire chapter to showing how to move each metric into the “good” range without crippling DX.&lt;/p&gt;




&lt;h2&gt;
  
  
  Benchmark: Next.js Movies
&lt;/h2&gt;

&lt;p&gt;The team built a fully‑featured movie‑browser powered by the &lt;strong&gt;TMDB&lt;/strong&gt; API—search, filter, favorites, server‑side rendering and authentication—to mimic a real‑world SPA. All experiments below were run against that code‑base.&lt;/p&gt;




&lt;h2&gt;
  
  
  Cumulative Results
&lt;/h2&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Metric (average across pages)&lt;/th&gt;
&lt;th&gt;Before&lt;/th&gt;
&lt;th&gt;After&lt;/th&gt;
&lt;th&gt;Δ&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;LCP&lt;/td&gt;
&lt;td&gt;3.43 s&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;2.86 s&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;−16 %&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;INP (TBT proxy)&lt;/td&gt;
&lt;td&gt;60 ms&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;20 ms&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;−67 %&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Speed Index&lt;/td&gt;
&lt;td&gt;4.2 s&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;3.5 s&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;−17 %&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Lighthouse Perf&lt;/td&gt;
&lt;td&gt;88 %&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;94 %&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;+6 pts&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;&lt;em&gt;Table reproduced from the book’s “Cumulative Improvements” section.&lt;/em&gt;&lt;/p&gt;




&lt;h2&gt;
  
  
  Optimization Checklist – 11 Changes
&lt;/h2&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;#&lt;/th&gt;
&lt;th&gt;Category&lt;/th&gt;
&lt;th&gt;What changed&lt;/th&gt;
&lt;th&gt;Why it helps&lt;/th&gt;
&lt;th&gt;Key gain&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;1&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;Trim heavy deps&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Font‑Awesome → &lt;code&gt;@svgr/webpack&lt;/code&gt;; &lt;code&gt;react-burger-menu&lt;/code&gt; → custom; &lt;code&gt;react-select&lt;/code&gt; → &lt;code&gt;react-select-search&lt;/code&gt;; &lt;code&gt;react-slick&lt;/code&gt; → &lt;code&gt;react-glider&lt;/code&gt;; &lt;code&gt;react-rating&lt;/code&gt; → &lt;code&gt;react-stars&lt;/code&gt;; native smooth‑scroll polyfill → &lt;code&gt;react-scroll&lt;/code&gt;
&lt;/td&gt;
&lt;td&gt;Removes KBs and main‑thread work&lt;/td&gt;
&lt;td&gt;LCP −23 %, TBT −51 % (SVG swap)【0†L55-L65】&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;2&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Code‑split UI chrome&lt;/td&gt;
&lt;td&gt;Sidebar &amp;amp; comments wrapped in &lt;code&gt;React.lazy&lt;/code&gt; + &lt;code&gt;Suspense&lt;/code&gt;
&lt;/td&gt;
&lt;td&gt;Sends less JS on critical path&lt;/td&gt;
&lt;td&gt;TBT −71 %【2†L5-L9】【2†L20-L27】&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;3&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Inline &lt;strong&gt;critical CSS&lt;/strong&gt;, defer the rest&lt;/td&gt;
&lt;td&gt;Moved node‑module CSS out of &lt;code&gt;_app.js&lt;/code&gt;; in‑lined dark/light‑mode CSS&lt;/td&gt;
&lt;td&gt;Unblocks rendering, lowers FCP/LCP&lt;/td&gt;
&lt;td&gt;2‑5 % faster LCP/TTI【4†L9-L18】【4†L37-L38】&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;4&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Fix CLS completely&lt;/td&gt;
&lt;td&gt;Adopted &lt;strong&gt;aspect‑ratio boxes&lt;/strong&gt; for posters&lt;/td&gt;
&lt;td&gt;Reserves space before images load&lt;/td&gt;
&lt;td&gt;CLS → 0【3†L14-L18】【3†L21-L22】&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;5&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;
&lt;strong&gt;Preconnect&lt;/strong&gt; origins&lt;/td&gt;
&lt;td&gt;TMDB image &amp;amp; API domains&lt;/td&gt;
&lt;td&gt;Warms DNS/TLS early&lt;/td&gt;
&lt;td&gt;Small but measurable FCP/Speed Index drop【3†L30-L36】【3†L38-L40】&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;6&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Re‑order API calls&lt;/td&gt;
&lt;td&gt;Metadata &amp;amp; poster calls run &lt;strong&gt;in parallel&lt;/strong&gt;
&lt;/td&gt;
&lt;td&gt;Main content arrives sooner&lt;/td&gt;
&lt;td&gt;LCP −16 %, Perf +5 pts【3†L43-L50】【3†L65-L70】&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;7&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;
&lt;strong&gt;Preload&lt;/strong&gt; predictable API response&lt;/td&gt;
&lt;td&gt;First‑visit “Popular movies – page 1” fetched during HTML parse&lt;/td&gt;
&lt;td&gt;Eliminates post‑render spinner&lt;/td&gt;
&lt;td&gt;LCP −12.6 %, TTI −7.8 %【7†L73-L79】【7†L77-L79】&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;8&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Preload logo &amp;amp; trademark&lt;/td&gt;
&lt;td&gt;Added media‑conditioned &lt;code&gt;&amp;lt;link preload&amp;gt;&lt;/code&gt;
&lt;/td&gt;
&lt;td&gt;Improves repeated nav&lt;/td&gt;
&lt;td&gt;FCP &amp;amp; Speed Index −5‑6 %【7†L81-L88】【7†L89-L90】&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;9&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Make SSR responsive&lt;/td&gt;
&lt;td&gt;Used &lt;code&gt;@artsy/fresnel&lt;/code&gt; so server renders all break‑points, client only hydrates one&lt;/td&gt;
&lt;td&gt;Reduces JS &amp;amp; CSS per viewport&lt;/td&gt;
&lt;td&gt;Faster Speed Index; no functionality loss【7†L91-L96】&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;10&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Lazy‑load carousel CSS&lt;/td&gt;
&lt;td&gt;In‑lined Glider styles only on pages that need them&lt;/td&gt;
&lt;td&gt;Cuts render‑blocking CSS&lt;/td&gt;
&lt;td&gt;Page Perf +2 pts【4†L28-L31】【4†L37-L38】&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;11&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Review loading sequence&lt;/td&gt;
&lt;td&gt;Followed Aurora team’s ideal ordering for CSS, fonts, JS, images&lt;/td&gt;
&lt;td&gt;Systematic CWV protection&lt;/td&gt;
&lt;td&gt;Framework for future regressions【1†L15-L23】【10†L91-L100】&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;




&lt;h2&gt;
  
  
  Conclusion &amp;amp; Key Take‑aways
&lt;/h2&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Swap, don’t just tweak:&lt;/strong&gt; Replacing a whole dependency can deliver outsized wins.
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Sequence matters:&lt;/strong&gt; Critical data and assets must arrive &lt;em&gt;first&lt;/em&gt;; speed without order still hurts LCP.
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Measure every change:&lt;/strong&gt; The team ran &lt;strong&gt;Lighthouse &amp;amp; WebPageTest&lt;/strong&gt; after &lt;em&gt;each&lt;/em&gt; tweak to avoid regression noise.
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Zero CLS is achievable:&lt;/strong&gt; Reserving space (aspect‑ratio boxes / &lt;code&gt;next/image&lt;/code&gt;) is usually enough.
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Performance is iterative:&lt;/strong&gt; These 11 optimizations built on one another—no single silver bullet.&lt;/li&gt;
&lt;/ol&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;em&gt;“Excellent user experience translates to passing Core Web Vitals.”&lt;/em&gt; — &lt;em&gt;Learning Patterns&lt;/em&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Happy optimizing! 🚀&lt;/p&gt;

</description>
    </item>
    <item>
      <title>Selective vs Progressive Hydration</title>
      <dc:creator>Md Enayetur Rahman</dc:creator>
      <pubDate>Sat, 13 Dec 2025 09:36:59 +0000</pubDate>
      <link>https://dev.to/md_enayeturrahman_2560e3/selective-vs-progressive-hydration-19mj</link>
      <guid>https://dev.to/md_enayeturrahman_2560e3/selective-vs-progressive-hydration-19mj</guid>
      <description>&lt;p&gt;Hydration is the moment a server‑rendered React tree becomes &lt;strong&gt;interactive&lt;/strong&gt; in the browser. Two patterns help us ship less JS and unblock the main thread:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Progressive Hydration&lt;/strong&gt; – hydrate &lt;em&gt;over time&lt;/em&gt;.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Selective Hydration&lt;/strong&gt; – hydrate &lt;em&gt;what matters first&lt;/em&gt;.&lt;/li&gt;
&lt;/ul&gt;




&lt;h2&gt;
  
  
  Progressive Hydration
&lt;/h2&gt;

&lt;p&gt;Progressive hydration defers work until a component actually &lt;strong&gt;needs&lt;/strong&gt; to be interactive—for example when it scrolls into view. Instead of hydrating the whole page at once, we hydrate in &lt;strong&gt;slices&lt;/strong&gt;, scheduling each slice when the browser is idle or a trigger fires.  This spreads CPU cost and reduces the &lt;strong&gt;Time‑to‑Interactive (TTI)&lt;/strong&gt;. &lt;/p&gt;

&lt;h3&gt;
  
  
  Simplified Example
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight jsx"&gt;&lt;code&gt;&lt;span class="c1"&gt;// Hydrator.js&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;hydrateRoot&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;react-dom/client&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;hydrateWhenVisible&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;id&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;el&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nb"&gt;document&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;getElementById&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;id&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="k"&gt;if &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;!&lt;/span&gt;&lt;span class="nx"&gt;el&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;return&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

  &lt;span class="c1"&gt;// Only hydrate once the element is in the viewport&lt;/span&gt;
  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;io&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;IntersectionObserver&lt;/span&gt;&lt;span class="p"&gt;(([&lt;/span&gt;&lt;span class="nx"&gt;entry&lt;/span&gt;&lt;span class="p"&gt;])&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;if &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;entry&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;isIntersecting&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="nf"&gt;hydrateRoot&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;el&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;App&lt;/span&gt; &lt;span class="p"&gt;/&amp;gt;);&lt;/span&gt;
      &lt;span class="nx"&gt;io&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;disconnect&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
  &lt;span class="p"&gt;});&lt;/span&gt;
  &lt;span class="nx"&gt;io&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;observe&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;el&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;





&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight html"&gt;&lt;code&gt;&lt;span class="c"&gt;&amp;lt;!-- index.html --&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;div&lt;/span&gt; &lt;span class="na"&gt;id=&lt;/span&gt;&lt;span class="s"&gt;"users"&lt;/span&gt; &lt;span class="na"&gt;data-hydrate=&lt;/span&gt;&lt;span class="s"&gt;"visible"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
  &lt;span class="c"&gt;&amp;lt;!-- SSR'ed markup for &amp;lt;Users /&amp;gt; --&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;/div&amp;gt;&lt;/span&gt;

&lt;span class="nt"&gt;&amp;lt;script &lt;/span&gt;&lt;span class="na"&gt;type=&lt;/span&gt;&lt;span class="s"&gt;"module"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
  &lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;hydrateWhenVisible&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;/Hydrator.js&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="nf"&gt;hydrateWhenVisible&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;users&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;/script&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The &lt;code&gt;Users&lt;/code&gt; list stays HTML‑only until the user scrolls to it, then we mount React.&lt;/p&gt;




&lt;h2&gt;
  
  
  Selective Hydration
&lt;/h2&gt;

&lt;p&gt;Selective hydration arrived with &lt;strong&gt;React 18+ streaming SSR&lt;/strong&gt;. When React streams HTML, it can &lt;em&gt;immediately&lt;/em&gt; hydrate chunks that have already arrived, without waiting for the entire page. Even better, if the user interacts with an already‑rendered—but not yet hydrated—portion, React &lt;strong&gt;prioritizes&lt;/strong&gt; that slice.&lt;/p&gt;

&lt;h3&gt;
  
  
  Simplified Example
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight jsx"&gt;&lt;code&gt;&lt;span class="c1"&gt;// server.jsx&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;renderToPipeableStream&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;react-dom/server&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="nx"&gt;express&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;express&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;app&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;express&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;

&lt;span class="nx"&gt;app&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;get&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;/&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;req&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;res&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;pipe&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;renderToPipeableStream&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;App&lt;/span&gt; &lt;span class="p"&gt;/&amp;gt;,&lt;/span&gt;
    &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="nf"&gt;onAllReady&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="nx"&gt;res&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;setHeader&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Content-Type&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;text/html&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
        &lt;span class="nf"&gt;pipe&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;res&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
      &lt;span class="p"&gt;},&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
  &lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="p"&gt;});&lt;/span&gt;

&lt;span class="c1"&gt;// client.jsx streamed chunk&lt;/span&gt;
&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;Suspense&lt;/span&gt; &lt;span class="na"&gt;fallback&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;Spinner&lt;/span&gt; &lt;span class="p"&gt;/&amp;gt;&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
  &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;Comments&lt;/span&gt; &lt;span class="p"&gt;/&amp;gt;&lt;/span&gt;   &lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="cm"&gt;/* arrives later */&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nc"&gt;Suspense&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;If the user taps inside &lt;code&gt;&amp;lt;Comments&amp;gt;&lt;/code&gt; &lt;strong&gt;before&lt;/strong&gt; its JS arrives, React hydrates that subtree first, keeping the interaction snappy.&lt;/p&gt;




&lt;h2&gt;
  
  
  Pros &amp;amp; Cons
&lt;/h2&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Pattern&lt;/th&gt;
&lt;th&gt;Pros&lt;/th&gt;
&lt;th&gt;Cons&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Progressive&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;• Defers JS &amp;amp; CPU&lt;br&gt;• Excellent for below‑the‑fold content&lt;br&gt;• Works in React ≤17 with small libs&lt;/td&gt;
&lt;td&gt;• Manual; you must decide triggers&lt;br&gt;• First interaction may still load JS&lt;br&gt;• Multiple idle callbacks can complicate state sync&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Selective&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;• Automatic priority on user interaction&lt;br&gt;• Plays well with streaming SSR/Suspense&lt;br&gt;• Reduces main‑thread blocking for critical UI&lt;/td&gt;
&lt;td&gt;• React 18+ only&lt;br&gt;• Needs streaming infra (Node &amp;amp; CDN that supports &lt;code&gt;flush()&lt;/code&gt;)&lt;br&gt;• Debugging hydration order can be tricky&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;




&lt;h2&gt;
  
  
  When to Use What?
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Use Progressive Hydration&lt;/strong&gt; if you have &lt;strong&gt;large, non‑critical&lt;/strong&gt; widgets (maps, big lists, ads) and you’re on a React version &lt;strong&gt;before 18&lt;/strong&gt; or can’t stream HTML.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Use Selective Hydration&lt;/strong&gt; if you already stream with &lt;strong&gt;React 18+&lt;/strong&gt; and want React to &lt;strong&gt;automatically&lt;/strong&gt; prioritize interactivity.&lt;/li&gt;
&lt;/ul&gt;




&lt;h2&gt;
  
  
  Conclusion
&lt;/h2&gt;

&lt;p&gt;Both patterns share a goal: &lt;strong&gt;ship less JavaScript upfront and make real user interactions faster&lt;/strong&gt;.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Progressive hydration lets &lt;em&gt;you&lt;/em&gt; orchestrate hydration.&lt;/li&gt;
&lt;li&gt;Selective hydration lets &lt;strong&gt;React&lt;/strong&gt; orchestrate hydration based on what the user does.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Mix‑and‑match: you can progressively hydrate low‑priority widgets while React selectively hydrates streamed chunks. The result is a faster, more resilient UX—exactly what modern users (and Core Web Vitals) demand.&lt;/p&gt;




&lt;h3&gt;
  
  
  Further Reading
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;Lydia Hallie &amp;amp; Addy Osmani – &lt;strong&gt;&lt;em&gt;Learning Patterns&lt;/em&gt;&lt;/strong&gt; (Hydration section)&lt;/li&gt;
&lt;/ul&gt;

</description>
    </item>
    <item>
      <title>Beyond SSR: Demystifying React Server Components for Real‑World Apps</title>
      <dc:creator>Md Enayetur Rahman</dc:creator>
      <pubDate>Sat, 13 Dec 2025 09:34:40 +0000</pubDate>
      <link>https://dev.to/md_enayeturrahman_2560e3/beyond-ssr-demystifying-react-server-components-for-real-world-apps-14le</link>
      <guid>https://dev.to/md_enayeturrahman_2560e3/beyond-ssr-demystifying-react-server-components-for-real-world-apps-14le</guid>
      <description>&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Inspired by the insights in Lydia Hallie &amp;amp; Addy Osmani’s &lt;em&gt;Learning Patterns&lt;/em&gt;.&lt;/strong&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h2&gt;
  
  
  Why look beyond classic SSR?
&lt;/h2&gt;

&lt;p&gt;Server‑side rendering (SSR) was a game‑changer for the initial performance of React apps. But as applications grew, teams hit a few &lt;strong&gt;pain points&lt;/strong&gt;:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Bundle duplication&lt;/strong&gt; – The same components get shipped to both server &lt;em&gt;and&lt;/em&gt; client.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Hydration costs&lt;/strong&gt; – After HTML is streamed, the browser must download JavaScript, parse it, and re‑attach event listeners.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Tight data -- UI coupling&lt;/strong&gt; – Fetching data inside &lt;code&gt;getServerSideProps&lt;/code&gt; (or equivalent) forces full‑page reloads when only a section needed updating.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Limited in‑flight streaming&lt;/strong&gt; – You can send HTML early, but JavaScript for large chunks often arrives all at once.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;React &lt;strong&gt;Server Components (RSC)&lt;/strong&gt; aim to address these issues while preserving React’s developer experience.&lt;/p&gt;




&lt;h2&gt;
  
  
  What &lt;em&gt;is&lt;/em&gt; a Server Component?
&lt;/h2&gt;

&lt;p&gt;A &lt;em&gt;server component&lt;/em&gt; is rendered &lt;strong&gt;only on the server&lt;/strong&gt;. It never appears in the client bundle, so there is &lt;strong&gt;zero JavaScript cost&lt;/strong&gt; for that component in the browser.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight tsx"&gt;&lt;code&gt;&lt;span class="c1"&gt;// app/page.tsx   (Next.js 14+)&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="nx"&gt;ProductList&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;./ProductList&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="c1"&gt;// ✅ server component&lt;/span&gt;

&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="k"&gt;default&lt;/span&gt; &lt;span class="k"&gt;async&lt;/span&gt; &lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;Page&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{{&lt;/span&gt;
  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;products&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nf"&gt;fetchProducts&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt; &lt;span class="c1"&gt;// runs on the server&lt;/span&gt;
  &lt;span class="k"&gt;return &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nt"&gt;main&lt;/span&gt; &lt;span class="na"&gt;className&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;"p-6"&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
      &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nt"&gt;h1&lt;/span&gt; &lt;span class="na"&gt;className&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;"text-3xl font-semibold mb-4"&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;Our catalog&lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nt"&gt;h1&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
      &lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="cm"&gt;/* ProductList is rendered on the server; 
          the HTML is streamed to the client. */&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;
      &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;ProductList&lt;/span&gt; &lt;span class="na"&gt;products&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;products&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt; &lt;span class="p"&gt;/&amp;gt;&lt;/span&gt;
    &lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nt"&gt;main&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
  &lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="p"&gt;}}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Key characteristics
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;Can &lt;strong&gt;&lt;code&gt;await&lt;/code&gt;&lt;/strong&gt; database or API calls directly.&lt;/li&gt;
&lt;li&gt;Output is &lt;strong&gt;HTML only&lt;/strong&gt;; no client‑side JS bundle.&lt;/li&gt;
&lt;li&gt;Can render &lt;strong&gt;client components&lt;/strong&gt; as children (marked with &lt;code&gt;"use client"&lt;/code&gt;).&lt;/li&gt;
&lt;/ul&gt;




&lt;h2&gt;
  
  
  Automatic Code Splitting (RSC vs. &lt;code&gt;React.lazy()&lt;/code&gt;)
&lt;/h2&gt;

&lt;p&gt;Traditional React relies on &lt;strong&gt;dynamic import&lt;/strong&gt; patterns:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight tsx"&gt;&lt;code&gt;&lt;span class="c1"&gt;// Before&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="nx"&gt;React&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;{{&lt;/span&gt; &lt;span class="nx"&gt;lazy&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;Suspense&lt;/span&gt; &lt;span class="p"&gt;}}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;react&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;HeavyChart&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;lazy&lt;/span&gt;&lt;span class="p"&gt;(()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="k"&gt;import&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;./HeavyChart&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;));&lt;/span&gt;

&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;Dashboard&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{{&lt;/span&gt;
  &lt;span class="k"&gt;return &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;Suspense&lt;/span&gt; &lt;span class="na"&gt;fallback&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;Spinner&lt;/span&gt;&lt;span class="o"&gt;/&amp;gt;&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
      &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;HeavyChart&lt;/span&gt; &lt;span class="p"&gt;/&amp;gt;&lt;/span&gt;
    &lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nc"&gt;Suspense&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
  &lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="p"&gt;}}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;With Server Components, React performs &lt;strong&gt;tree‑shaking on the server&lt;/strong&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight tsx"&gt;&lt;code&gt;&lt;span class="c1"&gt;// After – HeavyChart is a Server Component&lt;/span&gt;
&lt;span class="c1"&gt;// It is excluded from the client bundle automatically.&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="nx"&gt;HeavyChart&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;./HeavyChart&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="c1"&gt;// no 'lazy' needed&lt;/span&gt;

&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;Dashboard&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{{&lt;/span&gt;
  &lt;span class="k"&gt;return &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="p"&gt;&amp;lt;&amp;gt;&lt;/span&gt;
      &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;Summary&lt;/span&gt; &lt;span class="p"&gt;/&amp;gt;&lt;/span&gt;
      &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;HeavyChart&lt;/span&gt; &lt;span class="p"&gt;/&amp;gt;&lt;/span&gt; &lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="cm"&gt;/* streamed as HTML; zero JS sent */&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;
    &lt;span class="p"&gt;&amp;lt;/&amp;gt;&lt;/span&gt;
  &lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="p"&gt;}}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Because &lt;code&gt;HeavyChart&lt;/code&gt; never reaches the browser, &lt;strong&gt;code splitting becomes implicit&lt;/strong&gt;—React ships &lt;em&gt;only&lt;/em&gt; the minimal JS required for interactive parts.&lt;/p&gt;




&lt;h2&gt;
  
  
  SSR vs. Server Components — at a glance
&lt;/h2&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Capability&lt;/th&gt;
&lt;th&gt;Classic SSR&lt;/th&gt;
&lt;th&gt;React Server Components&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Eliminates client JS for non‑interactive UI&lt;/td&gt;
&lt;td&gt;❌ No (hydration needed)&lt;/td&gt;
&lt;td&gt;✅ Yes&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Can access secure server resources &lt;em&gt;during&lt;/em&gt; render&lt;/td&gt;
&lt;td&gt;✅ Yes&lt;/td&gt;
&lt;td&gt;✅ Yes&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Partial streaming without extra bundling config&lt;/td&gt;
&lt;td&gt;🚧 Limited&lt;/td&gt;
&lt;td&gt;✅ Built‑in&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Requires hydration cost in the browser&lt;/td&gt;
&lt;td&gt;✅ Always&lt;/td&gt;
&lt;td&gt;⚠️ Only for client components&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Works with existing &lt;code&gt;useEffect&lt;/code&gt;, DOM APIs&lt;/td&gt;
&lt;td&gt;✅ Yes&lt;/td&gt;
&lt;td&gt;⚠️ Only inside client components&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Ships duplicate logic (server + client)&lt;/td&gt;
&lt;td&gt;✅ Often&lt;/td&gt;
&lt;td&gt;❌ Never for pure server components&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;




&lt;h2&gt;
  
  
  Putting it together
&lt;/h2&gt;

&lt;p&gt;Server Components &lt;strong&gt;complement&lt;/strong&gt; — not replace — SSR:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;SSR&lt;/strong&gt; is still useful for the shell of your page and for client components that need early HTML.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;RSC&lt;/strong&gt; lets you push heavy, non‑interactive work entirely to the server, trimming bundles and hydration time.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;In practice you’ll mix them:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight tsx"&gt;&lt;code&gt;&lt;span class="c1"&gt;// 'layout.tsx' is a server component by default&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;@/styles/globals.css&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{{&lt;/span&gt; &lt;span class="nx"&gt;Suspense&lt;/span&gt; &lt;span class="p"&gt;}}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;react&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="k"&gt;default&lt;/span&gt; &lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;RootLayout&lt;/span&gt;&lt;span class="p"&gt;({{&lt;/span&gt; &lt;span class="nx"&gt;children&lt;/span&gt; &lt;span class="p"&gt;}})&lt;/span&gt; &lt;span class="p"&gt;{{&lt;/span&gt;
  &lt;span class="k"&gt;return &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nt"&gt;html&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
      &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nt"&gt;body&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
        &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;NavBar&lt;/span&gt; &lt;span class="p"&gt;/&amp;gt;&lt;/span&gt;              &lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="cm"&gt;/* client component */&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;
        &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;Suspense&lt;/span&gt; &lt;span class="na"&gt;fallback&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;Skeleton&lt;/span&gt;&lt;span class="o"&gt;/&amp;gt;&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
          &lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;children&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;           &lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="cm"&gt;/* could include server + client parts */&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;
        &lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nc"&gt;Suspense&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
      &lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nt"&gt;body&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
    &lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nt"&gt;html&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
  &lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="p"&gt;}}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h2&gt;
  
  
  Conclusion
&lt;/h2&gt;

&lt;p&gt;React Server Components let you &lt;strong&gt;scale UX and codebases&lt;/strong&gt; without punishing runtime performance:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Smaller client bundles&lt;/strong&gt; – ship less JavaScript.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Faster TTI&lt;/strong&gt; – fewer hydration bytes, more streaming.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Simpler data fetching&lt;/strong&gt; – &lt;code&gt;await&lt;/code&gt; directly in components.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Automatic code splitting&lt;/strong&gt; – implicit through server‑only execution.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;As teams iterate, &lt;strong&gt;learning when to choose a client vs. server boundary&lt;/strong&gt; becomes the new architecture art. &lt;em&gt;Learning Patterns&lt;/em&gt; reminds us that patterns evolve; RSC is the natural next turn in React’s performance playbook.&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Happy hacking—see you in the diff!&lt;/em&gt;&lt;/p&gt;

</description>
    </item>
    <item>
      <title>Streaming Server‑Side Rendering in React: A Learning Patterns Deep Dive</title>
      <dc:creator>Md Enayetur Rahman</dc:creator>
      <pubDate>Sat, 13 Dec 2025 09:32:20 +0000</pubDate>
      <link>https://dev.to/md_enayeturrahman_2560e3/streaming-server-side-rendering-in-react-a-learning-patterns-deep-dive-ka</link>
      <guid>https://dev.to/md_enayeturrahman_2560e3/streaming-server-side-rendering-in-react-a-learning-patterns-deep-dive-ka</guid>
      <description>&lt;h2&gt;
  
  
  Table of Contents
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;
Streaming Server‑Side Rendering in React: A Learning Patterns Deep Dive

&lt;ul&gt;
&lt;li&gt;Table of Contents&lt;/li&gt;
&lt;li&gt;What Is Streaming Server‑Side Rendering?&lt;/li&gt;
&lt;li&gt;Why Streaming?&lt;/li&gt;
&lt;li&gt;How React Implements Streaming&lt;/li&gt;
&lt;li&gt;Code Example – Express + React 18&lt;/li&gt;
&lt;li&gt;Three Takeaways&lt;/li&gt;
&lt;li&gt;Pros &amp;amp; Cons&lt;/li&gt;
&lt;li&gt;Conclusion&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;

&lt;/ul&gt;




&lt;h2&gt;
  
  
  What Is Streaming Server‑Side Rendering?
&lt;/h2&gt;

&lt;p&gt;Traditional &lt;strong&gt;server‑side rendering (SSR)&lt;/strong&gt; waits until the entire HTML for a page is ready before sending it to the browser. Streaming SSR, by contrast, sends &lt;em&gt;chunks&lt;/em&gt; of HTML as soon as they are generated.&lt;br&gt;&lt;br&gt;
This allows the browser to start parsing, painting, and hydrating the parts of the UI that are ready, improving &lt;strong&gt;Time to First Byte (TTFB)&lt;/strong&gt; and &lt;strong&gt;Largest Contentful Paint (LCP)&lt;/strong&gt;.&lt;/p&gt;


&lt;h2&gt;
  
  
  Why Streaming?
&lt;/h2&gt;

&lt;p&gt;From &lt;em&gt;Learning Patterns&lt;/em&gt;:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Progressive Perceived Performance&lt;/strong&gt; – users see something sooner, even on slow networks.
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Reduced Blocking&lt;/strong&gt; – slow data fetching or expensive computations in one part of the tree no longer block the entire document.
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Back‑pressure Friendly&lt;/strong&gt; – servers can push bytes as they become available, smoothing CPU spikes.&lt;/li&gt;
&lt;/ul&gt;


&lt;h2&gt;
  
  
  How React Implements Streaming
&lt;/h2&gt;

&lt;p&gt;React 18 introduced two APIs inside &lt;strong&gt;&lt;code&gt;react-dom/server&lt;/code&gt;&lt;/strong&gt;:&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;API&lt;/th&gt;
&lt;th&gt;Environment&lt;/th&gt;
&lt;th&gt;Description&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;renderToPipeableStream()&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Node.js (streams)&lt;/td&gt;
&lt;td&gt;Emits HTML chunks into a Node &lt;em&gt;Writable&lt;/em&gt; (e.g., an HTTP response).&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;renderToReadableStream()&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Edge runtimes / Deno&lt;/td&gt;
&lt;td&gt;Emits a &lt;em&gt;web&lt;/em&gt; &lt;code&gt;ReadableStream&lt;/code&gt; for platforms like Cloudflare Workers.&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;Key concepts from the book:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Suspense Boundaries&lt;/strong&gt; act as natural chunk boundaries.
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Client‑Side Hydration&lt;/strong&gt; still happens, but progressively (&lt;code&gt;hydrateRoot&lt;/code&gt;).
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Error Entrapment&lt;/strong&gt; – errors inside a boundary stream a fallback instead of crashing the whole response.&lt;/li&gt;
&lt;/ol&gt;



&lt;p&gt;&lt;a id="code-example"&gt;&lt;/a&gt;&lt;/p&gt;
&lt;h2&gt;
  
  
  Code Example – Express + React 18
&lt;/h2&gt;

&lt;p&gt;Below is a minimal, production‑safe example that streams an app using &lt;strong&gt;&lt;code&gt;renderToPipeableStream&lt;/code&gt;&lt;/strong&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight tsx"&gt;&lt;code&gt;&lt;span class="c1"&gt;// server.ts&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="nx"&gt;express&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;express&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="nx"&gt;fs&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;fs&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;renderToPipeableStream&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;react-dom/server&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="nx"&gt;App&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;./App&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="nx"&gt;React&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;react&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;app&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;express&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;

&lt;span class="nx"&gt;app&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;get&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;*&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;req&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;res&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="c1"&gt;// Prepare HTML shell&lt;/span&gt;
  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;pipe&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;renderToPipeableStream&lt;/span&gt;&lt;span class="p"&gt;(&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;App&lt;/span&gt; &lt;span class="na"&gt;url&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;req&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;url&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt; &lt;span class="p"&gt;/&amp;gt;,&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nf"&gt;onShellReady&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="c1"&gt;// Set headers early for better streaming&lt;/span&gt;
      &lt;span class="nx"&gt;res&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;statusCode&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;200&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
      &lt;span class="nx"&gt;res&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;setHeader&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Content-Type&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;text/html&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

      &lt;span class="c1"&gt;// Begin streaming!&lt;/span&gt;
      &lt;span class="nf"&gt;pipe&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;res&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="p"&gt;},&lt;/span&gt;
    &lt;span class="nf"&gt;onError&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;err&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;error&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;err&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="p"&gt;},&lt;/span&gt;
  &lt;span class="p"&gt;});&lt;/span&gt;

  &lt;span class="c1"&gt;// Abort the stream if the client disconnects&lt;/span&gt;
  &lt;span class="nx"&gt;res&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;on&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;close&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nx"&gt;pipe&lt;/span&gt;&lt;span class="p"&gt;?.&lt;/span&gt;&lt;span class="nx"&gt;abort&lt;/span&gt;&lt;span class="p"&gt;?.());&lt;/span&gt;
&lt;span class="p"&gt;});&lt;/span&gt;

&lt;span class="nx"&gt;app&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;listen&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;3000&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt;
  &lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;➜  Server listening at http://localhost:3000 🚀&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;





&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight tsx"&gt;&lt;code&gt;&lt;span class="c1"&gt;// App.tsx&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="nx"&gt;React&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;Suspense&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;react&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;Router&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;./Router&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="k"&gt;default&lt;/span&gt; &lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;App&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt; &lt;span class="nx"&gt;url&lt;/span&gt; &lt;span class="p"&gt;}:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nl"&gt;url&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kr"&gt;string&lt;/span&gt; &lt;span class="p"&gt;})&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="k"&gt;return &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;Suspense&lt;/span&gt; &lt;span class="na"&gt;fallback&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nt"&gt;p&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;Loading…&lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nt"&gt;p&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
      &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;Router&lt;/span&gt; &lt;span class="na"&gt;initialUrl&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;url&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt; &lt;span class="p"&gt;/&amp;gt;&lt;/span&gt;
    &lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nc"&gt;Suspense&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
  &lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Three Takeaways
&lt;/h3&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;&lt;code&gt;onShellReady&lt;/code&gt;&lt;/strong&gt; fires when the initial HTML shell is ready (no data).
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Suspense fallbacks&lt;/strong&gt; are sent immediately; React in the browser swaps them when data resolves.
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Abort logic&lt;/strong&gt; prevents resource leaks if the connection drops.&lt;/li&gt;
&lt;/ol&gt;




&lt;h2&gt;
  
  
  Pros &amp;amp; Cons
&lt;/h2&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;&lt;/th&gt;
&lt;th&gt;&lt;strong&gt;Pros&lt;/strong&gt;&lt;/th&gt;
&lt;th&gt;&lt;strong&gt;Cons&lt;/strong&gt;&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Performance&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Faster &lt;em&gt;FCP&lt;/em&gt; &amp;amp; &lt;em&gt;LCP&lt;/em&gt;; critical CSS/JS can stream early.&lt;/td&gt;
&lt;td&gt;Extra bytes from multiple script tags and fallbacks.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;User Perception&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Immediate feedback reduces bounce rates.&lt;/td&gt;
&lt;td&gt;Janky experience if fallbacks are poorly designed.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Scalability&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Better CPU utilization under load; back‑pressure friendly.&lt;/td&gt;
&lt;td&gt;Longer connections per request can hurt throughput on very chatty pages.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Developer DX&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Works with Suspense; single render pass; minimal boilerplate.&lt;/td&gt;
&lt;td&gt;More moving parts (streaming + hydration), dev tools still maturing.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;SEO&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Crawlers receive meaningful HTML sooner.&lt;/td&gt;
&lt;td&gt;Some bots don’t execute JS; ensure critical markup is in the shell.&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;




&lt;h2&gt;
  
  
  Conclusion
&lt;/h2&gt;

&lt;p&gt;Streaming SSR equips React apps with a &lt;strong&gt;progressive rendering pipeline&lt;/strong&gt; that can dramatically enhance real‑world performance, especially on slower networks.&lt;br&gt;&lt;br&gt;
However, like every pattern in &lt;em&gt;Learning Patterns&lt;/em&gt;, it shines only when aligned with product constraints:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Use it when&lt;/strong&gt; you have data bottlenecks or large above‑the‑fold payloads.
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Think twice when&lt;/strong&gt; your pages are mostly static, or when infrastructure limits long‑lived connections.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Experiment, measure, and iterate—&lt;strong&gt;bytes don’t lie&lt;/strong&gt;. 🏎️&lt;/p&gt;




&lt;p&gt;&lt;em&gt;References&lt;/em&gt;  &lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Hallie, Lydia &amp;amp; Osmani, Addy. &lt;strong&gt;“Learning Patterns.”&lt;/strong&gt; Chapter “Streaming Server‑Side Rendering”.
&lt;/li&gt;
&lt;li&gt;React 18 RFC: "Selective Hydration &amp;amp; Streaming".
&lt;/li&gt;
&lt;/ul&gt;

</description>
    </item>
    <item>
      <title>Progressive Hydration in React: Taming the Hydration Monster</title>
      <dc:creator>Md Enayetur Rahman</dc:creator>
      <pubDate>Sat, 13 Dec 2025 09:29:19 +0000</pubDate>
      <link>https://dev.to/md_enayeturrahman_2560e3/progressive-hydration-in-react-taming-the-hydration-monster-2n9a</link>
      <guid>https://dev.to/md_enayeturrahman_2560e3/progressive-hydration-in-react-taming-the-hydration-monster-2n9a</guid>
      <description>&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Learning Patterns Deep‑Dive – Pattern 45&lt;/strong&gt;&lt;br&gt;&lt;br&gt;
&lt;em&gt;Based on “Learning Patterns” by Lydia Hallie &amp;amp; Addy Osmani&lt;/em&gt;  &lt;/p&gt;
&lt;/blockquote&gt;




&lt;h2&gt;
  
  
  Table of Contents
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;
Progressive Hydration in React: Taming the Hydration Monster

&lt;ul&gt;
&lt;li&gt;Table of Contents&lt;/li&gt;
&lt;li&gt;The Hydration Problem&lt;/li&gt;
&lt;li&gt;Why Traditional Hydration Breaks Down&lt;/li&gt;
&lt;li&gt;Meet Progressive Hydration&lt;/li&gt;
&lt;li&gt;How it Works&lt;/li&gt;
&lt;li&gt;Implementation Walk‑through&lt;/li&gt;
&lt;li&gt;Step 1 – Identify Hydration Boundaries&lt;/li&gt;
&lt;li&gt;Step 2 – Lazy‑load &amp;amp; Hydrate on Demand&lt;/li&gt;
&lt;li&gt;Step 3 – Scheduling with Concurrent Mode&lt;/li&gt;
&lt;li&gt;Step 4 – Bringing in React Server Components&lt;/li&gt;
&lt;li&gt;Pros &amp;amp; Cons&lt;/li&gt;
&lt;li&gt;✅ Pros&lt;/li&gt;
&lt;li&gt;❌ Cons&lt;/li&gt;
&lt;li&gt;Conclusion&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;

&lt;/ul&gt;




&lt;h2&gt;
  
  
  The Hydration Problem
&lt;/h2&gt;

&lt;p&gt;Server‑side rendering (SSR) sends a &lt;strong&gt;static HTML shell&lt;/strong&gt; to the browser, then JavaScript “hydrates” it by attaching React’s event listeners and state.&lt;br&gt;&lt;br&gt;
While SSR improves &lt;strong&gt;First Contentful Paint (FCP)&lt;/strong&gt;, classic hydration still blocks the main thread:&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Pain Point&lt;/th&gt;
&lt;th&gt;Why it happens&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;⚙️ &lt;strong&gt;Long block on JS execution&lt;/strong&gt;
&lt;/td&gt;
&lt;td&gt;All component bundles download &amp;amp; execute &lt;em&gt;before&lt;/em&gt; the page becomes interactive.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;💤 &lt;strong&gt;Slow Time‑to‑Interactive (TTI)&lt;/strong&gt;
&lt;/td&gt;
&lt;td&gt;The entire app competes for the main thread at once.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;🤯 &lt;strong&gt;Jank on low‑end devices&lt;/strong&gt;
&lt;/td&gt;
&lt;td&gt;Big hydration tasks freeze scrolling &amp;amp; gestures.&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;




&lt;h2&gt;
  
  
  Why Traditional Hydration Breaks Down
&lt;/h2&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Monolithic&lt;/strong&gt; – One huge hydration task, regardless of what the user actually sees.
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Priority‑blind&lt;/strong&gt; – A hidden accordion in the footer hydrates as early as the hero carousel.
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Bandwidth‑heavy&lt;/strong&gt; – JS for every route ships up front, wasting KBs on first paint.
&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;&lt;em&gt;Learning Patterns&lt;/em&gt; frames this as the “&lt;strong&gt;Hydration Bottleneck&lt;/strong&gt;” and urges us to “treat hydration like we treat code‑splitting: progressively.”  &lt;/p&gt;




&lt;h2&gt;
  
  
  Meet Progressive Hydration
&lt;/h2&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Definition&lt;/strong&gt; – &lt;em&gt;Hydrate only the parts of the UI that matter **when&lt;/em&gt;* they matter.*  &lt;/p&gt;
&lt;/blockquote&gt;

&lt;h3&gt;
  
  
  How it Works
&lt;/h3&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Islands / Boundaries&lt;/strong&gt; – Slice your markup into “islands” (interactive) and “static ocean” (just HTML+CSS).
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Lazy Bundles&lt;/strong&gt; – Each island ships its own JS chunk, deferred or preloaded.
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Event Replay&lt;/strong&gt; – User events captured before hydration are replayed once the island is ready.
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Scheduler Integration&lt;/strong&gt; – React 18’s &lt;code&gt;startTransition()&lt;/code&gt; lets hydration yield to more urgent work.
&lt;/li&gt;
&lt;/ol&gt;

&lt;blockquote&gt;
&lt;p&gt;⛵ &lt;strong&gt;Analogy:&lt;/strong&gt; Instead of refitting the whole ship in dry‑dock, fix one deck at a time &lt;em&gt;while&lt;/em&gt; the ship keeps sailing.&lt;/p&gt;
&lt;/blockquote&gt;




&lt;h2&gt;
  
  
  Implementation Walk‑through
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Step 1 – Identify Hydration Boundaries
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight jsx"&gt;&lt;code&gt;&lt;span class="cm"&gt;/* server.jsx – React 18 SSR */&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;Suspense&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;react&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="nx"&gt;Footer&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;./islands/Footer.client&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;   &lt;span class="c1"&gt;// interactive island&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="nx"&gt;Hero&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;./islands/Hero.client&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;       &lt;span class="c1"&gt;// interactive island&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="nx"&gt;StaticTestimonials&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;./components/StaticTestimonials&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="c1"&gt;// no JS&lt;/span&gt;

&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="k"&gt;default&lt;/span&gt; &lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;App&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="k"&gt;return &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="p"&gt;&amp;lt;&amp;gt;&lt;/span&gt;
      &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;Hero&lt;/span&gt; &lt;span class="p"&gt;/&amp;gt;&lt;/span&gt;
      &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;StaticTestimonials&lt;/span&gt; &lt;span class="p"&gt;/&amp;gt;&lt;/span&gt;
      &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;Footer&lt;/span&gt; &lt;span class="p"&gt;/&amp;gt;&lt;/span&gt;
    &lt;span class="p"&gt;&amp;lt;/&amp;gt;&lt;/span&gt;
  &lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;Files ending in &lt;code&gt;.client&lt;/code&gt; compile into JS bundles.
&lt;/li&gt;
&lt;li&gt;Components without that suffix render as pure HTML.&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Step 2 – Lazy‑load &amp;amp; Hydrate on Demand
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight jsx"&gt;&lt;code&gt;&lt;span class="c1"&gt;// islands/Hero.client.jsx&lt;/span&gt;
&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;use client&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;useEffect&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;react&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="k"&gt;default&lt;/span&gt; &lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;Hero&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nf"&gt;useEffect&lt;/span&gt;&lt;span class="p"&gt;(()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Hero island hydrated! 🚀&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="p"&gt;},&lt;/span&gt; &lt;span class="p"&gt;[]);&lt;/span&gt;
  &lt;span class="cm"&gt;/* …interactive JSX… */&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The server streams the markup right away; the JS for &lt;code&gt;Hero&lt;/code&gt; downloads only when needed (e.g., via &lt;code&gt;import()&lt;/code&gt; or HTTP/2 Push).&lt;/p&gt;

&lt;h3&gt;
  
  
  Step 3 – Scheduling with Concurrent Mode
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight jsx"&gt;&lt;code&gt;&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;startTransition&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;react&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;hydrateIsland&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;importFn&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nf"&gt;startTransition&lt;/span&gt;&lt;span class="p"&gt;(()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nf"&gt;importFn&lt;/span&gt;&lt;span class="p"&gt;().&lt;/span&gt;&lt;span class="nf"&gt;then&lt;/span&gt;&lt;span class="p"&gt;(({&lt;/span&gt; &lt;span class="na"&gt;default&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;Island&lt;/span&gt; &lt;span class="p"&gt;})&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="nx"&gt;ReactDOM&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;createRoot&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;container&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nf"&gt;render&lt;/span&gt;&lt;span class="p"&gt;(&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;Island&lt;/span&gt; &lt;span class="p"&gt;/&amp;gt;);&lt;/span&gt;
    &lt;span class="p"&gt;});&lt;/span&gt;
  &lt;span class="p"&gt;});&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;startTransition&lt;/code&gt; tells React: &lt;strong&gt;“lower priority; keep the UI responsive.”&lt;/strong&gt;
&lt;/li&gt;
&lt;li&gt;Hydration yields to user input, tackling islands when the thread is free.&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Step 4 – Bringing in React Server Components
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight jsx"&gt;&lt;code&gt;&lt;span class="c1"&gt;// app/page.server.jsx  (Next.js / React 18)&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="nx"&gt;ProductList&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;./ProductList.server&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="k"&gt;default&lt;/span&gt; &lt;span class="k"&gt;async&lt;/span&gt; &lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;Page&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;products&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nf"&gt;fetch&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;/api/products&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nf"&gt;then&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;r&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nx"&gt;r&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;json&lt;/span&gt;&lt;span class="p"&gt;());&lt;/span&gt;
  &lt;span class="k"&gt;return &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="p"&gt;&amp;lt;&amp;gt;&lt;/span&gt;
      &lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="cm"&gt;/* Renders on the server, zero JS sent */&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;
      &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;ProductList&lt;/span&gt; &lt;span class="na"&gt;products&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;products&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt; &lt;span class="p"&gt;/&amp;gt;&lt;/span&gt;

      &lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="cm"&gt;/* Hydrated client island for the cart */&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;
      &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;AddToCartButton&lt;/span&gt; &lt;span class="p"&gt;/&amp;gt;&lt;/span&gt;
    &lt;span class="p"&gt;&amp;lt;/&amp;gt;&lt;/span&gt;
  &lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Server Components stream &lt;em&gt;ready‑to‑use HTML&lt;/em&gt;; only truly interactive islands (e.g., &lt;code&gt;AddToCartButton&lt;/code&gt;) ship JS and hydrate progressively.&lt;/p&gt;




&lt;h2&gt;
  
  
  Pros &amp;amp; Cons
&lt;/h2&gt;

&lt;h3&gt;
  
  
  ✅ Pros
&lt;/h3&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Faster TTI&lt;/strong&gt; – Only critical islands block interactivity.
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Lower JS Cost&lt;/strong&gt; – Each page loads &lt;em&gt;just enough&lt;/em&gt; code.
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Graceful Degradation&lt;/strong&gt; – Static parts work even if JS fails.
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Main‑thread Friendly&lt;/strong&gt; – Hydration tasks can yield via Concurrent Mode.
&lt;/li&gt;
&lt;/ol&gt;

&lt;h3&gt;
  
  
  ❌ Cons
&lt;/h3&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Complex Build Setup&lt;/strong&gt; – Need split pipelines for server vs client code.
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Tooling Maturity&lt;/strong&gt; – RSC &amp;amp; progressive hydration are still evolving.
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Event Replay Edge Cases&lt;/strong&gt; – Lost events if not buffered correctly.
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Debugging Overhead&lt;/strong&gt; – Mixed execution contexts (server/client) complicate tracing.&lt;/li&gt;
&lt;/ol&gt;




&lt;h2&gt;
  
  
  Conclusion
&lt;/h2&gt;

&lt;p&gt;Progressive hydration flips the traditional SSR model on its head: &lt;strong&gt;hydrate what matters, &lt;em&gt;when&lt;/em&gt; it matters.&lt;/strong&gt;&lt;br&gt;&lt;br&gt;
With React 18’s Concurrent Mode and the emerging React Server Components architecture, you can ship lighter pages, stay responsive, and delight users—especially on slow networks and devices.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Takeaway:&lt;/strong&gt; Start small. Convert a footer or sidebar into an island, measure TTI, then iterate. The performance gains compound quickly!&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Happy hydrating! 💧&lt;/p&gt;

</description>
    </item>
    <item>
      <title>Incremental Static Generation (ISR) in Next.js: Freshness at Scale</title>
      <dc:creator>Md Enayetur Rahman</dc:creator>
      <pubDate>Sat, 13 Dec 2025 09:26:48 +0000</pubDate>
      <link>https://dev.to/md_enayeturrahman_2560e3/incremental-static-generation-isr-in-nextjs-freshness-at-scale-m4b</link>
      <guid>https://dev.to/md_enayeturrahman_2560e3/incremental-static-generation-isr-in-nextjs-freshness-at-scale-m4b</guid>
      <description>&lt;p&gt;Modern teams love &lt;strong&gt;Static Site Generation (SSG)&lt;/strong&gt; for its speed and reliability. But as your site grows—and content changes frequently—pure SSG starts to hurt: builds get slow, pages go stale, and redeploys become bottlenecks. &lt;strong&gt;Incremental Static Generation (ISR)&lt;/strong&gt; is the practical pattern that keeps static &lt;strong&gt;fast&lt;/strong&gt; while making it &lt;strong&gt;fresh&lt;/strong&gt;.&lt;/p&gt;




&lt;h2&gt;
  
  
  1) The problem with pure SSG
&lt;/h2&gt;

&lt;p&gt;SSG pre-renders pages at build time and serves them from a CDN. That’s fantastic for performance but introduces a few pain points at scale:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Stale content&lt;/strong&gt;: Once deployed, pages don’t update until the &lt;em&gt;next build&lt;/em&gt;. News, pricing, stock, and listings drift out of date.
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Long build times&lt;/strong&gt;: Large sites require generating thousands of pages in a single build, slowing CI/CD.
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;All-or-nothing deployments&lt;/strong&gt;: A tiny copy change requires a whole-site rebuild &amp;amp; redeploy.
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Operational friction&lt;/strong&gt;: Content teams depend on developer-triggered deploys to publish updates.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Goal:&lt;/strong&gt; Keep static speed, reduce staleness, and decouple content updates from full redeploys.&lt;/p&gt;




&lt;h2&gt;
  
  
  2) How ISR solves it (mental model)
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;Incremental Static Regeneration&lt;/strong&gt; (ISR) allows pages to be &lt;strong&gt;statically generated&lt;/strong&gt; and &lt;strong&gt;regenerated&lt;/strong&gt; after a configurable interval or &lt;strong&gt;on demand&lt;/strong&gt;—&lt;em&gt;without&lt;/em&gt; a full rebuild.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Serve static instantly&lt;/strong&gt; from cache/CDN.
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Revalidate&lt;/strong&gt; the page in the background when it’s “too old” or when a change is pushed.
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Next request&lt;/strong&gt; gets the fresh page; failures keep the last good version.
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Granular control&lt;/strong&gt;: choose per-page timing or trigger updates per path or per data “tag”.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;This follows a familiar pattern: &lt;em&gt;cache + time/notification-based invalidation&lt;/em&gt;, analogous to &lt;strong&gt;stale‑while‑revalidate&lt;/strong&gt;.&lt;/p&gt;




&lt;h2&gt;
  
  
  3) How ISR works under the hood (flow)
&lt;/h2&gt;

&lt;ol&gt;
&lt;li&gt;First request after build renders and caches the static HTML.
&lt;/li&gt;
&lt;li&gt;Subsequent requests are served from cache (fast).
&lt;/li&gt;
&lt;li&gt;When the page exceeds its &lt;strong&gt;revalidate window&lt;/strong&gt; (e.g., 60s), a request triggers &lt;strong&gt;background regeneration&lt;/strong&gt;.
&lt;/li&gt;
&lt;li&gt;If regeneration succeeds, the cache swaps in the fresh HTML atomically.
&lt;/li&gt;
&lt;li&gt;If regeneration fails, the old version remains (graceful degradation).&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;You control &lt;em&gt;when&lt;/em&gt; this happens (time-based) and &lt;em&gt;what&lt;/em&gt; gets refreshed (path- or tag-based on-demand revalidation).&lt;/p&gt;




&lt;h2&gt;
  
  
  4) Code: Pages Router (Next.js 12/13+)
&lt;/h2&gt;

&lt;h3&gt;
  
  
  a) Time-based revalidation with &lt;code&gt;getStaticProps&lt;/code&gt;
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight tsx"&gt;&lt;code&gt;&lt;span class="c1"&gt;// pages/products/[id].tsx&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;GetStaticPaths&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;GetStaticProps&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;next&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;getStaticPaths&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;GetStaticPaths&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;async &lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="c1"&gt;// Pre-render a subset; fall back for the rest&lt;/span&gt;
  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;ids&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nf"&gt;fetchFeaturedIds&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
  &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="na"&gt;paths&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;ids&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;map&lt;/span&gt;&lt;span class="p"&gt;((&lt;/span&gt;&lt;span class="nx"&gt;id&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;({&lt;/span&gt; &lt;span class="na"&gt;params&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;id&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="p"&gt;})),&lt;/span&gt;
    &lt;span class="na"&gt;fallback&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;blocking&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="c1"&gt;// or true (shows a fallback UI)&lt;/span&gt;
  &lt;span class="p"&gt;};&lt;/span&gt;
&lt;span class="p"&gt;};&lt;/span&gt;

&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;getStaticProps&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;GetStaticProps&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;async &lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt; &lt;span class="nx"&gt;params&lt;/span&gt; &lt;span class="p"&gt;})&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;product&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nf"&gt;fetchProduct&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;params&lt;/span&gt;&lt;span class="o"&gt;!&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;id&lt;/span&gt; &lt;span class="k"&gt;as&lt;/span&gt; &lt;span class="kr"&gt;string&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="k"&gt;if &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;!&lt;/span&gt;&lt;span class="nx"&gt;product&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="na"&gt;notFound&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;true&lt;/span&gt; &lt;span class="p"&gt;};&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;
  &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="na"&gt;props&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;product&lt;/span&gt; &lt;span class="p"&gt;},&lt;/span&gt;
    &lt;span class="c1"&gt;// Re-generate this page in the background at most once per 60 seconds&lt;/span&gt;
    &lt;span class="na"&gt;revalidate&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;60&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="p"&gt;};&lt;/span&gt;
&lt;span class="p"&gt;};&lt;/span&gt;

&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="k"&gt;default&lt;/span&gt; &lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;ProductPage&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt; &lt;span class="nx"&gt;product&lt;/span&gt; &lt;span class="p"&gt;}:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nl"&gt;product&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;Product&lt;/span&gt; &lt;span class="p"&gt;})&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;ProductView&lt;/span&gt; &lt;span class="na"&gt;product&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;product&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt; &lt;span class="p"&gt;/&amp;gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Notes&lt;/strong&gt;  &lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;fallback: 'blocking'&lt;/code&gt; avoids a visible loading state for uncached paths.
&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;revalidate: 60&lt;/code&gt; means the page may be regenerated in the background at most once per 60 seconds after it becomes stale.&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  b) On-demand revalidation (Pages Router)
&lt;/h3&gt;

&lt;p&gt;Create an API route that your CMS/webhook can call after content changes:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="c1"&gt;// pages/api/revalidate.ts&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="kd"&gt;type&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;NextApiRequest&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;NextApiResponse&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;next&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="k"&gt;default&lt;/span&gt; &lt;span class="k"&gt;async&lt;/span&gt; &lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;handler&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;req&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;NextApiRequest&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;res&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;NextApiResponse&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="c1"&gt;// 1) Verify a secret to prevent abuse&lt;/span&gt;
  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;secret&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;process&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;env&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;REVALIDATE_SECRET&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="k"&gt;if &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;req&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;query&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;secret&lt;/span&gt; &lt;span class="o"&gt;!==&lt;/span&gt; &lt;span class="nx"&gt;secret&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nx"&gt;res&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;status&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;401&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nf"&gt;json&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt; &lt;span class="na"&gt;message&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Invalid token&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt; &lt;span class="p"&gt;});&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;

  &lt;span class="k"&gt;try&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;path&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;req&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;query&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="k"&gt;if &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;typeof&lt;/span&gt; &lt;span class="nx"&gt;path&lt;/span&gt; &lt;span class="o"&gt;!==&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;string&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nx"&gt;res&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;status&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;400&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nf"&gt;json&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt; &lt;span class="na"&gt;message&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Missing ?path=&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt; &lt;span class="p"&gt;});&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;

    &lt;span class="c1"&gt;// 2) Revalidate the given path&lt;/span&gt;
    &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nx"&gt;res&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;revalidate&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;path&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt; &lt;span class="c1"&gt;// e.g., "/products/123"&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nx"&gt;res&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;json&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt; &lt;span class="na"&gt;revalidated&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;path&lt;/span&gt; &lt;span class="p"&gt;});&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;catch &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;err&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nx"&gt;res&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;status&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;500&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nf"&gt;json&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt; &lt;span class="na"&gt;revalidated&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;false&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="na"&gt;error&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;err&lt;/span&gt; &lt;span class="k"&gt;as&lt;/span&gt; &lt;span class="nb"&gt;Error&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nx"&gt;message&lt;/span&gt; &lt;span class="p"&gt;});&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;How to use&lt;/strong&gt;  &lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Configure your CMS to hit &lt;code&gt;/api/revalidate?secret=...&amp;amp;path=/products/123&lt;/code&gt; after content updates.
&lt;/li&gt;
&lt;li&gt;Only the changed page refreshes—no redeploy required.&lt;/li&gt;
&lt;/ul&gt;




&lt;h2&gt;
  
  
  5) Code: App Router (Next.js 13/14+)
&lt;/h2&gt;

&lt;p&gt;With the App Router, you can control revalidation per route or per fetch, and use &lt;strong&gt;tag‑based&lt;/strong&gt; invalidation for powerful CMS workflows.&lt;/p&gt;

&lt;h3&gt;
  
  
  a) Time-based revalidation per route
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight tsx"&gt;&lt;code&gt;&lt;span class="c1"&gt;// app/blog/[slug]/page.tsx&lt;/span&gt;
&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;revalidate&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;120&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="c1"&gt;// seconds&lt;/span&gt;

&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;getPostBySlug&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;@/lib/posts&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="k"&gt;default&lt;/span&gt; &lt;span class="k"&gt;async&lt;/span&gt; &lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;BlogPost&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt; &lt;span class="nx"&gt;params&lt;/span&gt; &lt;span class="p"&gt;}:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nl"&gt;params&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="na"&gt;slug&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kr"&gt;string&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="p"&gt;})&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;post&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nf"&gt;getPostBySlug&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;params&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;slug&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="k"&gt;if &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;!&lt;/span&gt;&lt;span class="nx"&gt;post&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nf"&gt;notFound&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
  &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;Article&lt;/span&gt; &lt;span class="na"&gt;post&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;post&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt; &lt;span class="p"&gt;/&amp;gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  b) Time-based revalidation per fetch
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="c1"&gt;// app/lib/data.ts&lt;/span&gt;
&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="k"&gt;async&lt;/span&gt; &lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;getProducts&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;res&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nf"&gt;fetch&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;https://api.example.com/products&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="c1"&gt;// Revalidate this fetch every 60s&lt;/span&gt;
    &lt;span class="na"&gt;next&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="na"&gt;revalidate&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;60&lt;/span&gt; &lt;span class="p"&gt;},&lt;/span&gt;
  &lt;span class="p"&gt;});&lt;/span&gt;
  &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nx"&gt;res&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;json&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  c) Tag-based caching &amp;amp; revalidation (recommended for CMS-driven content)
&lt;/h3&gt;

&lt;p&gt;Tag your fetches, then revalidate by tag when content changes:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="c1"&gt;// app/lib/data.ts&lt;/span&gt;
&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="k"&gt;async&lt;/span&gt; &lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;getPost&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;slug&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kr"&gt;string&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;res&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nf"&gt;fetch&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;`https://cms.example.com/posts/&lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;slug&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;`&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="na"&gt;next&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="na"&gt;tags&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;posts&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s2"&gt;`post:&lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;slug&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;`&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="p"&gt;},&lt;/span&gt;
  &lt;span class="p"&gt;});&lt;/span&gt;
  &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nx"&gt;res&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;json&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Trigger revalidation by tag in a Route Handler:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="c1"&gt;// app/api/revalidate/route.ts&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;NextRequest&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;NextResponse&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;next/server&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;revalidatePath&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;revalidateTag&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;next/cache&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="k"&gt;async&lt;/span&gt; &lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;POST&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;req&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;NextRequest&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;secret&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;path&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;tag&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nx"&gt;req&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;json&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
  &lt;span class="k"&gt;if &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;secret&lt;/span&gt; &lt;span class="o"&gt;!==&lt;/span&gt; &lt;span class="nx"&gt;process&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;env&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;REVALIDATE_SECRET&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nx"&gt;NextResponse&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;json&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt; &lt;span class="na"&gt;message&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Invalid token&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt; &lt;span class="p"&gt;},&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="na"&gt;status&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;401&lt;/span&gt; &lt;span class="p"&gt;});&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;

  &lt;span class="k"&gt;if &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;tag&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nf"&gt;revalidateTag&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;tag&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;       &lt;span class="c1"&gt;// e.g., "posts" or `post:my-slug`&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;
  &lt;span class="k"&gt;if &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;path&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nf"&gt;revalidatePath&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;path&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;     &lt;span class="c1"&gt;// e.g., "/blog/my-slug"&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;

  &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nx"&gt;NextResponse&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;json&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt; &lt;span class="na"&gt;revalidated&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;path&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;tag&lt;/span&gt; &lt;span class="p"&gt;});&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Why tags?&lt;/strong&gt;  &lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Many pages share the same data (e.g., a “latest posts” list). Revalidating by &lt;strong&gt;tag&lt;/strong&gt; refreshes every page that used that data—without hunting down each path.&lt;/li&gt;
&lt;/ul&gt;




&lt;h2&gt;
  
  
  6) Updating existing pages in practice
&lt;/h2&gt;

&lt;p&gt;You have three primary strategies:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Time-based&lt;/strong&gt; (hands-off): choose a sensible &lt;code&gt;revalidate&lt;/code&gt; interval per page or per fetch.
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Event-driven&lt;/strong&gt; (precise): call &lt;code&gt;/api/revalidate&lt;/code&gt; (Pages) or &lt;code&gt;/api/revalidate&lt;/code&gt; (App Route) when CMS content changes.
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Hybrid&lt;/strong&gt; (safe default): short time-based windows + event-driven hooks for critical updates.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;&lt;strong&gt;Example: CMS webhook → App Router&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;CMS publishes a post and issues &lt;code&gt;POST /api/revalidate&lt;/code&gt; with &lt;code&gt;{ secret, tag: "posts" }&lt;/code&gt;.
&lt;/li&gt;
&lt;li&gt;All routes fetching with &lt;code&gt;{ next: { tags: ['posts'] } }&lt;/code&gt; refresh automatically on next request.
&lt;/li&gt;
&lt;li&gt;Editors see updates immediately; visitors get static speed.&lt;/li&gt;
&lt;/ul&gt;




&lt;h2&gt;
  
  
  7) Pros of ISR
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Static-speed performance&lt;/strong&gt;: Low TTFB from CDN/caches, great Core Web Vitals.
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Freshness without redeploys&lt;/strong&gt;: Background regeneration and on-demand invalidation keep content up to date.
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Build-time wins&lt;/strong&gt;: No need to pre-render every page; generate on first request and refresh incrementally.
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Cost &amp;amp; scale&lt;/strong&gt;: Less server work than full SSR on every request; avoids monolithic rebuilds.
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Resilience&lt;/strong&gt;: If regeneration fails, the last good page continues to serve.
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;SEO-friendly&lt;/strong&gt;: Crawlable, stable HTML with timely updates.
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Great with CMS&lt;/strong&gt;: Tag-based revalidation maps cleanly to content models and editorial workflows.&lt;/li&gt;
&lt;/ul&gt;




&lt;h2&gt;
  
  
  8) Caveats &amp;amp; good practices
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Highly personalized pages&lt;/strong&gt; still need SSR or client-side rendering.
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Very volatile data&lt;/strong&gt; (e.g., live prices) may require shorter revalidate windows or SSR.
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Atomic multi-page updates&lt;/strong&gt;: prefer &lt;strong&gt;tag-based&lt;/strong&gt; revalidation so related pages refresh together.
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Fallback UX&lt;/strong&gt;: if you use &lt;code&gt;fallback: true&lt;/code&gt;, ensure a good loading skeleton for first render.
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Error handling&lt;/strong&gt;: log regeneration failures; consider alerting for critical pages.
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Cache-awareness&lt;/strong&gt;: understand your platform’s CDN and region behavior to avoid surprise staleness.&lt;/li&gt;
&lt;/ul&gt;




&lt;h2&gt;
  
  
  9) Conclusion
&lt;/h2&gt;

&lt;p&gt;ISR gives you the &lt;strong&gt;best of both worlds&lt;/strong&gt;: the &lt;em&gt;speed and stability&lt;/em&gt; of static sites with the &lt;em&gt;freshness&lt;/em&gt; of dynamic systems. Adopt a &lt;strong&gt;cache-first&lt;/strong&gt; mindset: render statically, &lt;strong&gt;revalidate by time&lt;/strong&gt;, and &lt;strong&gt;revalidate by event/tag&lt;/strong&gt; when content changes. Start with conservative intervals (e.g., 60–120s), wire up CMS webhooks, and reach for SSR only when personalization or ultra-fresh data truly demands it.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;TL;DR&lt;/strong&gt;: Ship fast static pages. Keep them fresh—incrementally.&lt;/p&gt;
&lt;/blockquote&gt;




&lt;h3&gt;
  
  
  Quick Reference
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;Pages Router: &lt;code&gt;getStaticProps&lt;/code&gt; + &lt;code&gt;revalidate&lt;/code&gt;, &lt;code&gt;res.revalidate(path)&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;App Router: &lt;code&gt;export const revalidate&lt;/code&gt;, &lt;code&gt;fetch(..., { next: { revalidate, tags } })&lt;/code&gt;, &lt;code&gt;revalidatePath&lt;/code&gt;, &lt;code&gt;revalidateTag&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;Good defaults: &lt;code&gt;revalidate: 60–300&lt;/code&gt; for listings; on-demand for critical content&lt;/li&gt;
&lt;/ul&gt;

</description>
    </item>
    <item>
      <title>Static Rendering (SSG) in React: From Classic Builds to Data‑Driven Pages</title>
      <dc:creator>Md Enayetur Rahman</dc:creator>
      <pubDate>Sat, 13 Dec 2025 09:24:10 +0000</pubDate>
      <link>https://dev.to/md_enayeturrahman_2560e3/static-rendering-ssg-in-react-from-classic-builds-to-data-driven-pages-knm</link>
      <guid>https://dev.to/md_enayeturrahman_2560e3/static-rendering-ssg-in-react-from-classic-builds-to-data-driven-pages-knm</guid>
      <description>&lt;p&gt;Static rendering—also called &lt;strong&gt;Static‑Site Generation (SSG)&lt;/strong&gt;—pre‑generates HTML during your build step, so visitors receive &lt;strong&gt;ready‑to‑serve pages&lt;/strong&gt; without invoking a JavaScript runtime on each request. The pattern marries the &lt;strong&gt;speed of a CDN&lt;/strong&gt; with the &lt;strong&gt;developer experience of React&lt;/strong&gt;. Below we’ll unpack how it works, then walk through three escalating examples:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;&lt;strong&gt;Classic SSG (purely static)&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;SSG with build‑time data&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;SSG with individual detail pages&lt;/strong&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Finally, we’ll cover key considerations and wrap up with a quick checklist.&lt;/p&gt;




&lt;h2&gt;
  
  
  1. How Static Rendering Works
&lt;/h2&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Build step&lt;/strong&gt; – Your React components are rendered to HTML strings.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Asset emission&lt;/strong&gt; – The build outputs plain &lt;code&gt;.html&lt;/code&gt;, &lt;code&gt;.css&lt;/code&gt;, and &lt;code&gt;.js&lt;/code&gt; files.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;CDN deployment&lt;/strong&gt; – The files are uploaded to edge nodes worldwide.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Request/response cycle&lt;/strong&gt; – A user’s browser receives an already rendered page, massively reducing Time to First Byte (TTFB) and Largest Contentful Paint (LCP).&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Because there’s &lt;strong&gt;no server‑side computation per request&lt;/strong&gt;, SSG excels at:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Performance&lt;/strong&gt; (edge‑cached, no cold starts)
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Reliability&lt;/strong&gt; (few moving parts)
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Cost efficiency&lt;/strong&gt; (mostly bandwidth)
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;SEO&lt;/strong&gt; (search crawlers get full HTML)
&lt;/li&gt;
&lt;/ul&gt;




&lt;h2&gt;
  
  
  2. Classic SSG Implementation
&lt;/h2&gt;

&lt;p&gt;Below is a minimal one‑page build using Node + &lt;code&gt;react-dom/server&lt;/code&gt;. At build time we render &lt;code&gt;&amp;lt;App /&amp;gt;&lt;/code&gt; to HTML and write it to &lt;code&gt;/dist/index.html&lt;/code&gt;.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="c1"&gt;// build.js&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="nx"&gt;fs&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;node:fs/promises&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="nx"&gt;React&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;react&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;renderToStaticMarkup&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;react-dom/server&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="nx"&gt;App&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;./App.js&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;async &lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;html&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;renderToStaticMarkup&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;App&lt;/span&gt; &lt;span class="o"&gt;/&amp;gt;&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;doc&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;`&amp;lt;!DOCTYPE html&amp;gt;&amp;lt;html&amp;gt;&amp;lt;head&amp;gt;&amp;lt;title&amp;gt;Static App&amp;lt;/title&amp;gt;&amp;lt;/head&amp;gt;&amp;lt;body&amp;gt;&lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;html&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;&amp;lt;/body&amp;gt;&amp;lt;/html&amp;gt;`&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nx"&gt;fs&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;mkdir&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;dist&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="na"&gt;recursive&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;true&lt;/span&gt; &lt;span class="p"&gt;});&lt;/span&gt;
  &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nx"&gt;fs&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;writeFile&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;dist/index.html&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;doc&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;✅  Built static page ➜  dist/index.html&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="p"&gt;})();&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Run:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;node build.js   &lt;span class="c"&gt;# generates /dist/index.html&lt;/span&gt;
npx serve dist  &lt;span class="c"&gt;# serves the folder locally&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  What we achieved
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Zero runtime JavaScript&lt;/strong&gt; (unless you hydrate later)
&lt;/li&gt;
&lt;li&gt;Blazing‑fast first paint
&lt;/li&gt;
&lt;li&gt;Works great for &lt;em&gt;truly unchanging&lt;/em&gt; pages—docs, marketing landing pages, etc.&lt;/li&gt;
&lt;/ul&gt;




&lt;h2&gt;
  
  
  3. SSG with Build‑Time Data (Next.js)
&lt;/h2&gt;

&lt;p&gt;When your page depends on HEADLINE data that changes only daily/weekly, you can &lt;strong&gt;fetch during the build&lt;/strong&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight tsx"&gt;&lt;code&gt;&lt;span class="c1"&gt;// pages/index.tsx&lt;/span&gt;
&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="k"&gt;default&lt;/span&gt; &lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;Home&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt; &lt;span class="nx"&gt;posts&lt;/span&gt; &lt;span class="p"&gt;})&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="k"&gt;return &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nt"&gt;main&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
      &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nt"&gt;h1&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;Blog&lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nt"&gt;h1&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
      &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nt"&gt;ul&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
        &lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;posts&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;map&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;p&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nt"&gt;li&lt;/span&gt; &lt;span class="na"&gt;key&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;p&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;id&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;p&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;title&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nt"&gt;li&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;)&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;
      &lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nt"&gt;ul&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
    &lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nt"&gt;main&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
  &lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="k"&gt;async&lt;/span&gt; &lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;getStaticProps&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;res&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nf"&gt;fetch&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;https://jsonplaceholder.typicode.com/posts?_limit=10&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;posts&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nx"&gt;res&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;json&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
  &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="na"&gt;props&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;posts&lt;/span&gt; &lt;span class="p"&gt;},&lt;/span&gt;
    &lt;span class="na"&gt;revalidate&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;false&lt;/span&gt;   &lt;span class="c1"&gt;// no ISR in this example&lt;/span&gt;
  &lt;span class="p"&gt;};&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;During &lt;code&gt;next build&lt;/code&gt;, the API is hit &lt;strong&gt;once&lt;/strong&gt;, and the resulting HTML carries the fetched data. Early visitors get pre‑filled content — no spinners, no blocking XHR.&lt;/p&gt;




&lt;h2&gt;
  
  
  4. SSG with Individual Detail Pages
&lt;/h2&gt;

&lt;p&gt;For &lt;strong&gt;dynamic routes&lt;/strong&gt; like &lt;code&gt;/posts/[id]&lt;/code&gt;, pair &lt;code&gt;getStaticPaths&lt;/code&gt; with &lt;code&gt;getStaticProps&lt;/code&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight tsx"&gt;&lt;code&gt;&lt;span class="c1"&gt;// pages/posts/[id].tsx&lt;/span&gt;
&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="k"&gt;default&lt;/span&gt; &lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;Post&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt; &lt;span class="nx"&gt;post&lt;/span&gt; &lt;span class="p"&gt;})&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="k"&gt;return &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nt"&gt;article&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
      &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nt"&gt;h1&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;post&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;title&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nt"&gt;h1&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
      &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nt"&gt;p&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;post&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;body&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nt"&gt;p&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
    &lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nt"&gt;article&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
  &lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="k"&gt;async&lt;/span&gt; &lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;getStaticPaths&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;res&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nf"&gt;fetch&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;https://jsonplaceholder.typicode.com/posts?_limit=10&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;posts&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nx"&gt;res&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;json&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;paths&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;posts&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;map&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;p&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;({&lt;/span&gt; &lt;span class="na"&gt;params&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="na"&gt;id&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;p&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;id&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;toString&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="p"&gt;}));&lt;/span&gt;
  &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;paths&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="na"&gt;fallback&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;false&lt;/span&gt; &lt;span class="p"&gt;};&lt;/span&gt; &lt;span class="c1"&gt;// pre‑generate 10 pages&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="k"&gt;async&lt;/span&gt; &lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;getStaticProps&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt; &lt;span class="nx"&gt;params&lt;/span&gt; &lt;span class="p"&gt;})&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;res&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nf"&gt;fetch&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;`https://jsonplaceholder.typicode.com/posts/&lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;params&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;id&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;`&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;post&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nx"&gt;res&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;json&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
  &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="na"&gt;props&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;post&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="p"&gt;};&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;&lt;code&gt;getStaticPaths&lt;/code&gt;&lt;/strong&gt; enumerates which IDs to pre‑render.
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;&lt;code&gt;fallback&lt;/code&gt;&lt;/strong&gt; controls behavior for non‑generated IDs (&lt;code&gt;'blocking' | 'true' | 'false'&lt;/code&gt;).
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;You can scale this by enabling &lt;strong&gt;Incremental Static Regeneration (ISR)&lt;/strong&gt; or on‑demand revalidation so you’re not rebuilding the entire site for every content change.&lt;/p&gt;




&lt;h2&gt;
  
  
  5. Key Considerations
&lt;/h2&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Consideration&lt;/th&gt;
&lt;th&gt;Why It Matters&lt;/th&gt;
&lt;th&gt;Mitigation&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Build Time&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Thousands of pages mean longer builds.&lt;/td&gt;
&lt;td&gt;Split builds, ISR, parallelization.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Data Freshness&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Static pages can become stale.&lt;/td&gt;
&lt;td&gt;Use &lt;code&gt;revalidate&lt;/code&gt; (ISR) or webhooks to trigger rebuilds.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Personalization&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;SSG can’t easily personalize per user.&lt;/td&gt;
&lt;td&gt;Combine with &lt;strong&gt;client‑side rendering&lt;/strong&gt; or &lt;strong&gt;edge middleware&lt;/strong&gt;.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Large Data Sets&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Generating every permutation might be impractical.&lt;/td&gt;
&lt;td&gt;Opt for partial prerender + &lt;code&gt;fallback: "blocking"&lt;/code&gt; for rarer paths.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Secret Data&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Anything included at build is &lt;strong&gt;public&lt;/strong&gt;.&lt;/td&gt;
&lt;td&gt;Keep private data on the server; call via API at runtime.&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;




&lt;h2&gt;
  
  
  6. Conclusion
&lt;/h2&gt;

&lt;p&gt;Static rendering sits at the intersection of &lt;strong&gt;predictability&lt;/strong&gt; and &lt;strong&gt;performance&lt;/strong&gt;. Use it when:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Content changes &lt;strong&gt;infrequently or on a predictable schedule&lt;/strong&gt;
&lt;/li&gt;
&lt;li&gt;SEO and initial‑paint speed are paramount
&lt;/li&gt;
&lt;li&gt;You’re comfortable pushing updates via CI/CD rather than at request time&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;For highly dynamic, user‑specific dashboards you’ll still reach for SSR or CSR. But for landing pages, docs, blogs, e‑commerce product listings, and marketing sites, SSG remains a &lt;strong&gt;battle‑tested pattern&lt;/strong&gt;—and, as &lt;em&gt;Learning Patterns&lt;/em&gt; highlights, one of the simplest ways to deliver a snappy, resilient user experience.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Checklist&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;[ ] Identify pages with stable content
&lt;/li&gt;
&lt;li&gt;[ ] Fetch external data in &lt;code&gt;getStaticProps&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;[ ] Generate dynamic routes with &lt;code&gt;getStaticPaths&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;[ ] Decide if ISR is required for freshness
&lt;/li&gt;
&lt;li&gt;[ ] Automate deployment to a CDN/edge platform
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Happy building! 🏗️🚀&lt;/p&gt;

</description>
    </item>
    <item>
      <title>Mastering Server‑Side Rendering (SSR)</title>
      <dc:creator>Md Enayetur Rahman</dc:creator>
      <pubDate>Sat, 13 Dec 2025 09:21:01 +0000</pubDate>
      <link>https://dev.to/md_enayeturrahman_2560e3/mastering-server-side-rendering-ssr-23l</link>
      <guid>https://dev.to/md_enayeturrahman_2560e3/mastering-server-side-rendering-ssr-23l</guid>
      <description>&lt;blockquote&gt;
&lt;p&gt;&lt;em&gt;“Server‑side rendering is **not&lt;/em&gt;* the goal. Faster time‑to‑interactive, better SEO and predictable data is.”*&lt;br&gt;&lt;br&gt;
— &lt;em&gt;Learning Patterns&lt;/em&gt;, Hallie &amp;amp; Osmani&lt;/p&gt;
&lt;/blockquote&gt;




&lt;h2&gt;
  
  
  1. What &lt;em&gt;is&lt;/em&gt; Server‑Side Rendering?
&lt;/h2&gt;

&lt;p&gt;Server‑Side Rendering (SSR) means generating the HTML for each request &lt;strong&gt;on the server&lt;/strong&gt;, then sending that markup to the browser so the user sees meaningful UI before JavaScript finishes hydrating.&lt;br&gt;&lt;br&gt;
The sequence is:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Request&lt;/strong&gt; → browser asks for a page
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Render&lt;/strong&gt; → server executes component tree to HTML
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Send&lt;/strong&gt; → server returns HTML + critical assets
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Hydrate&lt;/strong&gt; → client JavaScript attaches event listeners&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;SSR differs from Static Site Generation (HTML produced at &lt;em&gt;build&lt;/em&gt; time) and purely Client‑Side Rendering (HTML generated &lt;em&gt;after&lt;/em&gt; JS loads).&lt;/p&gt;


&lt;h2&gt;
  
  
  2. Classic React SSR (before frameworks)
&lt;/h2&gt;


&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;npm i express react react-dom react-dom/server
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="c1"&gt;// server.js – minimal SSR with Express&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="nx"&gt;express&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;express&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;readFileSync&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;fs&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="nx"&gt;React&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;react&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;renderToString&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;react-dom/server&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="nx"&gt;App&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;./App.js&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;htmlTemplate&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;readFileSync&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;./index.html&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;utf8&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;server&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;express&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;

&lt;span class="nx"&gt;server&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;get&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;*&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;req&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;res&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;markup&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;renderToString&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;App&lt;/span&gt; &lt;span class="nx"&gt;url&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;req&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;url&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="sr"&gt;/&amp;gt;&lt;/span&gt;&lt;span class="se"&gt;)&lt;/span&gt;&lt;span class="err"&gt;;
&lt;/span&gt;  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;html&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;htmlTemplate&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;replace&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;&amp;lt;!--app--&amp;gt;&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;markup&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="nx"&gt;res&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;send&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;html&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="p"&gt;});&lt;/span&gt;

&lt;span class="nx"&gt;server&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;listen&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;3000&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;SSR app ↘ http://localhost:3000&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;));&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;This &lt;strong&gt;works&lt;/strong&gt;, but you must hand‑roll routing, code‑splitting, data‑fetch orchestration, streaming, and more.&lt;/p&gt;


&lt;h2&gt;
  
  
  3. Pros &amp;amp; Cons of SSR
&lt;/h2&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;✅ Pros&lt;/th&gt;
&lt;th&gt;🚧 Cons&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;First content paints fast on slow devices&lt;/td&gt;
&lt;td&gt;Server must render on every request — cost &amp;amp; latency&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;SEO‑friendly (HTML visible to crawlers)&lt;/td&gt;
&lt;td&gt;More complicated cache strategy than static generation&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Consistent data (no layout shift from client fetching)&lt;/td&gt;
&lt;td&gt;Adds coupling between server and client environments&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Enables progressive streaming &amp;amp; React Suspense&lt;/td&gt;
&lt;td&gt;Cannot fully leverage CDN edge unless cached&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;


&lt;h2&gt;
  
  
  4. SSR &lt;em&gt;with&lt;/em&gt; Next.js
&lt;/h2&gt;

&lt;p&gt;Next.js automates bundling, routing, code‑splitting and &lt;strong&gt;hot‑reloading&lt;/strong&gt; while exposing two flavours of SSR:&lt;/p&gt;
&lt;h3&gt;
  
  
  4.1 Pages Router – &lt;code&gt;getServerSideProps&lt;/code&gt;
&lt;/h3&gt;


&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight jsx"&gt;&lt;code&gt;&lt;span class="c1"&gt;// pages/index.jsx&lt;/span&gt;
&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="k"&gt;async&lt;/span&gt; &lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;getServerSideProps&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;res&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nf"&gt;fetch&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;https://api.example.com/posts&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;posts&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nx"&gt;res&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;json&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
  &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="na"&gt;props&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;posts&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="p"&gt;};&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="k"&gt;default&lt;/span&gt; &lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;Home&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt; &lt;span class="nx"&gt;posts&lt;/span&gt; &lt;span class="p"&gt;})&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="k"&gt;return &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nt"&gt;main&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
      &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nt"&gt;h1&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;Latest posts&lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nt"&gt;h1&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
      &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nt"&gt;ul&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;posts&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;map&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;p&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nt"&gt;li&lt;/span&gt; &lt;span class="na"&gt;key&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;p&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;id&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;p&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;title&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nt"&gt;li&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;)&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nt"&gt;ul&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
    &lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nt"&gt;main&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
  &lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;&lt;em&gt;Every&lt;/em&gt; request runs &lt;code&gt;getServerSideProps&lt;/code&gt;; HTML streams back to the client.&lt;/p&gt;
&lt;h3&gt;
  
  
  4.2 App Router (Next 14 +) – Server Components &amp;amp; Streaming
&lt;/h3&gt;


&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight tsx"&gt;&lt;code&gt;&lt;span class="c1"&gt;// app/page.tsx (acts like a React Server Component)&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="nx"&gt;PostList&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;./PostList&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;   &lt;span class="c1"&gt;// also a server component&lt;/span&gt;

&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="k"&gt;default&lt;/span&gt; &lt;span class="k"&gt;async&lt;/span&gt; &lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;Home&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;posts&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nf"&gt;fetch&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;https://api.example.com/posts&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nf"&gt;then&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;r&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nx"&gt;r&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;json&lt;/span&gt;&lt;span class="p"&gt;());&lt;/span&gt;

  &lt;span class="k"&gt;return &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="p"&gt;&amp;lt;&amp;gt;&lt;/span&gt;
      &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nt"&gt;h1&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;Latest posts&lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nt"&gt;h1&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
      &lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="cm"&gt;/* PostList can stream in parallel */&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;
      &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;PostList&lt;/span&gt; &lt;span class="na"&gt;initialPosts&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;posts&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt; &lt;span class="p"&gt;/&amp;gt;&lt;/span&gt;
    &lt;span class="p"&gt;&amp;lt;/&amp;gt;&lt;/span&gt;
  &lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;The App Router uses &lt;strong&gt;React Server Components (RSC)&lt;/strong&gt; and &lt;code&gt;Suspense&lt;/code&gt;‐based &lt;strong&gt;streaming&lt;/strong&gt; so HTML chunks arrive progressively. &lt;/p&gt;


&lt;h2&gt;
  
  
  5. React &lt;em&gt;for the Server&lt;/em&gt; (RSC vs SSR)
&lt;/h2&gt;

&lt;p&gt;&lt;em&gt;React 19&lt;/em&gt; stabilised &lt;strong&gt;Server Components&lt;/strong&gt;, letting parts of the tree run &lt;strong&gt;only on the server&lt;/strong&gt; — no JS shipped to the client.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight jsx"&gt;&lt;code&gt;&lt;span class="c1"&gt;// components/ServerChart.server.jsx&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="nx"&gt;db&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;@/lib/db&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="nx"&gt;Chart&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;@/components/Chart&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;   &lt;span class="c1"&gt;// client component&lt;/span&gt;

&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="k"&gt;default&lt;/span&gt; &lt;span class="k"&gt;async&lt;/span&gt; &lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;ServerChart&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;data&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nx"&gt;db&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;sales&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;findMany&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
  &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;Chart&lt;/span&gt; &lt;span class="na"&gt;data&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;data&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt; &lt;span class="p"&gt;/&amp;gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;.server.jsx&lt;/code&gt; executes on the server, can access secrets, returns serialized props.&lt;/li&gt;
&lt;li&gt;Client receives just the final HTML for that chunk plus minimal hydration JS for purely interactive children.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;This &lt;em&gt;complements&lt;/em&gt; SSR: pages can statically stream &lt;em&gt;and&lt;/em&gt; embed dynamic server logic. &lt;/p&gt;




&lt;h2&gt;
  
  
  6. Putting It All Together
&lt;/h2&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Small sites&lt;/strong&gt; → prefer &lt;em&gt;Static&lt;/em&gt; generation; sprinkle RSC for secure data.
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Content‑heavy, SEO‑critical apps&lt;/strong&gt; → SSR via Pages or App router.
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Data‑intensive dashboards&lt;/strong&gt; → mix SSR + RSC + streaming for best TTFB and interactivity.&lt;/li&gt;
&lt;/ol&gt;




&lt;h2&gt;
  
  
  7. Conclusion
&lt;/h2&gt;

&lt;p&gt;Server‑Side Rendering has matured from hand‑rolled &lt;code&gt;renderToString()&lt;/code&gt; scripts to &lt;strong&gt;first‑class primitives&lt;/strong&gt; in Next.js 14 and React 19.&lt;br&gt;&lt;br&gt;
By combining SSR, React Server Components and streaming, you can deliver fast‑painting, SEO‑friendly, &lt;strong&gt;user‑centric&lt;/strong&gt; experiences without drowning in complexity.&lt;/p&gt;




&lt;p&gt;&lt;em&gt;Inspired by principles in “Learning Patterns” — Hallie &amp;amp; Osmani, ch. 5 (Rendering Strategies).&lt;/em&gt;  &lt;/p&gt;

</description>
    </item>
    <item>
      <title>Next.js Client‑Side Rendering: Bundles, Performance &amp; Practical Optimisations</title>
      <dc:creator>Md Enayetur Rahman</dc:creator>
      <pubDate>Sat, 13 Dec 2025 09:19:06 +0000</pubDate>
      <link>https://dev.to/md_enayeturrahman_2560e3/nextjs-client-side-rendering-bundles-performance-practical-optimisations-4l0j</link>
      <guid>https://dev.to/md_enayeturrahman_2560e3/nextjs-client-side-rendering-bundles-performance-practical-optimisations-4l0j</guid>
      <description>&lt;blockquote&gt;
&lt;p&gt;&lt;em&gt;This article is part of my Learning Patterns series, where I distill insights from Lydia Hallie &amp;amp; Addy Osmani’s book into real‑world React/Next.js workflows.&lt;/em&gt;  &lt;/p&gt;
&lt;/blockquote&gt;




&lt;h2&gt;
  
  
  1  |  What is Client‑Side Rendering (CSR)?
&lt;/h2&gt;

&lt;p&gt;In CSR, the server ships &lt;strong&gt;only a bare‑bones HTML container&lt;/strong&gt;; React and its JavaScript take over in the browser—handling routing, data fetching and templating.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Server ⟶ &amp;lt;div id="root"&amp;gt;&amp;lt;/div&amp;gt;  
Browser ⟶ downloads `/static/js/bundle.js` ⟶ runs React ⟶ paints UI
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Quick demo in a Next.js 14 app
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight jsx"&gt;&lt;code&gt;&lt;span class="c1"&gt;// app/csr-clock/page.js&lt;/span&gt;
&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;use client&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;useEffect&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;useState&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;react&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="k"&gt;default&lt;/span&gt; &lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;Clock&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;now&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;setNow&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;useState&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nb"&gt;Date&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;now&lt;/span&gt;&lt;span class="p"&gt;());&lt;/span&gt;
  &lt;span class="nf"&gt;useEffect&lt;/span&gt;&lt;span class="p"&gt;(()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;id&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;setInterval&lt;/span&gt;&lt;span class="p"&gt;(()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nf"&gt;setNow&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nb"&gt;Date&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;now&lt;/span&gt;&lt;span class="p"&gt;()),&lt;/span&gt; &lt;span class="mi"&gt;1000&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="k"&gt;return &lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nf"&gt;clearInterval&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;id&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="p"&gt;},&lt;/span&gt; &lt;span class="p"&gt;[]);&lt;/span&gt;
  &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nt"&gt;p&lt;/span&gt; &lt;span class="na"&gt;className&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;"text-center text-2xl"&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;Date&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;now&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nf"&gt;toLocaleTimeString&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nt"&gt;p&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;em&gt;Everything&lt;/em&gt; (including the interval) runs on the client, so no extra round‑trips are needed.&lt;/p&gt;




&lt;h2&gt;
  
  
  2  |  Understanding the JavaScript Bundle
&lt;/h2&gt;

&lt;h3&gt;
  
  
  What lands in the bundle?
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;Static imports in every route.&lt;/li&gt;
&lt;li&gt;Third‑party dependencies.&lt;/li&gt;
&lt;li&gt;Your own components and utilities.&lt;/li&gt;
&lt;/ul&gt;

&lt;blockquote&gt;
&lt;p&gt;The book reminds us that &lt;strong&gt;“the bigger the bundle, the longer users stare at a blank screen”&lt;/strong&gt; before FCP and TTI kick in.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h3&gt;
  
  
  Peeking inside
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;# Install once&lt;/span&gt;
npm i &lt;span class="nt"&gt;-D&lt;/span&gt; @next/bundle-analyzer
&lt;span class="c"&gt;# Build with analysis&lt;/span&gt;
&lt;span class="nv"&gt;ANALYZE&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="nb"&gt;true &lt;/span&gt;npm run build
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This opens an interactive treemap showing which packages bloat the bundle.&lt;/p&gt;

&lt;h3&gt;
  
  
  Measuring real performance
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;# Local Lighthouse&lt;/span&gt;
npx lighthouse http://localhost:3000 &lt;span class="nt"&gt;--view&lt;/span&gt;

&lt;span class="c"&gt;# Web‑Vitals snippet (in _app.tsx)&lt;/span&gt;
import &lt;span class="o"&gt;{&lt;/span&gt; reportWebVitals &lt;span class="o"&gt;}&lt;/span&gt; from &lt;span class="s1"&gt;'next/web-vitals'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="nb"&gt;export &lt;/span&gt;&lt;span class="k"&gt;function &lt;/span&gt;reportWebVitals&lt;span class="o"&gt;(&lt;/span&gt;metric&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
  console.log&lt;span class="o"&gt;(&lt;/span&gt;metric&lt;span class="o"&gt;)&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="o"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h2&gt;
  
  
  3  |  Pros &amp;amp; Cons of CSR
&lt;/h2&gt;

&lt;p&gt;| 💚 &lt;em&gt;Strengths&lt;/em&gt;                                               | 😬 &lt;em&gt;Trade‑offs&lt;/em&gt;                                                  |&lt;br&gt;
| --------------------------------------------------------------| --------------- -------------------------------------------------|&lt;br&gt;
| SPA‑like fluid navigation—no full page reloads                | Initial blank screen until JS downloads &amp;amp; executes               |&lt;br&gt;
| Clear separation between API &amp;amp; UI layers                      | SEO is tougher: crawlers may time‑out before content appears     |&lt;br&gt;
| Powerful client‑only interactions (e.g. real‑time dashboards) | Large bundles hit FCP/LCP/TTI, especially on low‑end devices     |&lt;br&gt;
| Works offline/with service‑workers                            | Potential duplication of validation logic across client &amp;amp; server |&lt;/p&gt;




&lt;h2&gt;
  
  
  4  |  Five Ways to Speed‑Up CSR in Next.js
&lt;/h2&gt;

&lt;blockquote&gt;
&lt;p&gt;Performance is &lt;strong&gt;inversely proportional&lt;/strong&gt; to bundle size—so shrink, split and delay JS!&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h3&gt;
  
  
  4.1 Route‑based code splitting (automatic)
&lt;/h3&gt;

&lt;p&gt;Next.js ships each page as its own chunk. Avoid giant &lt;em&gt;layouts&lt;/em&gt; that re‑import heavy libs everywhere.&lt;/p&gt;

&lt;h3&gt;
  
  
  4.2 Component‑level code splitting
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight jsx"&gt;&lt;code&gt;&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="nx"&gt;dynamic&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;next/dynamic&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;EmojiPicker&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;dynamic&lt;/span&gt;&lt;span class="p"&gt;(()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="k"&gt;import&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;./EmojiPicker&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="na"&gt;ssr&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;false&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="na"&gt;loading&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nt"&gt;p&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;Loading…&lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nt"&gt;p&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;,&lt;/span&gt;
&lt;span class="p"&gt;});&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;code&gt;EmojiPicker&lt;/code&gt; drops out of the initial bundle and loads on demand.&lt;/p&gt;

&lt;h3&gt;
  
  
  4.3 Tree‑shaking &amp;amp; dead‑code elimination
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;Use ES modules (&lt;code&gt;import { X } from "y"&lt;/code&gt;)
&lt;/li&gt;
&lt;li&gt;Prefer lightweight icon/lib alternatives (e.g. &lt;code&gt;@svgr/webpack&lt;/code&gt; over Font‑Awesome).&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  4.4 Inline critical CSS, defer the rest
&lt;/h3&gt;

&lt;p&gt;Inline the &lt;em&gt;bare minimum&lt;/em&gt; styles needed for first paint—defer bulky component CSS with &lt;code&gt;@import()&lt;/code&gt; inside the component file.&lt;/p&gt;

&lt;h3&gt;
  
  
  4.5 Audit third‑party packages
&lt;/h3&gt;

&lt;p&gt;Regularly compare alternatives (&lt;code&gt;react-select&lt;/code&gt; → &lt;code&gt;react-select-search&lt;/code&gt;, etc.) and watch Lighthouse/TBT drop.&lt;/p&gt;

&lt;h4&gt;
  
  
  Real‑world win (Next.js Movies App)
&lt;/h4&gt;

&lt;ul&gt;
&lt;li&gt;Lazy‑loading a sidebar reduced &lt;strong&gt;Total Blocking Time by 71%&lt;/strong&gt;.
&lt;/li&gt;
&lt;li&gt;Swapping Font‑Awesome for inline SVG slashed LCP by 23%.&lt;/li&gt;
&lt;/ul&gt;




&lt;h2&gt;
  
  
  5  |  Putting It All Together – A Checklist
&lt;/h2&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Analyze&lt;/strong&gt; your bundles after &lt;em&gt;every&lt;/em&gt; dependency addition.
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Split&lt;/strong&gt; routes &amp;amp; heavy components with &lt;code&gt;next/dynamic&lt;/code&gt;.
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Inline&lt;/strong&gt; only the CSS needed for FCP.
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Ship&lt;/strong&gt; SVGs/icons smartly—avoid icon fonts.
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Monitor&lt;/strong&gt; Web‑Vitals in production and iterate.&lt;/li&gt;
&lt;/ol&gt;




&lt;h2&gt;
  
  
  6  |  Conclusion
&lt;/h2&gt;

&lt;p&gt;Client‑Side Rendering isn’t dead—&lt;strong&gt;it just demands discipline&lt;/strong&gt;. By treating every kilobyte of JavaScript as a cost and applying the patterns above, you keep CSR fast, SEO‑friendly &lt;em&gt;enough&lt;/em&gt;, and enjoyable to build.&lt;/p&gt;




&lt;p&gt;&lt;em&gt;Inspired by pages on CSR, bundle‑splitting and performance tuning in **Learning Patterns&lt;/em&gt;* (Hallie &amp;amp; Osmani, 2021).*  &lt;/p&gt;

</description>
    </item>
  </channel>
</rss>
