<?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: Sachin Maurya</title>
    <description>The latest articles on DEV Community by Sachin Maurya (@maurya-sachin).</description>
    <link>https://dev.to/maurya-sachin</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.us-east-2.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F1046037%2F27ffba04-9465-46ab-84bb-50236e7e309e.png</url>
      <title>DEV Community: Sachin Maurya</title>
      <link>https://dev.to/maurya-sachin</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/maurya-sachin"/>
    <language>en</language>
    <item>
      <title>How I Got My Portfolio to 100 PageSpeed on Mobile and Desktop</title>
      <dc:creator>Sachin Maurya</dc:creator>
      <pubDate>Sun, 28 Jun 2026 07:36:53 +0000</pubDate>
      <link>https://dev.to/maurya-sachin/how-i-got-my-portfolio-to-100-pagespeed-on-mobile-and-desktop-4c9l</link>
      <guid>https://dev.to/maurya-sachin/how-i-got-my-portfolio-to-100-pagespeed-on-mobile-and-desktop-4c9l</guid>
      <description>&lt;p&gt;I recently cleaned up my portfolio and got it to 100 in PageSpeed Insights on both mobile and desktop for:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Performance&lt;/li&gt;
&lt;li&gt;Accessibility&lt;/li&gt;
&lt;li&gt;Best Practices&lt;/li&gt;
&lt;li&gt;SEO&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;It also got an A on GTmetrix.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fubyvb8h0n36te09sv5s0.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fubyvb8h0n36te09sv5s0.png" alt="PageSpeed Insights result showing 100 scores" width="800" height="433"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;This was not because of one magic trick.&lt;/p&gt;

&lt;p&gt;It was mostly a lot of small cleanup decisions.&lt;/p&gt;

&lt;h2&gt;
  
  
  1. I reduced unnecessary client-side work
&lt;/h2&gt;

&lt;p&gt;One thing I focused on was keeping the public page as light as possible.&lt;/p&gt;

&lt;p&gt;If something does not need to run in the browser, it should not run in the browser.&lt;/p&gt;

&lt;p&gt;That means:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;fewer client-side features&lt;/li&gt;
&lt;li&gt;less JavaScript shipped to the user&lt;/li&gt;
&lt;li&gt;simple rendering flow&lt;/li&gt;
&lt;li&gt;no extra state where it is not needed&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;This helped keep the page fast.&lt;/p&gt;

&lt;h2&gt;
  
  
  2. I kept the UI simple
&lt;/h2&gt;

&lt;p&gt;I did not want to add effects just for the sake of it.&lt;/p&gt;

&lt;p&gt;A portfolio should load fast and communicate clearly.&lt;/p&gt;

&lt;p&gt;So I kept the layout simple:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;clear sections&lt;/li&gt;
&lt;li&gt;readable text&lt;/li&gt;
&lt;li&gt;simple buttons&lt;/li&gt;
&lt;li&gt;no heavy animations&lt;/li&gt;
&lt;li&gt;no unnecessary libraries&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;This made the site easier to maintain and also helped performance.&lt;/p&gt;

&lt;h2&gt;
  
  
  3. I cleaned up SEO metadata
&lt;/h2&gt;

&lt;p&gt;SEO was another area I improved.&lt;/p&gt;

&lt;p&gt;I checked that the site had:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;proper title and description&lt;/li&gt;
&lt;li&gt;correct canonical URL&lt;/li&gt;
&lt;li&gt;Open Graph metadata&lt;/li&gt;
&lt;li&gt;robots and sitemap behavior&lt;/li&gt;
&lt;li&gt;different handling for production and staging&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;One important thing was making sure the staging/dev version does not get indexed.&lt;/p&gt;

&lt;p&gt;Production should be visible. Staging should stay hidden.&lt;/p&gt;

&lt;h2&gt;
  
  
  4. I improved accessibility
&lt;/h2&gt;

&lt;p&gt;Accessibility improvements were mostly basic but important.&lt;/p&gt;

&lt;p&gt;I checked things like:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;color contrast&lt;/li&gt;
&lt;li&gt;button and link behavior&lt;/li&gt;
&lt;li&gt;readable text sizes&lt;/li&gt;
&lt;li&gt;semantic HTML&lt;/li&gt;
&lt;li&gt;useful fallback screens&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Sometimes accessibility is not about adding more code. It is about making the existing UI clearer.&lt;/p&gt;

&lt;h2&gt;
  
  
  5. I added better error and offline states
&lt;/h2&gt;

&lt;p&gt;I added cleaner fallback screens for error and not-found cases.&lt;/p&gt;

&lt;p&gt;I also added a very small offline fallback.&lt;/p&gt;

&lt;p&gt;The idea was simple:&lt;/p&gt;

&lt;p&gt;If the portfolio is not available offline, show a basic message and still allow the visitor to download the resume.&lt;/p&gt;

&lt;p&gt;I did not want to build a full PWA or add unnecessary complexity.&lt;/p&gt;

&lt;p&gt;Just enough offline support to be useful.&lt;/p&gt;

&lt;h2&gt;
  
  
  6. I checked with GTmetrix too
&lt;/h2&gt;

&lt;p&gt;After PageSpeed, I also checked the site with GTmetrix.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Frfuyw46suxxzbmq55zj8.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Frfuyw46suxxzbmq55zj8.png" alt="GTmetrix report showing A grade and strong web vitals" width="800" height="433"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The result was:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;GTmetrix Grade: A&lt;/li&gt;
&lt;li&gt;Performance: 99%&lt;/li&gt;
&lt;li&gt;Structure: 99%&lt;/li&gt;
&lt;li&gt;LCP: 781ms&lt;/li&gt;
&lt;li&gt;TBT: 0ms&lt;/li&gt;
&lt;li&gt;CLS: 0&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;This helped confirm that the site was not only passing one tool, but performing well in another check too.&lt;/p&gt;

&lt;h2&gt;
  
  
  7. I kept performance features minimal
&lt;/h2&gt;

&lt;p&gt;It is easy to over-engineer performance.&lt;/p&gt;

&lt;p&gt;But for this site, the best approach was to keep things boring:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;no heavy runtime logic&lt;/li&gt;
&lt;li&gt;no unnecessary fallbacks&lt;/li&gt;
&lt;li&gt;no large client-side packages&lt;/li&gt;
&lt;li&gt;no complex caching strategy&lt;/li&gt;
&lt;li&gt;no feature that hurts the main page load&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The goal was not to add more. The goal was to remove what was not needed.&lt;/p&gt;

&lt;h2&gt;
  
  
  8. I verified everything before shipping
&lt;/h2&gt;

&lt;p&gt;Before calling it done, I ran checks for:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;lint&lt;/li&gt;
&lt;li&gt;TypeScript&lt;/li&gt;
&lt;li&gt;formatting&lt;/li&gt;
&lt;li&gt;production build&lt;/li&gt;
&lt;li&gt;PageSpeed Insights&lt;/li&gt;
&lt;li&gt;GTmetrix&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;This helped catch small issues before deployment.&lt;/p&gt;

&lt;h2&gt;
  
  
  What I learned
&lt;/h2&gt;

&lt;p&gt;Getting a 100 score is not about chasing Lighthouse blindly.&lt;/p&gt;

&lt;p&gt;It is about building with discipline.&lt;/p&gt;

&lt;p&gt;For me, the main lessons were:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;keep the fast path simple&lt;/li&gt;
&lt;li&gt;avoid unnecessary JavaScript&lt;/li&gt;
&lt;li&gt;care about accessibility from the start&lt;/li&gt;
&lt;li&gt;make SEO explicit&lt;/li&gt;
&lt;li&gt;don’t add features without a reason&lt;/li&gt;
&lt;li&gt;verify before shipping&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Small cleanup decisions add up.&lt;/p&gt;

&lt;p&gt;That was the biggest learning from this work.&lt;/p&gt;

</description>
      <category>webdev</category>
      <category>webperf</category>
      <category>a11y</category>
      <category>seo</category>
    </item>
    <item>
      <title>Building a Multi-Layer Caching Strategy in Next.js App Router: From Static to Real-Time</title>
      <dc:creator>Sachin Maurya</dc:creator>
      <pubDate>Thu, 01 Jan 2026 05:29:06 +0000</pubDate>
      <link>https://dev.to/maurya-sachin/building-a-multi-layer-caching-strategy-in-nextjs-app-router-from-static-to-real-time-4che</link>
      <guid>https://dev.to/maurya-sachin/building-a-multi-layer-caching-strategy-in-nextjs-app-router-from-static-to-real-time-4che</guid>
      <description>&lt;p&gt;Caching is one of those make-or-break aspects of modern web development. Get it right, and your app is fast, resilient, and scalable. Get it wrong, and you’re left with stale data, poor performance, or worse — broken user experiences.&lt;/p&gt;

&lt;p&gt;At my previous role, I led the migration of our corporate platform to the Next.js App Router. One of our core challenges was designing a caching strategy that could handle:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Fully static marketing pages
&lt;/li&gt;
&lt;li&gt;Occasionally updated blog content
&lt;/li&gt;
&lt;li&gt;Personalized user dashboards
&lt;/li&gt;
&lt;li&gt;Real-time activity feeds
&lt;/li&gt;
&lt;li&gt;Mixed-content pages (static + dynamic)&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;In this post, I’ll walk through how we built a &lt;strong&gt;multi-layer caching architecture&lt;/strong&gt; that kept our Lighthouse scores consistently above 95 while ensuring data freshness where it mattered most.&lt;/p&gt;




&lt;h2&gt;
  
  
  Understanding Next.js Caching Layers
&lt;/h2&gt;

&lt;p&gt;Before jumping into implementation, it’s important to understand the caching layers available in the App Router:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Full Route Cache&lt;/strong&gt; – Entire route responses (HTML) cached at build or request time
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Data Cache&lt;/strong&gt; – Results of &lt;code&gt;fetch&lt;/code&gt; requests persisted across requests
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Client Cache&lt;/strong&gt; – Caching done in the browser (via React Query, Zustand, etc.)
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;CDN/Edge Cache&lt;/strong&gt; – Caching at the network edge (Vercel, Cloudflare, etc.)&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Each layer serves a different purpose, and using them together is key.&lt;/p&gt;




&lt;h2&gt;
  
  
  Layer 1: Fully Static Pages with &lt;code&gt;force-static&lt;/code&gt;
&lt;/h2&gt;

&lt;p&gt;We had several pages that never changed: &lt;code&gt;/about&lt;/code&gt;, &lt;code&gt;/contact&lt;/code&gt;, &lt;code&gt;/legal&lt;/code&gt;. For these, we used:&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;// app/about/page.js&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;dynamic&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;force-static&lt;/span&gt;&lt;span class="dl"&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;AboutPage&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="c1"&gt;// This page is cached at build time&lt;/span&gt;
  &lt;span class="c1"&gt;// and served from CDN indefinitely&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 &lt;code&gt;force-static&lt;/code&gt;?&lt;/strong&gt;&lt;br&gt;&lt;br&gt;
It tells Next.js to skip all dynamic logic, treat the page as completely static, and cache it at the edge. This is ideal for true static content.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Impact:&lt;/strong&gt;&lt;br&gt;&lt;br&gt;
These pages loaded instantly on repeat visits and required zero backend computation.&lt;/p&gt;


&lt;h2&gt;
  
  
  Layer 2: Incrementally Static Pages with ISR
&lt;/h2&gt;

&lt;p&gt;Our blog and documentation pages were mostly static but could be updated via CMS. We used &lt;strong&gt;Incremental Static Regeneration (ISR)&lt;/strong&gt; with on-demand revalidation.&lt;/p&gt;
&lt;h3&gt;
  
  
  Step 1 – Basic ISR
&lt;/h3&gt;


&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="c1"&gt;// app/blog/[slug]/page.js&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;3600&lt;/span&gt; &lt;span class="c1"&gt;// Revalidate every hour&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="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://api.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="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;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="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;getPost&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;return&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;PostLayout&lt;/span&gt; &lt;span class="nx"&gt;post&lt;/span&gt;&lt;span class="o"&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="sr"&gt;/&lt;/span&gt;&lt;span class="err"&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;
  
  
  Step 2 – On-Demand Revalidation
&lt;/h3&gt;

&lt;p&gt;When a post was updated in the CMS, we triggered:&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;// app/api/revalidate/route.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;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="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;request&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;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;request&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="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'&lt;/span&gt;
  &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nx"&gt;Response&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="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This meant:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Blog posts were cached for performance&lt;/li&gt;
&lt;li&gt;But could be updated in seconds when needed&lt;/li&gt;
&lt;li&gt;No full rebuilds required&lt;/li&gt;
&lt;/ul&gt;




&lt;h2&gt;
  
  
  Layer 3: Personalized Dashboards – No Server Cache
&lt;/h2&gt;

&lt;p&gt;For authenticated user dashboards (&lt;code&gt;/dashboard&lt;/code&gt;, &lt;code&gt;/settings&lt;/code&gt;), we disabled server caching entirely.&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;// app/dashboard/page.js&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;dynamic&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;force-dynamic&lt;/span&gt;&lt;span class="dl"&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;DashboardPage&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="c1"&gt;// This page is never cached on the server&lt;/span&gt;
  &lt;span class="c1"&gt;// Fresh data on every request&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Instead, we moved caching to the &lt;strong&gt;client layer&lt;/strong&gt;:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;React Query&lt;/strong&gt; for server-state caching, background updates, and request deduplication&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Zustand&lt;/strong&gt; for client-side UI state&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Optimistic updates&lt;/strong&gt; for a snappy UX&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Example with React Query:&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;// app/dashboard/activity.js&lt;/span&gt;
&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;use client&lt;/span&gt;&lt;span class="dl"&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;useQuery&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;@tanstack/react-query&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;

&lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;fetchActivity&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="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;/api/activity&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;res&lt;/span&gt; &lt;span class="o"&gt;=&amp;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;json&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;ActivityFeed&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;data&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;isLoading&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;useQuery&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;
    &lt;span class="na"&gt;queryKey&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;activity&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;
    &lt;span class="na"&gt;queryFn&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;fetchActivity&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="na"&gt;staleTime&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;1000&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="mi"&gt;60&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="mi"&gt;5&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="c1"&gt;// Consider data fresh for 5 minutes&lt;/span&gt;
  &lt;span class="p"&gt;})&lt;/span&gt;

  &lt;span class="c1"&gt;// Render feed&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 client cache here?&lt;/strong&gt;&lt;br&gt;&lt;br&gt;
User data is personalized and sensitive. Server caching could leak data between users. Client caching is safe and still provides performance benefits.&lt;/p&gt;


&lt;h2&gt;
  
  
  Layer 4: Real-Time Components with Streaming
&lt;/h2&gt;

&lt;p&gt;For real-time components like live notifications or stats, we used &lt;strong&gt;Streaming with Suspense&lt;/strong&gt;.&lt;/p&gt;
&lt;h3&gt;
  
  
  Component Structure
&lt;/h3&gt;


&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="c1"&gt;// app/dashboard/live-stats.js&lt;/span&gt;
&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;use client&lt;/span&gt;&lt;span class="dl"&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="s1"&gt;react&lt;/span&gt;&lt;span class="dl"&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;LiveStats&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;stats&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;setStats&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="kc"&gt;null&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;ws&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;WebSocket&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;wss://api.example.com/live&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="nx"&gt;ws&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;onmessage&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;event&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;setStats&lt;/span&gt;&lt;span class="p"&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;event&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;data&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="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nx"&gt;ws&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;close&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;stats&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;StatCard&lt;/span&gt; &lt;span class="nx"&gt;stats&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;stats&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="sr"&gt;/&amp;gt; : &amp;lt;StatSkeleton /&lt;/span&gt;&lt;span class="o"&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;
  
  
  Wrapping in Suspense
&lt;/h3&gt;


&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="c1"&gt;// app/dashboard/page.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;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="s1"&gt;react&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="nx"&gt;LiveStats&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;./live-stats&lt;/span&gt;&lt;span class="dl"&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;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="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;div&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;
      &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;h1&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="nx"&gt;Dashboard&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="sr"&gt;/h1&lt;/span&gt;&lt;span class="err"&gt;&amp;gt;
&lt;/span&gt;      &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;Suspense&lt;/span&gt; &lt;span class="nx"&gt;fallback&lt;/span&gt;&lt;span class="o"&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;StatSkeleton&lt;/span&gt; &lt;span class="o"&gt;/&amp;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="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;LiveStats&lt;/span&gt; &lt;span class="o"&gt;/&amp;gt;&lt;/span&gt;
      &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="sr"&gt;/Suspense&lt;/span&gt;&lt;span class="err"&gt;&amp;gt;
&lt;/span&gt;    &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="sr"&gt;/div&lt;/span&gt;&lt;span class="err"&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;This allowed the rest of the page to load quickly while real-time components hydrated separately.&lt;/p&gt;


&lt;h2&gt;
  
  
  The Hybrid Page Problem
&lt;/h2&gt;

&lt;p&gt;Our homepage was tricky:  &lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Static hero section
&lt;/li&gt;
&lt;li&gt;Dynamic user greeting (if logged in)
&lt;/li&gt;
&lt;li&gt;Real-time trending section
&lt;/li&gt;
&lt;li&gt;Cached blog previews&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;
  
  
  Our Solution: Isolate Caching Boundaries
&lt;/h3&gt;


&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="c1"&gt;// app/page.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;React&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;react&lt;/span&gt;&lt;span class="dl"&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;getHeroData&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;getTrendingPosts&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;@/app/actions&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="nx"&gt;UserGreeting&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;./user-greeting&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="nx"&gt;TrendingSection&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;./trending&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="nx"&gt;BlogPreview&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;./blog-preview&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;

&lt;span class="c1"&gt;// Cache static data&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;getCachedHeroData&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;React&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;cache&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;getHeroData&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;getCachedTrending&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;React&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;cache&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;getTrendingPosts&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;HomePage&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;heroData&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;trending&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="nb"&gt;Promise&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;all&lt;/span&gt;&lt;span class="p"&gt;([&lt;/span&gt;
    &lt;span class="nf"&gt;getCachedHeroData&lt;/span&gt;&lt;span class="p"&gt;(),&lt;/span&gt;
    &lt;span class="nf"&gt;getCachedTrending&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="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;main&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;
      &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="cm"&gt;/* Static hero */&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;Hero&lt;/span&gt; &lt;span class="nx"&gt;data&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;heroData&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="sr"&gt;/&lt;/span&gt;&lt;span class="err"&gt;&amp;gt;
&lt;/span&gt;
      &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="cm"&gt;/* Dynamic user greeting */&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;Suspense&lt;/span&gt; &lt;span class="nx"&gt;fallback&lt;/span&gt;&lt;span class="o"&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;GreetingSkeleton&lt;/span&gt; &lt;span class="o"&gt;/&amp;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="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;UserGreeting&lt;/span&gt; &lt;span class="o"&gt;/&amp;gt;&lt;/span&gt;
      &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="sr"&gt;/Suspense&lt;/span&gt;&lt;span class="err"&gt;&amp;gt;
&lt;/span&gt;
      &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="cm"&gt;/* Real-time trending */&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;Suspense&lt;/span&gt; &lt;span class="nx"&gt;fallback&lt;/span&gt;&lt;span class="o"&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;TrendingSkeleton&lt;/span&gt; &lt;span class="o"&gt;/&amp;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="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;TrendingSection&lt;/span&gt; &lt;span class="o"&gt;/&amp;gt;&lt;/span&gt;
      &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="sr"&gt;/Suspense&lt;/span&gt;&lt;span class="err"&gt;&amp;gt;
&lt;/span&gt;
      &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="cm"&gt;/* Cached blog previews */&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;BlogPreview&lt;/span&gt; &lt;span class="nx"&gt;posts&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;trending&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="sr"&gt;/&lt;/span&gt;&lt;span class="err"&gt;&amp;gt;
&lt;/span&gt;    &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="sr"&gt;/main&lt;/span&gt;&lt;span class="err"&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;By splitting sections into different caching boundaries, we optimized each part independently.&lt;/p&gt;


&lt;h2&gt;
  
  
  Monitoring &amp;amp; Debugging
&lt;/h2&gt;

&lt;p&gt;A caching strategy is useless without monitoring.&lt;/p&gt;
&lt;h3&gt;
  
  
  1. Lighthouse + Web Vitals
&lt;/h3&gt;

&lt;p&gt;We ran Lighthouse in CI on every PR and set performance budgets.&lt;/p&gt;
&lt;h3&gt;
  
  
  2. Custom Cache Logging
&lt;/h3&gt;

&lt;p&gt;We added logging middleware to track cache hits/misses:&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;// middleware.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;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="k"&gt;export&lt;/span&gt; &lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;middleware&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;request&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;response&lt;/span&gt; &lt;span class="o"&gt;=&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;next&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;

  &lt;span class="c1"&gt;// Add cache headers for static assets&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;request&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;nextUrl&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;pathname&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;startsWith&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;/_next/static&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;response&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;headers&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;set&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Cache-Control&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="s1"&gt;public, max-age=31536000, immutable&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;response&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  3. Vercel Analytics
&lt;/h3&gt;

&lt;p&gt;We used Vercel’s built-in analytics to monitor cache hit ratios and edge performance.&lt;/p&gt;




&lt;h2&gt;
  
  
  Results &amp;amp; Metrics
&lt;/h2&gt;

&lt;p&gt;After implementing this layered approach:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Lighthouse Performance:&lt;/strong&gt; 96+ (consistent across pages)&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Cache Hit Ratio (CDN):&lt;/strong&gt; 92%&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Reduced Backend Load:&lt;/strong&gt; ~40% fewer queries for cached content&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Time to Interactive:&lt;/strong&gt; Improved by ~35%&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Real-Time Updates:&lt;/strong&gt; Reflected within 2-3 seconds&lt;/li&gt;
&lt;/ul&gt;




&lt;h2&gt;
  
  
  Lessons Learned
&lt;/h2&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Cache based on content type, not convenience&lt;/strong&gt; – Each type of content has different freshness requirements.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Use &lt;code&gt;revalidateTag&lt;/code&gt; over &lt;code&gt;revalidatePath&lt;/code&gt;&lt;/strong&gt; – More precise, less expensive.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Client caching is not obsolete&lt;/strong&gt; – It’s essential for personalized data.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Monitor, monitor, monitor&lt;/strong&gt; – Caching behavior can change with traffic patterns and updates.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Document your strategy&lt;/strong&gt; – Team onboarding and debugging become much easier.&lt;/li&gt;
&lt;/ol&gt;




&lt;h2&gt;
  
  
  Final Thoughts
&lt;/h2&gt;

&lt;p&gt;Caching in the App Router is powerful but requires intentional design. There’s no one-size-fits-all solution. By building a &lt;strong&gt;multi-layer caching strategy&lt;/strong&gt;, you can optimize for both performance and freshness.&lt;/p&gt;

&lt;p&gt;If you’re working on a Next.js app and thinking about caching, start by:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Auditing your content types&lt;/strong&gt; – What’s static? What’s dynamic?
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Mapping content to cache layers&lt;/strong&gt; – Use the right tool for each job.
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Implementing incrementally&lt;/strong&gt; – Start with static pages, then add ISR, then client caching.
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Measuring impact&lt;/strong&gt; – Use Lighthouse and analytics to validate improvements.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Caching isn’t just a performance optimization—it’s a core part of your application architecture. Design it thoughtfully, and your users (and your infrastructure) will thank you.&lt;/p&gt;




&lt;p&gt;&lt;strong&gt;Interested in more deep dives on Next.js performance?&lt;/strong&gt;&lt;br&gt;&lt;br&gt;
Check out my other posts on &lt;a href="https://dev.to/maurya-sachin/the-cost-of-re-renders-how-to-make-react-apps-actually-reactive-3mc6"&gt;React re-renders&lt;/a&gt;, &lt;a href="https://dev.to/maurya-sachin/reducing-javascript-bundle-size-in-nextjs-practical-guide-for-faster-apps-h0"&gt;bundle optimization&lt;/a&gt;, and &lt;a href="https://dev.to/maurya-sachin/wcag-21-complete-guide-for-developers-practical-tips-from-real-audits-3l35"&gt;WCAG compliance&lt;/a&gt;.&lt;/p&gt;

</description>
      <category>webdev</category>
      <category>frontend</category>
      <category>react</category>
      <category>nextjs</category>
    </item>
    <item>
      <title>A More Structured Version of Frontend Master Prep Series</title>
      <dc:creator>Sachin Maurya</dc:creator>
      <pubDate>Fri, 12 Dec 2025 14:49:04 +0000</pubDate>
      <link>https://dev.to/maurya-sachin/a-more-structured-version-of-frontend-master-prep-series-1300</link>
      <guid>https://dev.to/maurya-sachin/a-more-structured-version-of-frontend-master-prep-series-1300</guid>
      <description>&lt;p&gt;I’ve updated the Frontend Master Prep Series with a focus on structure and clarity rather than adding more questions or problems.&lt;/p&gt;

&lt;p&gt;The earlier versions of the repo were useful, but not very guided. There wasn’t a clear sense of where to begin, how to move through topics, or how the Q&amp;amp;A, challenges, and flashcards were meant to work together. This update focuses on solving that.&lt;/p&gt;

&lt;p&gt;The README now includes three specific starting points:&lt;br&gt;
• A four-week study plan for anyone preparing with a defined timeline&lt;br&gt;
• A daily practice flow that combines flashcards and coding problems&lt;br&gt;
• A short, focused revision checklist for last-minute preparation&lt;/p&gt;

&lt;p&gt;The internal structure is now more intentional. Each topic has its own place, and Q&amp;amp;A, examples, and flashcards are no longer mixed together. The architecture section is also separated out so it can grow without affecting the rest of the repo.&lt;/p&gt;

&lt;p&gt;The flashcards have been updated as well. They now work in both Markdown and the interactive version of the app, which uses spaced repetition and tracks progress locally.&lt;/p&gt;

&lt;p&gt;Coding problems remain at 65 for now, but the grouping and purpose are clearer. They are organized by theme and difficulty instead of being a loose collection.&lt;/p&gt;

&lt;p&gt;This update is mainly about usability. The goal is to make the repo something developers can return to regularly, whether they are revising fundamentals or preparing for interviews.&lt;/p&gt;

&lt;p&gt;The repo is here if you want to explore the structure:&lt;br&gt;
&lt;a href="https://github.com/maurya-sachin/Frontend-Master-Prep-Series" rel="noopener noreferrer"&gt;https://github.com/maurya-sachin/Frontend-Master-Prep-Series&lt;/a&gt;&lt;/p&gt;

</description>
      <category>webdev</category>
      <category>learning</category>
      <category>javascript</category>
      <category>react</category>
    </item>
    <item>
      <title>I just shipped v3.0 of Frontend Master Prep Series — Study Paths, 374+ Q&amp;A, 65 Coding Problems &amp; 500+ Flashcards</title>
      <dc:creator>Sachin Maurya</dc:creator>
      <pubDate>Fri, 28 Nov 2025 05:14:21 +0000</pubDate>
      <link>https://dev.to/maurya-sachin/i-just-shipped-v30-of-frontend-master-prep-series-study-paths-374-qa-65-coding-problems--44mi</link>
      <guid>https://dev.to/maurya-sachin/i-just-shipped-v30-of-frontend-master-prep-series-study-paths-374-qa-65-coding-problems--44mi</guid>
      <description>&lt;p&gt;A while back, I shared two big milestones in my frontend prep journey:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;A list of 650+ frontend interview questions&lt;/strong&gt; — the raw brain-dump that started it all.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;v2.0 of Frontend Master Prep Series&lt;/strong&gt; — where that list evolved into a more structured “frontend mastery system.”&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Since then, the repo has kept growing — but more importantly, &lt;strong&gt;how you use it&lt;/strong&gt; has changed.&lt;/p&gt;

&lt;p&gt;Developers didn’t just want &lt;em&gt;more&lt;/em&gt; content.&lt;br&gt;
They wanted:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Clear &lt;strong&gt;entry points&lt;/strong&gt; (What do I do if my interview is tomorrow vs in 4 weeks?)&lt;/li&gt;
&lt;li&gt;A way to &lt;strong&gt;revise quickly&lt;/strong&gt; without scrolling through massive markdown files&lt;/li&gt;
&lt;li&gt;A path that feels like a &lt;strong&gt;learning system&lt;/strong&gt;, not just a massive question bank&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;So v3.0 is all about that.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Less “here are a thousand things you could read.”&lt;br&gt;
More “here’s exactly how to use this to get better, fast.”&lt;/p&gt;
&lt;/blockquote&gt;


&lt;h2&gt;
  
  
  What’s new in v3.0?
&lt;/h2&gt;

&lt;p&gt;Here’s what this release focuses on.&lt;/p&gt;
&lt;h3&gt;
  
  
  1. Guided Quick Start paths
&lt;/h3&gt;

&lt;p&gt;The README now starts with &lt;strong&gt;four clear ways to begin&lt;/strong&gt;:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;4-Week Sprint&lt;/strong&gt; → A complete study plan for people targeting interviews in a month&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Interview Tomorrow?&lt;/strong&gt; → A 30-card flashcard deck for last-minute revision&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Daily Practice&lt;/strong&gt; → A consistent routine with Essential 50 + coding problems&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Interactive Study&lt;/strong&gt; → A flashcard web app you can open in your browser&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Instead of wondering &lt;em&gt;“Where do I start?”&lt;/em&gt;, you pick the path that fits your timeline and dive in. (&lt;a href="https://github.com/maurya-sachin/Frontend-Master-Prep-Series" rel="noopener noreferrer"&gt;GitHub&lt;/a&gt;)&lt;/p&gt;


&lt;h3&gt;
  
  
  2. A cleaner content model (with real numbers)
&lt;/h3&gt;

&lt;p&gt;The repo is now explicitly framed around &lt;strong&gt;three pillars&lt;/strong&gt;:&lt;/p&gt;
&lt;h4&gt;
  
  
  ✅ Core Q&amp;amp;A
&lt;/h4&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;374+ Q&amp;amp;A&lt;/strong&gt; across &lt;strong&gt;16 topics&lt;/strong&gt;
&lt;/li&gt;
&lt;li&gt;JavaScript, TypeScript, React, Next.js, HTML/CSS, Testing, Performance, Accessibility, Security, System Design, Browser, Networking, PWA, Tooling, i18n, SEO&lt;/li&gt;
&lt;li&gt;Each with explanations, follow-up questions, mistakes, and real-world context (&lt;a href="https://github.com/maurya-sachin/Frontend-Master-Prep-Series" rel="noopener noreferrer"&gt;GitHub&lt;/a&gt;)&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;This is the “deep reading + understanding” layer.&lt;/p&gt;
&lt;h4&gt;
  
  
  ✅ Coding Problems
&lt;/h4&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;65 problems&lt;/strong&gt; live right now, targeting &lt;strong&gt;185+&lt;/strong&gt;
&lt;/li&gt;
&lt;li&gt;Categories: JS fundamentals, DOM, React problems, algorithms, UI components, system implementations, company-style questions&lt;/li&gt;
&lt;li&gt;Each problem aims to include: multiple solution approaches, tests, complexity, and real-world use cases (&lt;a href="https://github.com/maurya-sachin/Frontend-Master-Prep-Series" rel="noopener noreferrer"&gt;GitHub&lt;/a&gt;)&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;This is where you move from &lt;em&gt;knowing&lt;/em&gt; to &lt;em&gt;doing&lt;/em&gt;.&lt;/p&gt;
&lt;h4&gt;
  
  
  ✅ Flashcards + Web App
&lt;/h4&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;514+ flashcards&lt;/strong&gt; spread across curated decks and topic decks&lt;/li&gt;
&lt;li&gt;Curated decks like &lt;strong&gt;Essential 50&lt;/strong&gt;, &lt;strong&gt;Pre-Interview 30&lt;/strong&gt;, &lt;strong&gt;Daily Review 20&lt;/strong&gt;
&lt;/li&gt;
&lt;li&gt;Topic decks for JS, React, TS, Next.js, HTML/CSS, Performance, etc.(&lt;a href="https://github.com/maurya-sachin/Frontend-Master-Prep-Series" rel="noopener noreferrer"&gt;GitHub&lt;/a&gt;)&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Two formats:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Markdown (for GitHub / Obsidian / VS Code)&lt;/li&gt;
&lt;li&gt;An &lt;strong&gt;interactive React app&lt;/strong&gt; with spaced repetition (SM-2), local storage, and progress tracking&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;This is your “maintenance mode” — keeping your brain warm daily.&lt;/p&gt;


&lt;h3&gt;
  
  
  3. A dev-friendly, scalable structure
&lt;/h3&gt;

&lt;p&gt;One big change in v3.0 is treating the repo &lt;strong&gt;like a real product&lt;/strong&gt;, not just a folder of notes.&lt;/p&gt;

&lt;p&gt;Here’s the updated structure straight from the repo:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;Frontend-Master-Prep-Series/
├── 01-javascript/          &lt;span class="c"&gt;# Core JS concepts, async, engine internals (53 files)&lt;/span&gt;
├── 02-typescript/          &lt;span class="c"&gt;# Type system, generics, advanced patterns (22 files)&lt;/span&gt;
├── 03-react/               &lt;span class="c"&gt;# Hooks, patterns, performance, internals (71 files)&lt;/span&gt;
├── 04-nextjs/              &lt;span class="c"&gt;# App Router, SSR, ISR, Server Components (16 files)&lt;/span&gt;
├── 05-html-css/            &lt;span class="c"&gt;# Semantics, layouts, modern CSS (19 files)&lt;/span&gt;
├── 06-testing/             &lt;span class="c"&gt;# Jest, RTL, E2E, testing patterns (5 files)&lt;/span&gt;
├── 07-performance/         &lt;span class="c"&gt;# Core Web Vitals, optimization (6 files)&lt;/span&gt;
├── 08-accessibility/       &lt;span class="c"&gt;# WCAG, ARIA, keyboard navigation (17 files)&lt;/span&gt;
├── 09-security/            &lt;span class="c"&gt;# XSS, CSRF, auth, headers (6 files - expanding)&lt;/span&gt;
├── 10-system-design/       &lt;span class="c"&gt;# Component &amp;amp; frontend design patterns (4 files)&lt;/span&gt;
├── 11-browser/             &lt;span class="c"&gt;# Rendering pipeline, storage APIs (3 files)&lt;/span&gt;
├── 12-networking/          &lt;span class="c"&gt;# HTTP/2/3, caching, CDNs (3 files)&lt;/span&gt;
├── 13-pwa/                 &lt;span class="c"&gt;# Service workers, offline-first (3 files)&lt;/span&gt;
├── 14-tooling/             &lt;span class="c"&gt;# Webpack, Vite, Babel (3 files)&lt;/span&gt;
├── 15-i18n/                &lt;span class="c"&gt;# Localization, RTL, formatting (3 files)&lt;/span&gt;
├── 16-architecture/        &lt;span class="c"&gt;# Coming soon - frontend architecture patterns&lt;/span&gt;
├── 17-seo/                 &lt;span class="c"&gt;# Technical SEO, structured data (2 files)&lt;/span&gt;
├── 18-coding-challenges/   &lt;span class="c"&gt;# 65 coding problems&lt;/span&gt;
│   ├── 01-javascript-fundamentals/
│   ├── 02-dom-manipulation/
│   ├── 03-react-problems/
│   ├── 04-algorithms/
│   ├── 05-ui-components/
│   └── 06-performance/
├── 19-flashcards/          &lt;span class="c"&gt;# 514+ flashcards&lt;/span&gt;
│   ├── curated-decks/
│   └── by-topic/
├── src/                    &lt;span class="c"&gt;# Flashcard web app (React + Vite)&lt;/span&gt;
├── public/                 &lt;span class="c"&gt;# Static assets, manifest&lt;/span&gt;
└── resources/              &lt;span class="c"&gt;# Study guides, checklists, learning paths&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This is intentional: if someone clones the repo, they immediately understand &lt;strong&gt;where everything lives&lt;/strong&gt; and how to extend it.&lt;/p&gt;




&lt;h3&gt;
  
  
  4. Study paths baked into the README
&lt;/h3&gt;

&lt;p&gt;You no longer have to invent your own plan.&lt;/p&gt;

&lt;p&gt;The README now includes:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;A &lt;strong&gt;4-week sprint plan&lt;/strong&gt; (week-by-week focus + time estimates)&lt;/li&gt;
&lt;li&gt;A &lt;strong&gt;Daily Practice path&lt;/strong&gt; for long-term growth&lt;/li&gt;
&lt;li&gt;An &lt;strong&gt;“Interview Tomorrow?” checklist&lt;/strong&gt; that tells you exactly what to hit in 30–60 minutes (&lt;a href="https://github.com/maurya-sachin/Frontend-Master-Prep-Series" rel="noopener noreferrer"&gt;GitHub&lt;/a&gt;)&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;This makes the repo usable for:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Panic revision&lt;/li&gt;
&lt;li&gt;Structured, medium-term prep&lt;/li&gt;
&lt;li&gt;Slow, consistent mastery&lt;/li&gt;
&lt;/ul&gt;




&lt;h2&gt;
  
  
  The GitHub repo
&lt;/h2&gt;

&lt;p&gt;👉 &lt;strong&gt;Frontend Master Prep Series v3&lt;/strong&gt;&lt;br&gt;
&lt;a href="https://github.com/maurya-sachin/Frontend-Master-Prep-Series" rel="noopener noreferrer"&gt;https://github.com/maurya-sachin/Frontend-Master-Prep-Series&lt;/a&gt; (&lt;a href="https://github.com/maurya-sachin/Frontend-Master-Prep-Series" rel="noopener noreferrer"&gt;GitHub&lt;/a&gt;)&lt;/p&gt;

&lt;p&gt;Open it in VS Code, Obsidian, or straight in the browser.&lt;br&gt;
Use it as a reference, a study plan, or a daily practice system.&lt;/p&gt;




&lt;h2&gt;
  
  
  Why this version matters
&lt;/h2&gt;

&lt;p&gt;The first post (650+ questions) was about &lt;strong&gt;volume&lt;/strong&gt;.&lt;br&gt;
The second one (v2.0) was about turning that volume into a &lt;strong&gt;mastery system&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;v3.0 is different.&lt;/p&gt;

&lt;p&gt;This release is about &lt;strong&gt;experience&lt;/strong&gt;:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;How fast can you get from “I found this repo” to “I’m using it daily”?&lt;/li&gt;
&lt;li&gt;How easy is it to switch between reading, solving, and revising?&lt;/li&gt;
&lt;li&gt;Can you use it whether you have 10 minutes or 2 hours?&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;I’ve tried to answer those questions with:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Clear quick-start paths&lt;/li&gt;
&lt;li&gt;A predictable structure&lt;/li&gt;
&lt;li&gt;A flashcard app that actually respects how memory works&lt;/li&gt;
&lt;li&gt;Study plans you don’t have to design yourself&lt;/li&gt;
&lt;/ul&gt;




&lt;h2&gt;
  
  
  What’s next?
&lt;/h2&gt;

&lt;p&gt;I’m actively working on:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Filling out &lt;strong&gt;Architecture&lt;/strong&gt; and &lt;strong&gt;System Design&lt;/strong&gt; sections&lt;/li&gt;
&lt;li&gt;More &lt;strong&gt;company-style question sets&lt;/strong&gt;
&lt;/li&gt;
&lt;li&gt;Expanding &lt;strong&gt;React + Next.js patterns&lt;/strong&gt;
&lt;/li&gt;
&lt;li&gt;More &lt;strong&gt;performance &amp;amp; networking case studies&lt;/strong&gt;
&lt;/li&gt;
&lt;li&gt;Potentially a &lt;strong&gt;Notion/Obsidian template&lt;/strong&gt; wired to this structure&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;If there’s something specific you’d like:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;A deck for a specific company?&lt;/li&gt;
&lt;li&gt;More problems in a certain category?&lt;/li&gt;
&lt;li&gt;A deep-dive on a topic inside this repo?&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Open an issue, comment on the repo, or ping me — I’m building this in public and your feedback genuinely shapes the roadmap.&lt;/p&gt;




&lt;h2&gt;
  
  
  Why I keep building this
&lt;/h2&gt;

&lt;p&gt;Honestly, I built this for myself first.&lt;/p&gt;

&lt;p&gt;I wanted to:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Stop prepping from scattered YouTube playlists and notes&lt;/li&gt;
&lt;li&gt;Have a single place that respects both &lt;strong&gt;interview prep&lt;/strong&gt; and &lt;strong&gt;real-world engineering&lt;/strong&gt;
&lt;/li&gt;
&lt;li&gt;Turn my own interview scars into something useful for other devs&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;If even one developer walks into their next interview a little more confident because of this repo, all the late-night organizing, refactoring, and writing has already paid off.&lt;/p&gt;




&lt;p&gt;⭐ If this helps you, consider:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Starring the repo&lt;/li&gt;
&lt;li&gt;Sharing it with a friend who’s prepping&lt;/li&gt;
&lt;li&gt;Sending feedback so v4.0 can be even better&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Let’s make frontend interview prep feel less chaotic — and a lot more intentional.&lt;/p&gt;

</description>
      <category>webdev</category>
      <category>react</category>
      <category>javascript</category>
      <category>career</category>
    </item>
    <item>
      <title>The 7 Mistakes I Made as a Junior Frontend Developer (and the Engineering Fixes That Helped Me Grow Faster)</title>
      <dc:creator>Sachin Maurya</dc:creator>
      <pubDate>Fri, 21 Nov 2025 17:00:34 +0000</pubDate>
      <link>https://dev.to/maurya-sachin/the-7-mistakes-i-made-as-a-junior-frontend-developer-and-the-engineering-fixes-that-helped-me-grow-26ii</link>
      <guid>https://dev.to/maurya-sachin/the-7-mistakes-i-made-as-a-junior-frontend-developer-and-the-engineering-fixes-that-helped-me-grow-26ii</guid>
      <description>&lt;p&gt;Early in my frontend career, I wasn’t struggling because JavaScript was hard.&lt;br&gt;
I struggled because I didn’t understand &lt;em&gt;engineering thinking&lt;/em&gt;.&lt;br&gt;
Here are the mistakes that slowed me down — and the exact technical shifts that finally pushed me forward.&lt;/p&gt;




&lt;h2&gt;
  
  
  &lt;strong&gt;1. Focusing on UI output instead of understanding the architecture&lt;/strong&gt;
&lt;/h2&gt;

&lt;p&gt;I used to write components quickly… and rewrite them even quicker when the project grew.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;What I learned:&lt;/strong&gt;&lt;br&gt;
Frontend is architecture-heavy. Naming, data ownership, routing boundaries, API strategy, state placement — everything matters.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Fix in practice:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Co-located state with the smallest responsible component&lt;/li&gt;
&lt;li&gt;Used “feature-first” folder structure&lt;/li&gt;
&lt;li&gt;Adopted clear boundaries between server state (React Query) and UI state (Zustand/Context)&lt;/li&gt;
&lt;li&gt;Removed cross-feature imports to avoid spaghetti&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;This alone made my codebases far more predictable.&lt;/p&gt;




&lt;h2&gt;
  
  
  &lt;strong&gt;2. Copy–pasting solutions without understanding internals&lt;/strong&gt;
&lt;/h2&gt;

&lt;p&gt;I solved problems fast, but only on the surface.&lt;br&gt;
Whenever something broke, I couldn't debug deeper because I never knew how it &lt;em&gt;actually&lt;/em&gt; worked.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Fix in practice:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Studied the React reconciliation RFC&lt;/li&gt;
&lt;li&gt;Read how the browser event loop schedules microtasks vs macrotasks&lt;/li&gt;
&lt;li&gt;Explored how React Query caches and invalidates data&lt;/li&gt;
&lt;li&gt;Learned how Next.js handles RSC hydration boundaries&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Reading internals gave me “X-ray vision” during debugging.&lt;/p&gt;




&lt;h2&gt;
  
  
  &lt;strong&gt;3. Treating performance as a final step instead of a design constraint&lt;/strong&gt;
&lt;/h2&gt;

&lt;p&gt;I used to optimise only when Lighthouse screamed at me.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Fix in practice:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Measured hydration cost and moved heavy UI to server components&lt;/li&gt;
&lt;li&gt;Reduced bundle size using dynamic imports + route-level code splitting&lt;/li&gt;
&lt;li&gt;Cached expensive calculations using &lt;code&gt;useMemo&lt;/code&gt; only where profiling proved it helped&lt;/li&gt;
&lt;li&gt;Added proper caching headers + ISR for API-heavy pages&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Performance improved because I designed with it in mind.&lt;/p&gt;




&lt;h2&gt;
  
  
  &lt;strong&gt;4. Over-engineering small features&lt;/strong&gt;
&lt;/h2&gt;

&lt;p&gt;I thought adding abstraction made me “senior”.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Fix in practice:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Used reducers only for genuinely complex state transitions&lt;/li&gt;
&lt;li&gt;Avoided wrapper components when plain JSX worked&lt;/li&gt;
&lt;li&gt;Stopped making utility functions for one-line logic&lt;/li&gt;
&lt;li&gt;Followed the “start simple → scale when needed” rule&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Removing unnecessary layers made my code easier to read and maintain.&lt;/p&gt;




&lt;h2&gt;
  
  
  &lt;strong&gt;5. Taking CSS lightly&lt;/strong&gt;
&lt;/h2&gt;

&lt;p&gt;My layouts looked fine… until they broke on a different screen size or when content changed.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Fix in practice:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Learned CSS cascade layers (huge mental unlock)&lt;/li&gt;
&lt;li&gt;Used logical properties for RTL-friendly layouts&lt;/li&gt;
&lt;li&gt;Adopted consistent spacing/typography tokens&lt;/li&gt;
&lt;li&gt;Designed components with intrinsic sizing first, not pixel-perfect assumptions&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;CSS became less “trial and error” and more “predictable behaviour”.&lt;/p&gt;




&lt;h2&gt;
  
  
  &lt;strong&gt;6. Random learning with no system&lt;/strong&gt;
&lt;/h2&gt;

&lt;p&gt;I bounced between tutorials, and it felt like progress… except nothing stuck.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Fix in practice:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Followed a clear roadmap&lt;/li&gt;
&lt;li&gt;Built real projects instead of cloning UIs&lt;/li&gt;
&lt;li&gt;Took notes with examples, not theory&lt;/li&gt;
&lt;li&gt;Revised older codebases to see improvement clearly&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;This structured approach finally created momentum.&lt;/p&gt;




&lt;h2&gt;
  
  
  &lt;strong&gt;7. Ignoring accessibility until a real project forced me to care&lt;/strong&gt;
&lt;/h2&gt;

&lt;p&gt;My mindset changed when I worked on a government project that &lt;em&gt;had&lt;/em&gt; to meet WCAG.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Fix in practice:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Ensured every interactive element was keyboard-first&lt;/li&gt;
&lt;li&gt;Used semantic markup before ARIA&lt;/li&gt;
&lt;li&gt;Tested with screen readers&lt;/li&gt;
&lt;li&gt;Checked contrast ratios and focus paths&lt;/li&gt;
&lt;li&gt;Avoided “div soup” that confuses assistive tech&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Accessibility stopped being a checkbox; it became a performance and UX enhancer.&lt;/p&gt;




&lt;h1&gt;
  
  
  &lt;strong&gt;Why I Wrote This&lt;/strong&gt;
&lt;/h1&gt;

&lt;p&gt;Every engineer grows through mistakes — but some mistakes slow the journey more than others.&lt;br&gt;
These were mine.&lt;br&gt;
If you're somewhere in this list, you’re not behind — you’re right where most of us started.&lt;/p&gt;

</description>
      <category>frontend</category>
      <category>webdev</category>
      <category>javascript</category>
      <category>html</category>
    </item>
    <item>
      <title>I just shipped v2.0 of Frontend Master Prep Series — 1,020+ Q&amp;A + 185 coding problems + 600 flashcards</title>
      <dc:creator>Sachin Maurya</dc:creator>
      <pubDate>Mon, 10 Nov 2025 16:36:25 +0000</pubDate>
      <link>https://dev.to/maurya-sachin/i-just-shipped-v20-of-frontend-master-prep-series-1020-qa-185-coding-problems-600-33j7</link>
      <guid>https://dev.to/maurya-sachin/i-just-shipped-v20-of-frontend-master-prep-series-1020-qa-185-coding-problems-600-33j7</guid>
      <description>&lt;p&gt;A few days back, I published a list of 650+ frontend interview questions.&lt;/p&gt;

&lt;p&gt;That post got attention, feedback, and a surprising amount of messages from developers (both junior and senior) telling me it helped them prep better.&lt;/p&gt;

&lt;p&gt;But something didn’t feel complete.&lt;/p&gt;

&lt;p&gt;Because questions alone are not enough.&lt;/p&gt;

&lt;p&gt;So I continued learning deeply, exploring each topic, facing more interviews, reading docs, breaking code, and then documenting the patterns I found.&lt;/p&gt;

&lt;p&gt;And that small side note list turned into something else completely.&lt;/p&gt;




&lt;h2&gt;
  
  
  What’s new in v2.0?
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;1,020+ questions with detailed answers&lt;/li&gt;
&lt;li&gt;185+ coding problems (each solved step-by-step)&lt;/li&gt;
&lt;li&gt;600+ flashcards for fast revision&lt;/li&gt;
&lt;li&gt;new sections: TypeScript, Security, Testing, Tooling&lt;/li&gt;
&lt;li&gt;difficulty tags, interview frequency, company tags&lt;/li&gt;
&lt;li&gt;code examples + common mistakes + time to answer estimates&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;This is no longer “a question bank”.&lt;br&gt;
This is a &lt;strong&gt;complete frontend mastery system&lt;/strong&gt;.&lt;/p&gt;




&lt;h2&gt;
  
  
  GitHub Repo
&lt;/h2&gt;

&lt;blockquote&gt;
&lt;p&gt;📘 Frontend Master Prep Series v2&lt;br&gt;
&lt;a href="https://github.com/maurya-sachin/Frontend-Master-Prep-Series" rel="noopener noreferrer"&gt;https://github.com/maurya-sachin/Frontend-Master-Prep-Series&lt;/a&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Open-source. Free. Well-structured.&lt;br&gt;
Use it in VS Code / Obsidian / Notion.&lt;/p&gt;




&lt;h2&gt;
  
  
  Why this matters
&lt;/h2&gt;

&lt;p&gt;Most interview prep content online is too shallow.&lt;/p&gt;

&lt;p&gt;It teaches the &lt;em&gt;what&lt;/em&gt;.&lt;/p&gt;

&lt;p&gt;But senior interviews check the &lt;em&gt;why&lt;/em&gt;.&lt;/p&gt;

&lt;p&gt;Why does React re-render?&lt;br&gt;
Why does this promise resolve later?&lt;br&gt;
Why Next.js instead of client-side React?&lt;/p&gt;

&lt;p&gt;This project grew because I kept asking that exact question myself.&lt;/p&gt;




&lt;h2&gt;
  
  
  What’s next?
&lt;/h2&gt;

&lt;p&gt;I’m currently working on:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;a Notion version with progress tracking&lt;/li&gt;
&lt;li&gt;a PDF cheat sheet for 1-day revision&lt;/li&gt;
&lt;li&gt;a “Roadmap style” resource guide by topics&lt;/li&gt;
&lt;/ul&gt;




&lt;h2&gt;
  
  
  Why I built this
&lt;/h2&gt;

&lt;p&gt;To be honest — I built this for myself first.&lt;br&gt;
Because I wanted to really understand this craft.&lt;/p&gt;

&lt;p&gt;But if even one developer somewhere uses this repo and gets more confident before their next interview —&lt;br&gt;
then this work is already worth it.&lt;/p&gt;




&lt;p&gt;If you find this useful — consider giving a ⭐ to the repo.&lt;br&gt;
That’s how I’ll know this should continue growing.&lt;/p&gt;




&lt;p&gt;tags: &lt;code&gt;frontend&lt;/code&gt; &lt;code&gt;react&lt;/code&gt; &lt;code&gt;nextjs&lt;/code&gt; &lt;code&gt;javascript&lt;/code&gt; &lt;code&gt;typescript&lt;/code&gt; &lt;code&gt;webdev&lt;/code&gt; &lt;code&gt;career&lt;/code&gt; &lt;code&gt;interviewprep&lt;/code&gt; &lt;code&gt;learning&lt;/code&gt;&lt;/p&gt;

</description>
      <category>javascript</category>
      <category>career</category>
      <category>webdev</category>
      <category>react</category>
    </item>
    <item>
      <title>650+ Frontend Interview Questions (JavaScript, React, Next.js &amp; More) — My Complete Prep Journey</title>
      <dc:creator>Sachin Maurya</dc:creator>
      <pubDate>Sat, 01 Nov 2025 13:36:16 +0000</pubDate>
      <link>https://dev.to/maurya-sachin/650-frontend-interview-questions-javascript-react-nextjs-more-my-complete-prep-journey-12in</link>
      <guid>https://dev.to/maurya-sachin/650-frontend-interview-questions-javascript-react-nextjs-more-my-complete-prep-journey-12in</guid>
      <description>&lt;p&gt;After giving a few frontend interviews recently, I noticed a pattern.&lt;/p&gt;

&lt;p&gt;Almost every interviewer went beyond surface-level coding questions and asked about how things actually work under the hood —&lt;br&gt;&lt;br&gt;
things like &lt;strong&gt;the event loop&lt;/strong&gt;, &lt;strong&gt;React Fiber&lt;/strong&gt;, &lt;strong&gt;Next.js routing&lt;/strong&gt;, and &lt;strong&gt;JavaScript internals&lt;/strong&gt; that power our apps every day.&lt;/p&gt;

&lt;p&gt;Instead of just memorizing answers, I decided to deeply explore every topic I encountered.&lt;br&gt;&lt;br&gt;
So I began building a small question list.&lt;/p&gt;

&lt;p&gt;Then it became 50.&lt;br&gt;&lt;br&gt;
Then 200.&lt;br&gt;&lt;br&gt;
And finally — a collection of &lt;strong&gt;over 650 questions and concepts&lt;/strong&gt; covering everything from core JavaScript to advanced React and Next.js internals.&lt;/p&gt;




&lt;h2&gt;
  
  
  🔍 What’s Inside
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;💻 &lt;strong&gt;JavaScript Deep Dives&lt;/strong&gt; — event loop, call stack, microtask vs macrotask queues, shadowing, closures, promises, async/await, debouncing, throttling, memory leaks, and more.
&lt;/li&gt;
&lt;li&gt;⚛️ &lt;strong&gt;React Concepts&lt;/strong&gt; — reconciliation, Fiber, lifecycle with hooks, memoization, custom hooks, performance tuning, suspense, error boundaries, and rendering optimization.
&lt;/li&gt;
&lt;li&gt;🔗 &lt;strong&gt;Next.js&lt;/strong&gt; — SSR, SSG, ISR, RSC, parallel routing, middleware, static optimization, SEO, and API routes.
&lt;/li&gt;
&lt;li&gt;🎨 &lt;strong&gt;UI / CSS / HTML&lt;/strong&gt; — accessibility, animations, layouts, BEM, flexbox vs grid, performance, and responsive systems.
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;This isn’t just a question dump — it’s a &lt;strong&gt;structured learning roadmap&lt;/strong&gt; for frontend engineers preparing for interviews or aiming to grow into senior roles.&lt;/p&gt;




&lt;h2&gt;
  
  
  📘 The GitHub Repository
&lt;/h2&gt;

&lt;blockquote&gt;
&lt;p&gt;📘 &lt;strong&gt;View the full guide here:&lt;/strong&gt;&lt;br&gt;&lt;br&gt;
&lt;a href="https://github.com/maurya-sachin/Frontend-Master-Prep-Series/blob/main/README.md" rel="noopener noreferrer"&gt;Frontend Master Prep Series (650+ Questions)&lt;/a&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;It’s a single Markdown file you can open directly in VS Code, Obsidian, or Notion for easy reading and note-taking.&lt;br&gt;&lt;br&gt;
Each section is cleanly structured so you can use it as a reference or learning log.&lt;/p&gt;




&lt;h2&gt;
  
  
  🧩 How I Built It
&lt;/h2&gt;

&lt;p&gt;This list came together from:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Real interview questions I faced during recent rounds
&lt;/li&gt;
&lt;li&gt;Discussions with mentors and frontend peers
&lt;/li&gt;
&lt;li&gt;Topics I explored deeply using ChatGPT, MDN, and official documentation
&lt;/li&gt;
&lt;li&gt;Debugging challenges from my own projects like

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;GENAI Document Analyzer&lt;/strong&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Kreate Energy Platform&lt;/strong&gt;
&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Kreate Technologies&lt;/strong&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Each section evolved organically as I learned — not just &lt;em&gt;what&lt;/em&gt; to answer, but &lt;em&gt;why&lt;/em&gt; things work that way.&lt;/p&gt;




&lt;h2&gt;
  
  
  💬 What’s Next
&lt;/h2&gt;

&lt;p&gt;I’m planning to release:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;🧾 A &lt;strong&gt;PDF cheat sheet&lt;/strong&gt; (condensed quick notes for revision)
&lt;/li&gt;
&lt;li&gt;🧠 A &lt;strong&gt;Notion version&lt;/strong&gt; for interactive prep and progress tracking
&lt;/li&gt;
&lt;li&gt;📚 A &lt;strong&gt;topic-wise resource roadmap&lt;/strong&gt; with links to docs and tutorials
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;If that sounds useful, comment below — I’ll make them public soon.&lt;/p&gt;




&lt;h2&gt;
  
  
  🧠 Why I Wrote This
&lt;/h2&gt;

&lt;p&gt;Because frontend interview prep shouldn’t be about memorizing buzzwords —&lt;br&gt;&lt;br&gt;
it should be about &lt;strong&gt;understanding what makes the web actually work&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;This guide started as a personal learning log, but I realized it could help others too.&lt;br&gt;&lt;br&gt;
If it helps even one developer feel more confident walking into their next interview, it’s worth every late-night deep dive into React Fiber, microtask queues, and performance tuning.&lt;/p&gt;




&lt;p&gt;⭐ If you find it helpful, consider &lt;strong&gt;starring the GitHub repo&lt;/strong&gt; and sharing it with someone preparing for frontend interviews.&lt;br&gt;&lt;br&gt;
Let’s make learning a bit easier for the next person in line.  &lt;/p&gt;




&lt;h1&gt;
  
  
  frontend #react #nextjs #javascript #webdevelopment #career #interviewprep #learningjourney
&lt;/h1&gt;

</description>
      <category>resources</category>
      <category>interview</category>
      <category>javascript</category>
      <category>react</category>
    </item>
    <item>
      <title>The Cost of Re-Renders: How to Make React Apps Actually Reactive</title>
      <dc:creator>Sachin Maurya</dc:creator>
      <pubDate>Thu, 30 Oct 2025 09:44:35 +0000</pubDate>
      <link>https://dev.to/maurya-sachin/the-cost-of-re-renders-how-to-make-react-apps-actually-reactive-3mc6</link>
      <guid>https://dev.to/maurya-sachin/the-cost-of-re-renders-how-to-make-react-apps-actually-reactive-3mc6</guid>
      <description>&lt;h3&gt;
  
  
  &lt;strong&gt;Introduction&lt;/strong&gt;
&lt;/h3&gt;

&lt;p&gt;React’s biggest selling point has always been simple:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;“It’s fast because it re-renders efficiently.”&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;But here’s the uncomfortable truth — &lt;strong&gt;React isn’t fast by default.&lt;/strong&gt;&lt;br&gt;
It’s just &lt;em&gt;forgiving&lt;/em&gt;.&lt;/p&gt;

&lt;p&gt;If you don’t design your state carefully, React’s virtual DOM can easily become your bottleneck.&lt;br&gt;
And the more complex your app grows, the more expensive every unnecessary re-render becomes.&lt;/p&gt;

&lt;p&gt;Let’s dissect &lt;em&gt;why&lt;/em&gt; re-renders happen, how to &lt;em&gt;avoid&lt;/em&gt; them, and what being “reactive” actually means in 2025.&lt;/p&gt;


&lt;h3&gt;
  
  
  &lt;strong&gt;1. Every Re-Render Has a Cost&lt;/strong&gt;
&lt;/h3&gt;

&lt;p&gt;Every React render triggers a reconciliation cycle:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Components re-run,&lt;/li&gt;
&lt;li&gt;Hooks re-evaluate,&lt;/li&gt;
&lt;li&gt;JSX re-diffing happens,&lt;/li&gt;
&lt;li&gt;Child components may re-render too.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;It’s all virtual, but it’s not free.&lt;br&gt;
When your app scales to hundreds of components, these micro re-renders add up — especially when tied to global or context-based state.&lt;/p&gt;


&lt;h3&gt;
  
  
  &lt;strong&gt;2. The Silent Villain: Shared State&lt;/strong&gt;
&lt;/h3&gt;

&lt;p&gt;Developers often push everything into Context or Redux for “simplicity.”&lt;br&gt;
The problem? Every value change triggers &lt;strong&gt;re-renders across all consumers&lt;/strong&gt;, even if most don’t use that specific part of the state.&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;// Common pattern&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;ThemeContext&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;createContext&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;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;&lt;/span&gt;&lt;span class="nc"&gt;ThemeContext&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nc"&gt;Provider&lt;/span&gt; &lt;span class="na"&gt;value&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;darkMode&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;toggleDarkMode&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;Header&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;Sidebar&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;Content&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;ThemeContext&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nc"&gt;Provider&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;Even if only &lt;code&gt;Header&lt;/code&gt; uses &lt;code&gt;darkMode&lt;/code&gt;, all children inside the provider re-render when it changes.&lt;br&gt;
That’s &lt;em&gt;death by a thousand re-renders&lt;/em&gt;.&lt;/p&gt;


&lt;h3&gt;
  
  
  &lt;strong&gt;3. Memoization Isn’t a Silver Bullet&lt;/strong&gt;
&lt;/h3&gt;

&lt;p&gt;You might say, &lt;em&gt;“I’ll just memo everything.”&lt;/em&gt;&lt;br&gt;
Sure — but memoization has its own cost.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;React.memo()&lt;/code&gt; prevents re-renders only if props are shallow-equal.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;useMemo()&lt;/code&gt; and &lt;code&gt;useCallback()&lt;/code&gt; cache computations, but add complexity and memory overhead.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;If you’re wrapping half your tree in &lt;code&gt;React.memo()&lt;/code&gt;, you’re fighting React — not optimizing it.&lt;/p&gt;

&lt;p&gt;The better solution is &lt;strong&gt;state locality&lt;/strong&gt; — keeping state as close as possible to where it’s used.&lt;/p&gt;


&lt;h3&gt;
  
  
  &lt;strong&gt;4. Localize, Slice, and Select&lt;/strong&gt;
&lt;/h3&gt;

&lt;p&gt;The more granular your state, the fewer components React needs to re-render.&lt;/p&gt;

&lt;p&gt;That’s why libraries like &lt;strong&gt;Zustand&lt;/strong&gt;, &lt;strong&gt;Jotai&lt;/strong&gt;, and &lt;strong&gt;Valtio&lt;/strong&gt; are so effective — they allow components to &lt;em&gt;subscribe only to the data they need.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;Example (Zustand):&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="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;useStore&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;create&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kd"&gt;set&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;count&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="na"&gt;increment&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="nf"&gt;set&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;state&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;count&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;state&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;count&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="p"&gt;}));&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="p"&gt;{&lt;/span&gt;
  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;count&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;useStore&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;state&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nx"&gt;state&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="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="p"&gt;&amp;gt;&lt;/span&gt;&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;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;Here, React re-renders &lt;em&gt;only&lt;/em&gt; components using &lt;code&gt;count&lt;/code&gt;, not the entire app.&lt;br&gt;
That’s true &lt;strong&gt;reactivity&lt;/strong&gt;, not reconciliation.&lt;/p&gt;




&lt;h3&gt;
  
  
  &lt;strong&gt;5. Fine-Grained Reactivity Is the Future&lt;/strong&gt;
&lt;/h3&gt;

&lt;p&gt;React’s model is coarse-grained: it re-renders entire components when state changes.&lt;br&gt;
But new paradigms (like &lt;strong&gt;Signals&lt;/strong&gt; in Solid, Qwik, and even React Canary builds) use &lt;strong&gt;fine-grained reactivity&lt;/strong&gt; — updating &lt;em&gt;only the exact DOM nodes&lt;/em&gt; that depend on changed data.&lt;/p&gt;

&lt;p&gt;This shift reduces the cost of re-renders dramatically, making UI feel instantaneous.&lt;/p&gt;

&lt;p&gt;If React 18 was about &lt;em&gt;concurrency&lt;/em&gt;, React 19+ will be about &lt;em&gt;reactivity&lt;/em&gt;.&lt;/p&gt;




&lt;h3&gt;
  
  
  &lt;strong&gt;6. Measuring Re-Render Costs&lt;/strong&gt;
&lt;/h3&gt;

&lt;p&gt;You can’t optimize what you can’t see.&lt;br&gt;
Use the React DevTools “Profiler” to measure where re-renders happen — you’ll often be surprised.&lt;/p&gt;

&lt;p&gt;Look out for:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Components re-rendering without prop/state changes&lt;/li&gt;
&lt;li&gt;Context-heavy trees&lt;/li&gt;
&lt;li&gt;Missing &lt;code&gt;key&lt;/code&gt; attributes&lt;/li&gt;
&lt;li&gt;Inline object/array props&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Identifying hot spots is half the battle.&lt;/p&gt;




&lt;h3&gt;
  
  
  &lt;strong&gt;7. The Real Goal: Flow, Not Frames&lt;/strong&gt;
&lt;/h3&gt;

&lt;p&gt;When your React app feels slow, it’s rarely the algorithm — it’s usually the &lt;strong&gt;render flow&lt;/strong&gt;.&lt;br&gt;
True performance comes from structuring your app around &lt;em&gt;reactive data flow&lt;/em&gt;, not just faster diffing.&lt;/p&gt;

&lt;p&gt;It’s not about “preventing re-renders”; it’s about &lt;strong&gt;making every render count.&lt;/strong&gt;&lt;/p&gt;




&lt;h3&gt;
  
  
  &lt;strong&gt;Conclusion&lt;/strong&gt;
&lt;/h3&gt;

&lt;p&gt;React doesn’t slow down your app — &lt;em&gt;your architecture does.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;Stop chasing &lt;code&gt;useMemo&lt;/code&gt; everywhere.&lt;br&gt;
Start designing &lt;strong&gt;state locality&lt;/strong&gt;, &lt;strong&gt;reactive data flows&lt;/strong&gt;, and &lt;strong&gt;granular subscriptions&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;That’s how modern UIs achieve “speed” — not by skipping renders, but by rendering &lt;em&gt;intelligently.&lt;/em&gt;&lt;/p&gt;




&lt;h3&gt;
  
  
  &lt;strong&gt;Why I Wrote This&lt;/strong&gt;
&lt;/h3&gt;

&lt;p&gt;I wrote this after noticing how often React developers (my past self included) equate “performance” with “memoization.”&lt;br&gt;
But performance doesn’t come from avoiding renders — it comes from understanding &lt;em&gt;when&lt;/em&gt; they happen and &lt;em&gt;why&lt;/em&gt;.&lt;/p&gt;

&lt;p&gt;If this post helped you see React’s rendering model differently, I’d love to hear your take —&lt;br&gt;
How do &lt;strong&gt;you&lt;/strong&gt; handle re-renders in your projects?&lt;br&gt;
Do you rely more on memoization or on state locality patterns (like Zustand/Jotai)?&lt;/p&gt;

&lt;p&gt;Drop your thoughts below — let’s make this a conversation rather than just another React article.&lt;/p&gt;

</description>
      <category>webdev</category>
      <category>react</category>
      <category>javascript</category>
      <category>performance</category>
    </item>
    <item>
      <title>Optimizing for Perceived Performance: The Psychology Behind Fast UIs</title>
      <dc:creator>Sachin Maurya</dc:creator>
      <pubDate>Sat, 11 Oct 2025 18:04:16 +0000</pubDate>
      <link>https://dev.to/maurya-sachin/optimizing-for-perceived-performance-the-psychology-behind-fast-uis-4c11</link>
      <guid>https://dev.to/maurya-sachin/optimizing-for-perceived-performance-the-psychology-behind-fast-uis-4c11</guid>
      <description>&lt;p&gt;When we talk about performance in frontend engineering, we usually mean metrics:&lt;br&gt;
&lt;strong&gt;LCP&lt;/strong&gt;, &lt;strong&gt;FID&lt;/strong&gt;, &lt;strong&gt;CLS&lt;/strong&gt;, &lt;strong&gt;INP&lt;/strong&gt;, &lt;strong&gt;TTFB&lt;/strong&gt; — numbers that quantify “speed.”&lt;/p&gt;

&lt;p&gt;But here’s the truth most developers learn the hard way:&lt;br&gt;
&lt;strong&gt;Users don’t experience speed as numbers. They experience it as &lt;em&gt;feel&lt;/em&gt;.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;And that’s what &lt;em&gt;perceived performance&lt;/em&gt; is about — how fast your app &lt;em&gt;feels&lt;/em&gt;, not just how fast it actually is.&lt;/p&gt;


&lt;h3&gt;
  
  
  &lt;strong&gt;1. Performance ≠ Perception&lt;/strong&gt;
&lt;/h3&gt;

&lt;p&gt;I’ve seen products that hit 95+ Lighthouse scores yet &lt;em&gt;feel sluggish&lt;/em&gt; to users.&lt;br&gt;
At the same time, I’ve built apps that score 80 but feel “instant.”&lt;/p&gt;

&lt;p&gt;Why? Because our brains don’t measure milliseconds. They respond to &lt;strong&gt;feedback, continuity, and control.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;A user who sees immediate feedback (even if data isn’t ready) perceives speed.&lt;br&gt;
A user who waits with no visual cue perceives slowness — even if it’s technically faster.&lt;/p&gt;


&lt;h3&gt;
  
  
  &lt;strong&gt;2. Skeletons, Placeholders, and the Illusion of Speed&lt;/strong&gt;
&lt;/h3&gt;

&lt;p&gt;Let’s take an example:&lt;br&gt;
When your app fetches data, showing nothing makes the user wait.&lt;br&gt;
Showing a skeleton makes them &lt;em&gt;feel&lt;/em&gt; progress.&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="p"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;isLoading&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;SkeletonList&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;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;UserList&lt;/span&gt; &lt;span class="na"&gt;users&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;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Skeleton UIs don’t reduce load time.&lt;br&gt;
They reduce &lt;strong&gt;wait perception&lt;/strong&gt; — the most important performance metric that Lighthouse can’t measure.&lt;/p&gt;


&lt;h3&gt;
  
  
  &lt;strong&gt;3. The Power of Optimistic Updates&lt;/strong&gt;
&lt;/h3&gt;

&lt;p&gt;Optimistic updates are the perfect intersection of UI and psychology.&lt;/p&gt;

&lt;p&gt;You’re not waiting for the server; you’re &lt;strong&gt;trusting&lt;/strong&gt; the user’s intent.&lt;/p&gt;

&lt;p&gt;Example: liking a post, updating a task, or toggling a switch — don’t wait for confirmation. Assume success and sync later.&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="nf"&gt;setLiked&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="nf"&gt;updateLikeOnServer&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;postId&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="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nf"&gt;setLiked&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;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This pattern creates &lt;strong&gt;instant feedback&lt;/strong&gt;, even in high-latency environments.&lt;br&gt;
It’s a small gesture that makes your product feel confident — and that confidence transfers to the user.&lt;/p&gt;


&lt;h3&gt;
  
  
  &lt;strong&gt;4. Transitions: The Hidden Layer of Perceived Speed&lt;/strong&gt;
&lt;/h3&gt;

&lt;p&gt;React’s &lt;code&gt;useTransition&lt;/code&gt; and concurrent rendering introduced a new way to &lt;strong&gt;separate urgent vs. non-urgent updates.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;This isn’t micro-optimization — it’s &lt;em&gt;UX optimization.&lt;/em&gt;&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="kd"&gt;const&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;isPending&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="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;useTransition&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;setFilteredItems&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nf"&gt;filterData&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;items&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;searchTerm&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;Your UI stays responsive while heavy updates happen in the background.&lt;br&gt;
The user keeps typing, scrolling, navigating — uninterrupted.&lt;/p&gt;

&lt;p&gt;That’s perceived performance in motion.&lt;/p&gt;




&lt;h3&gt;
  
  
  &lt;strong&gt;5. Small Delays That Feel Fast&lt;/strong&gt;
&lt;/h3&gt;

&lt;p&gt;It’s counterintuitive, but sometimes &lt;strong&gt;adding delay makes interfaces feel smoother.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;A quick example:&lt;br&gt;
If you show a spinner for only 50ms, users perceive flicker.&lt;br&gt;
If you delay it for 150–200ms, transitions feel natural.&lt;/p&gt;

&lt;p&gt;The brain interprets fluid motion as quality.&lt;br&gt;
That’s why &lt;strong&gt;Framer Motion&lt;/strong&gt; and &lt;strong&gt;GSAP&lt;/strong&gt; animations are performance tools — not just aesthetics.&lt;/p&gt;




&lt;h3&gt;
  
  
  &lt;strong&gt;6. Perception Is a Design System Concern&lt;/strong&gt;
&lt;/h3&gt;

&lt;p&gt;Frontend performance isn’t only a React problem.&lt;br&gt;
It’s a &lt;strong&gt;design system&lt;/strong&gt; problem.&lt;/p&gt;

&lt;p&gt;Designers define visual hierarchy; engineers define &lt;em&gt;interaction hierarchy&lt;/em&gt;.&lt;br&gt;
Knowing what needs to respond instantly (click feedback) vs. what can wait (data rendering) is what creates perceived speed.&lt;/p&gt;

&lt;p&gt;When design and engineering collaborate on feedback loops, even slow backends can &lt;em&gt;feel fast.&lt;/em&gt;&lt;/p&gt;




&lt;h3&gt;
  
  
  &lt;strong&gt;Conclusion&lt;/strong&gt;
&lt;/h3&gt;

&lt;p&gt;We obsess over performance metrics — and we should.&lt;br&gt;
But metrics can’t capture the &lt;strong&gt;emotional velocity&lt;/strong&gt; of your product.&lt;/p&gt;

&lt;p&gt;Users don’t thank you for your 100 Lighthouse score.&lt;br&gt;
They thank you for making things &lt;em&gt;feel&lt;/em&gt; instant, fluid, and alive.&lt;/p&gt;

&lt;p&gt;So next time your app “feels slow,” don’t just open DevTools.&lt;br&gt;
Ask: &lt;em&gt;Where is the user waiting without feedback?&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;That’s your real performance bottleneck.&lt;/p&gt;




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

&lt;h1&gt;
  
  
  FrontendDevelopment #ReactJS #WebPerformance #UXDesign #NextJS #JavaScript
&lt;/h1&gt;

</description>
      <category>webdev</category>
      <category>frontend</category>
      <category>react</category>
      <category>javascript</category>
    </item>
    <item>
      <title>Lessons I Took Away from the Meta Front-End Developer Career Certificate</title>
      <dc:creator>Sachin Maurya</dc:creator>
      <pubDate>Tue, 07 Oct 2025 08:40:14 +0000</pubDate>
      <link>https://dev.to/maurya-sachin/lessons-i-took-away-from-the-meta-front-end-developer-career-certificate-2l1b</link>
      <guid>https://dev.to/maurya-sachin/lessons-i-took-away-from-the-meta-front-end-developer-career-certificate-2l1b</guid>
      <description>&lt;p&gt;&lt;strong&gt;Introduction&lt;/strong&gt;&lt;br&gt;
When I picked up the &lt;strong&gt;Meta Front-End Developer Career Certificate&lt;/strong&gt; on Coursera, I thought of it as just another structured path to sharpen my React and frontend skills. What I didn’t expect was how it would shift my perspective from &lt;em&gt;building pages&lt;/em&gt; to &lt;em&gt;engineering user experiences.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;Here’s what stood out to me.&lt;/p&gt;




&lt;h2&gt;
  
  
  1. Frontend engineering is more than visuals
&lt;/h2&gt;

&lt;p&gt;The course emphasizes HTML, CSS, and JavaScript fundamentals, but the deeper value is in accessibility and responsive design.&lt;/p&gt;

&lt;p&gt;I learned that:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Semantic HTML improves accessibility for real users (and screen readers).&lt;/li&gt;
&lt;li&gt;ARIA roles aren’t optional if inclusivity is the goal.&lt;/li&gt;
&lt;li&gt;Responsive layouts are not “mobile-friendly hacks” but part of design systems.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;This mindset helps move from “does it render?” to “does it serve everyone?”&lt;/p&gt;




&lt;h2&gt;
  
  
  2. Performance is a feature
&lt;/h2&gt;

&lt;p&gt;One big takeaway: performance isn’t something to patch later — it’s something to design for.&lt;/p&gt;

&lt;p&gt;From my projects, I experimented with:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Code-splitting and dynamic imports to reduce JS bundles.&lt;/li&gt;
&lt;li&gt;Caching and ISR in Next.js for faster delivery.&lt;/li&gt;
&lt;li&gt;Image and font optimization to improve Core Web Vitals.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;When performance is prioritized early, users notice.&lt;/p&gt;




&lt;h2&gt;
  
  
  3. Error states matter more than happy paths
&lt;/h2&gt;

&lt;p&gt;The course introduces testing and debugging, but I pushed this further with error boundaries and resilient components.&lt;/p&gt;

&lt;p&gt;The lesson: &lt;strong&gt;a broken app erodes trust immediately.&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;A fallback message is better than a crash.&lt;/li&gt;
&lt;li&gt;A retry button tells the user you thought ahead.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Good UI is defined by how it behaves under stress.&lt;/p&gt;




&lt;h2&gt;
  
  
  4. Learning compounds when you share
&lt;/h2&gt;

&lt;p&gt;I didn’t stop at completing exercises. I extended them into projects and wrote about accessibility audits, state management tradeoffs, and rendering strategies.&lt;/p&gt;

&lt;p&gt;By sharing, I not only reinforced my learning but also connected with developers who challenged me with new ideas (like diving into &lt;code&gt;useTransition&lt;/code&gt;).&lt;/p&gt;




&lt;p&gt;&lt;strong&gt;Conclusion&lt;/strong&gt;&lt;br&gt;
The Meta Front-End Developer Career Certificate isn’t just about checking a box. It’s about developing the discipline to think about accessibility, performance, resilience, and communication as core parts of frontend engineering.&lt;/p&gt;

&lt;p&gt;Courses give you the scaffolding — but it’s the building, testing, and sharing that turn it into real growth.&lt;/p&gt;

</description>
      <category>frontend</category>
      <category>javascript</category>
      <category>webdev</category>
      <category>react</category>
    </item>
    <item>
      <title>Mastering React’s useTransition: Smooth UI Updates Without Blocking the Main Thread</title>
      <dc:creator>Sachin Maurya</dc:creator>
      <pubDate>Wed, 24 Sep 2025 06:32:26 +0000</pubDate>
      <link>https://dev.to/maurya-sachin/mastering-reacts-usetransition-smooth-ui-updates-without-blocking-the-main-thread-2ngk</link>
      <guid>https://dev.to/maurya-sachin/mastering-reacts-usetransition-smooth-ui-updates-without-blocking-the-main-thread-2ngk</guid>
      <description>&lt;p&gt;&lt;strong&gt;Introduction:&lt;/strong&gt;&lt;br&gt;
A few days ago, I was diving into rendering strategies in React and Next.js, discussing CSR, SSR, SSG, and ISR. One comment really caught my eye:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;“useEffect ❌, useTransition ✅”&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;This got me curious—how can we make our React apps feel instantly responsive even under heavy state updates? That’s where &lt;code&gt;useTransition&lt;/code&gt; shines. Let’s break it down and see how to use it effectively.&lt;/p&gt;



&lt;p&gt;&lt;strong&gt;1. Why We Need &lt;code&gt;useTransition&lt;/code&gt;&lt;/strong&gt;&lt;br&gt;
In complex React apps, updating state in big components (like large lists, dashboards, or filtered tables) can block the main thread. Typing, clicking, or scrolling feels sluggish. Traditional &lt;code&gt;useEffect&lt;/code&gt; updates can cause noticeable lag because React treats them as &lt;strong&gt;urgent&lt;/strong&gt; updates.&lt;/p&gt;

&lt;p&gt;&lt;code&gt;useTransition&lt;/code&gt; (introduced in React 18) lets us mark some updates as &lt;strong&gt;transitions&lt;/strong&gt;, which are non-urgent. React can then prioritize keeping the UI responsive while handling heavier updates in the background.&lt;/p&gt;



&lt;p&gt;&lt;strong&gt;2. Basic Usage&lt;/strong&gt;&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="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="nx"&gt;useTransition&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;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;SearchList&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt; &lt;span class="nx"&gt;data&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;query&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;setQuery&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="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="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;filtered&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;setFiltered&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;data&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;isPending&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="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;useTransition&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;handleChange&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;e&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;value&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;e&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;target&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;value&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="nf"&gt;setQuery&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;value&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="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;result&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;data&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;filter&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;item&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nx"&gt;item&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;includes&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;value&lt;/span&gt;&lt;span class="p"&gt;));&lt;/span&gt;
      &lt;span class="nf"&gt;setFiltered&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;result&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="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nt"&gt;div&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;input&lt;/span&gt; &lt;span class="na"&gt;type&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;"text"&lt;/span&gt; &lt;span class="na"&gt;value&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;query&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt; &lt;span class="na"&gt;onChange&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;handleChange&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;isPending&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&amp;amp;&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;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;filtered&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;item&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;idx&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="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;idx&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;item&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="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;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;div&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;strong&gt;Explanation:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;isPending&lt;/code&gt;: true while the transition is in progress&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;startTransition&lt;/code&gt;: wraps state updates we want to defer&lt;/li&gt;
&lt;li&gt;Result: typing remains smooth, even for large lists&lt;/li&gt;
&lt;/ul&gt;




&lt;p&gt;&lt;strong&gt;3. When to Use &lt;code&gt;useTransition&lt;/code&gt;&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Typing/search in large datasets&lt;/li&gt;
&lt;li&gt;Filtering or sorting heavy lists&lt;/li&gt;
&lt;li&gt;Updating dashboards with multiple components&lt;/li&gt;
&lt;li&gt;UI interactions that must stay responsive&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;4. Best Practices&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Don’t overuse: simple state toggles don’t need transitions&lt;/li&gt;
&lt;li&gt;Combine with &lt;code&gt;React.memo&lt;/code&gt; to avoid unnecessary re-renders&lt;/li&gt;
&lt;li&gt;Use with Suspense for async updates to show loaders&lt;/li&gt;
&lt;/ul&gt;




&lt;p&gt;&lt;strong&gt;5. Real-World Example&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Imagine a product catalog with 1000+ items. Without &lt;code&gt;useTransition&lt;/code&gt;, typing in a search bar blocks the UI. With &lt;code&gt;useTransition&lt;/code&gt;:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Typing stays fluid&lt;/li&gt;
&lt;li&gt;Filtered results update progressively&lt;/li&gt;
&lt;li&gt;Optional “Loading…” feedback via &lt;code&gt;isPending&lt;/code&gt;
&lt;/li&gt;
&lt;/ul&gt;




&lt;p&gt;&lt;strong&gt;6. Measuring Improvements&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Use React Profiler to see which components re-render&lt;/li&gt;
&lt;li&gt;Check Core Web Vitals for interactive performance&lt;/li&gt;
&lt;li&gt;Verify that deferred updates don’t compromise UX&lt;/li&gt;
&lt;/ul&gt;




&lt;p&gt;&lt;strong&gt;Conclusion:&lt;/strong&gt;&lt;br&gt;
&lt;code&gt;useTransition&lt;/code&gt; is simple but powerful. It prioritizes UX over raw computation speed, making apps feel smoother and more professional. Next time your React app feels sluggish during large updates, consider marking some updates as transitions—you might be surprised by the difference.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;CTA:&lt;/strong&gt;&lt;br&gt;
Have you tried &lt;code&gt;useTransition&lt;/code&gt; yet? Share your experiences or tricky edge cases in the comments—I’d love to hear how you make your React apps feel lightning-fast!&lt;/p&gt;

</description>
      <category>react</category>
      <category>webdev</category>
      <category>nextjs</category>
      <category>ui</category>
    </item>
    <item>
      <title>Rendering Strategies in Next.js: CSR, SSR, SSG, ISR Explained</title>
      <dc:creator>Sachin Maurya</dc:creator>
      <pubDate>Thu, 18 Sep 2025 12:41:25 +0000</pubDate>
      <link>https://dev.to/maurya-sachin/rendering-strategies-in-nextjs-csr-ssr-ssg-isr-explained-417n</link>
      <guid>https://dev.to/maurya-sachin/rendering-strategies-in-nextjs-csr-ssr-ssg-isr-explained-417n</guid>
      <description>&lt;p&gt;Next.js gives us the flexibility to decide &lt;strong&gt;how each page should be rendered&lt;/strong&gt;.&lt;br&gt;
That flexibility is powerful — but also confusing if you don’t know the tradeoffs.&lt;/p&gt;

&lt;p&gt;In this post, let’s break down the 4 main rendering strategies in Next.js with examples and use cases.&lt;/p&gt;




&lt;h2&gt;
  
  
  1. Client-Side Rendering (CSR)
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;How it works:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Page loads with minimal HTML.&lt;/li&gt;
&lt;li&gt;Data is fetched in the browser using &lt;code&gt;useEffect&lt;/code&gt; or similar hooks.
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight tsx"&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;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;Profile&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;user&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;setUser&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="kc"&gt;null&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="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/user&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="nf"&gt;then&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;res&lt;/span&gt; &lt;span class="o"&gt;=&amp;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;json&lt;/span&gt;&lt;span class="p"&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;setUser&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;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;user&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="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="k"&gt;return&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;Hello &lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;user&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;name&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;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;✅ Good for: dashboards, private user pages.&lt;br&gt;
❌ Bad for: SEO and initial load performance.&lt;/p&gt;




&lt;h2&gt;
  
  
  2. Server-Side Rendering (SSR)
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;How it works:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Page HTML is generated on each request.&lt;/li&gt;
&lt;li&gt;Always up-to-date but increases server load.
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight tsx"&gt;&lt;code&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/products&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;products&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;products&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;Products&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="p"&gt;{&lt;/span&gt;
  &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nx"&gt;products&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;p&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;name&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;✅ Good for: user-specific dashboards, search pages.&lt;br&gt;
❌ Bad for: pages with high traffic but static data.&lt;/p&gt;




&lt;h2&gt;
  
  
  3. Static Site Generation (SSG)
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;How it works:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Pages are built into static HTML at build time.&lt;/li&gt;
&lt;li&gt;Served instantly via CDN.
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight tsx"&gt;&lt;code&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://api.example.com/blog&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;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;✅ Good for: marketing pages, blogs, docs.&lt;br&gt;
❌ Bad for: content that changes often (stock prices, news).&lt;/p&gt;




&lt;h2&gt;
  
  
  4. Incremental Static Regeneration (ISR)
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;How it works:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Pages are pre-rendered statically, then &lt;strong&gt;revalidated on a schedule&lt;/strong&gt;.&lt;/li&gt;
&lt;li&gt;Combines the speed of SSG with freshness of SSR.
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight tsx"&gt;&lt;code&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://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="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="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;products&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="c1"&gt;// revalidate every 60s&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;✅ Good for: product catalogs, dashboards, news feeds.&lt;br&gt;
❌ Requires caching strategy &amp;amp; CDN setup to be effective.&lt;/p&gt;




&lt;h2&gt;
  
  
  Choosing the Right Strategy
&lt;/h2&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Strategy&lt;/th&gt;
&lt;th&gt;Speed&lt;/th&gt;
&lt;th&gt;Freshness&lt;/th&gt;
&lt;th&gt;SEO&lt;/th&gt;
&lt;th&gt;Best Use Case&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;CSR&lt;/td&gt;
&lt;td&gt;Slow&lt;/td&gt;
&lt;td&gt;Fresh&lt;/td&gt;
&lt;td&gt;Poor&lt;/td&gt;
&lt;td&gt;Private dashboards&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;SSR&lt;/td&gt;
&lt;td&gt;Medium&lt;/td&gt;
&lt;td&gt;Fresh&lt;/td&gt;
&lt;td&gt;Good&lt;/td&gt;
&lt;td&gt;User-specific pages&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;SSG&lt;/td&gt;
&lt;td&gt;Fast&lt;/td&gt;
&lt;td&gt;Stale&lt;/td&gt;
&lt;td&gt;Great&lt;/td&gt;
&lt;td&gt;Blogs, docs&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;ISR&lt;/td&gt;
&lt;td&gt;Fast&lt;/td&gt;
&lt;td&gt;Semi-fresh&lt;/td&gt;
&lt;td&gt;Great&lt;/td&gt;
&lt;td&gt;Product listings&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;




&lt;h2&gt;
  
  
  Closing Thoughts
&lt;/h2&gt;

&lt;p&gt;The beauty of Next.js is that you don’t need a &lt;strong&gt;one-size-fits-all&lt;/strong&gt; solution.&lt;br&gt;
You can mix rendering strategies across routes to balance speed, freshness, and scalability.&lt;/p&gt;

&lt;p&gt;👉 Pro tip: Start with &lt;strong&gt;SSG/ISR&lt;/strong&gt; for performance, and use &lt;strong&gt;SSR/CSR&lt;/strong&gt; only where absolutely necessary.&lt;/p&gt;




&lt;p&gt;💬 Which rendering strategy has worked best in your projects — and where did it fail?&lt;/p&gt;

</description>
      <category>nextjs</category>
      <category>javascript</category>
      <category>react</category>
      <category>webdev</category>
    </item>
  </channel>
</rss>
