<?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: Hamed Fatehi</title>
    <description>The latest articles on DEV Community by Hamed Fatehi (@hamed-fatehi).</description>
    <link>https://dev.to/hamed-fatehi</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F1062717%2F1076699a-f3e2-4f06-90a0-12cb79dc66af.jpeg</url>
      <title>DEV Community: Hamed Fatehi</title>
      <link>https://dev.to/hamed-fatehi</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/hamed-fatehi"/>
    <language>en</language>
    <item>
      <title>Demystifying OAuth 2.0 with a Clubbing Analogy</title>
      <dc:creator>Hamed Fatehi</dc:creator>
      <pubDate>Tue, 26 Mar 2024 12:07:57 +0000</pubDate>
      <link>https://dev.to/hamed-fatehi/vip-access-only-demystifying-oauth-20-with-a-clubbing-analogy-nca</link>
      <guid>https://dev.to/hamed-fatehi/vip-access-only-demystifying-oauth-20-with-a-clubbing-analogy-nca</guid>
      <description>&lt;p&gt;Understanding OAuth 2.0 authentication can be complex. To simplify, we compare it to a club night out, using Google OAuth 2.0 as our example. This analogy will help demystify how applications authenticate users and manage access. Let's break down this process into more relatable terms.&lt;/p&gt;

&lt;h3&gt;
  
  
  Key Technical Terms and Their Club Night Out Analogies
&lt;/h3&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;&lt;strong&gt;Technical Term&lt;/strong&gt;&lt;/th&gt;
&lt;th&gt;&lt;strong&gt;Analogy&lt;/strong&gt;&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Client ID&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Akin to an event flyer with a QR code that gets you started on your journey to the club.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Client Secret&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Similar to a secret passphrase given to the club's entrance (the backend) by the club's partner (Google), ensuring that the entrance is authorized to request VIP passes on behalf of guests.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Google OAuth&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Comparable to the special pass system managed by the club's partner, verifying your identity and granting access.&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;h4&gt;
  
  
  Clarifications
&lt;/h4&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Where does the Client Secret come from?&lt;/strong&gt; The Client Secret is provided by Google when the application is registered with Google's OAuth system. It's like when the club's entrance (the backend of the application) gets a secret passphrase directly from the club's partner (Google) as proof of their partnership and authorization to request VIP passes.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Why does the backend have a Client Secret at all?&lt;/strong&gt; The backend holds the Client Secret to prove its identity and authorization to Google. It's necessary because it ensures that not just anyone can request access tokens on behalf of the application. Think of it as a way to prevent unauthorized parties from acting as the club's entrance and requesting VIP passes without proper authorization.&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Authentication Flow and Club Night Out Analogy Explanation
&lt;/h3&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;&lt;strong&gt;Authentication Flow Steps&lt;/strong&gt;&lt;/th&gt;
&lt;th&gt;&lt;strong&gt;Club Night Out Analogy&lt;/strong&gt;&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;
&lt;strong&gt;1. Redirect to Google OAuth Page:&lt;/strong&gt; Frontend (F) directs the user to Google's OAuth 2.0 authentication page.&lt;/td&gt;
&lt;td&gt;
&lt;strong&gt;1. Heading to Google Club Partner's Booth:&lt;/strong&gt; You follow the instructions (like a QR code on a flyer) to go to the Google Club Partner's booth to start the access process.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;
&lt;strong&gt;2. User Grants Access:&lt;/strong&gt; User agrees to grant the application access to specified data on the consent screen.&lt;/td&gt;
&lt;td&gt;
&lt;strong&gt;2. Showing Your ID at the Booth:&lt;/strong&gt; You show your ID (Google credentials) at the booth, allowing Google to verify who you are, similar to giving consent for a VIP status check.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;
&lt;strong&gt;3. Auth Code via /auth/google/redirect:&lt;/strong&gt; Google redirects the user back to the application with an authorization code.&lt;/td&gt;
&lt;td&gt;
&lt;strong&gt;3. Receiving a Special Code:&lt;/strong&gt; Google verifies your ID and gives you a special code, like a temporary VIP pass, to take to the club's entrance.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;
&lt;strong&gt;4. Exchange Code with Token:&lt;/strong&gt; The backend receives the code and sends it back to Google, alongside the clientID and clientSecret for authentication.&lt;/td&gt;
&lt;td&gt;
&lt;strong&gt;4. Exchanging the Code at the Club Entrance:&lt;/strong&gt; You present the special code at the club's entrance. The entrance then uses the secret passphrase (clientSecret) to prove to Google that it's authorized to request the actual VIP pass.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;
&lt;strong&gt;5. Token Response:&lt;/strong&gt; Google validates the authorization code, clientID, and clientSecret, then sends an access token back to the application.&lt;/td&gt;
&lt;td&gt;
&lt;strong&gt;5. Getting the Pass:&lt;/strong&gt; Google recognizes the passphrase, validating the club's entrance request, and issues the actual VIP pass (access token).&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;
&lt;strong&gt;6. Create JWT Token:&lt;/strong&gt; The backend generates a JWT for the authenticated user using the access token.&lt;/td&gt;
&lt;td&gt;
&lt;strong&gt;6. Creating Your VIP Badge:&lt;/strong&gt; With the VIP pass received, the club's entrance creates a VIP badge for you, symbolizing your verified access.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;
&lt;strong&gt;7. Set JWT Token in Cookie and Redirect:&lt;/strong&gt; The backend places the JWT in an HTTP-only cookie and redirects the user to the dashboard on the Frontend.&lt;/td&gt;
&lt;td&gt;
&lt;strong&gt;7. Entering the Club:&lt;/strong&gt; With the VIP badge (the JWT in a cookie), you're granted entry into the club, ready to enjoy its exclusive amenities.&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;Now lets have a look at the technical sequence diagram of the OAuth Authentication flow and see if we can understand it better:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fzeluttnbmplwvcerbwfy.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fzeluttnbmplwvcerbwfy.png" alt="Google OAuth Sequence Diagram" width="800" height="352"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Hopefully it is now more clear :)&lt;/p&gt;

&lt;p&gt;For a deeper dive into Google OAuth 2.0, check out this &lt;a href="https://developers.google.com/identity/protocols/oauth2"&gt;Google Developers post&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Thanks for reading!&lt;/p&gt;

&lt;p&gt;As always, I appreciate any feedback. 🍺&lt;/p&gt;

</description>
      <category>oauth</category>
      <category>security</category>
      <category>google</category>
    </item>
    <item>
      <title>How to Implement Micro Frontends Using SystemJS: A Comprehensive Guide</title>
      <dc:creator>Hamed Fatehi</dc:creator>
      <pubDate>Tue, 19 Mar 2024 09:55:10 +0000</pubDate>
      <link>https://dev.to/hamed-fatehi/how-to-implement-micro-frontends-using-systemjs-a-comprehensive-guide-i3a</link>
      <guid>https://dev.to/hamed-fatehi/how-to-implement-micro-frontends-using-systemjs-a-comprehensive-guide-i3a</guid>
      <description>&lt;p&gt;In the ever-evolving landscape of web development, the need for scalable, maintainable, and flexible architectures has never been greater. Enter micro frontends, a design approach that breaks down the frontend monolith into smaller, more manageable pieces. Much like microservices have revolutionized backend development by decomposing complex applications into smaller services, micro frontends aim to achieve the same for the user interface. The benefits of this approach are manifold:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Scalability&lt;/strong&gt;: By breaking down the frontend into smaller units, teams can scale development processes more efficiently.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Independence&lt;/strong&gt;: Different teams can work on different parts of the frontend simultaneously without stepping on each other's toes.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Flexibility&lt;/strong&gt;: It's easier to experiment with new technologies or frameworks when you're working with a smaller piece of the puzzle.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Resilience&lt;/strong&gt;: A failure in one micro frontend doesn't necessarily bring down the entire application.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Reusability&lt;/strong&gt;: Components or entire micro frontends can be reused across different parts of the application or even different projects.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Given these advantages, it's tempting to dive right into micro frontends. However, it's crucial to understand the architectural choices available and their implications. Broadly speaking, there are two prevalent approaches:&lt;/p&gt;

&lt;p&gt;1.&lt;strong&gt;Central Orchestrator Model&lt;/strong&gt;: In this approach, there's a primary application that acts as the orchestrator. It's responsible for mounting and unmounting micro frontends based on user interactions or other triggers. This centralized control can simplify state management and inter-micro frontend communication. However, a significant challenge arises when different micro frontends use different frameworks. Even varying versions of the same framework can pose integration challenges. Consistency in technology choices becomes essential for smooth operation.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F05ka209dlq2z3rv4wdqo.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F05ka209dlq2z3rv4wdqo.png" alt="Central Orchestrator Model"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;2.&lt;strong&gt;Route-Driven Fragmentation&lt;/strong&gt;: Here, the main application is stripped down to its bare essentials, primarily handling routes. Each route or link corresponds to a micro frontend, making this approach particularly suitable for dashboards or applications where each view is distinct. The primary advantage is the flexibility it offers. Since each micro frontend is loaded independently based on routes, there's greater freedom in choosing frameworks or technologies for each one. Teams can pick the best tool for the job without being constrained by the choices of other micro frontends.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fz77oeimlbg49k9ntx7hb.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fz77oeimlbg49k9ntx7hb.png" alt="Route-Driven Fragmentation"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  State Management in Micro Frontends
&lt;/h2&gt;

&lt;p&gt;State management is a cornerstone of any frontend application, determining how data flows, is stored, and is manipulated. When diving into the realm of micro frontends, the challenge amplifies, given the distributed nature of the architecture. Let's explore how state management varies between the two primary micro frontend architectural approaches.&lt;/p&gt;

&lt;h3&gt;
  
  
  Central Orchestrator Model
&lt;/h3&gt;

&lt;p&gt;In this approach, the overarching application acts as the central hub, making it conducive to employ a centralized state management system. Tools like Redux, Vuex, or NgRx can be seamlessly integrated, allowing for a unified store that holds the global state.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Programmatic State Passing&lt;/strong&gt;: The main application can pass down relevant parts of the state to individual micro frontends as they are mounted. Depending on the framework, this can be achieved through props, context, or other mechanisms. This ensures that each micro frontend has access to the data it needs without being overwhelmed by the entirety of the global state.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Modularity with Centralization&lt;/strong&gt;: Even though the state is centralized, it doesn't mean everything is lumped together. Middleware, actions, reducers, or equivalent constructs can be organized around individual micro frontends. This ensures modularity and maintainability while benefiting from a unified data store.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Route-Driven Fragmentation
&lt;/h3&gt;

&lt;p&gt;Given the isolated nature of micro frontends in this approach, state management tends to be more decentralized.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;URL Params:&lt;/strong&gt; State relevant to navigation or user interface settings can be encoded in the URL. This allows for deep linking, where users can bookmark or share specific application views. For instance, a dashboard's filter settings might be represented as URL parameters, ensuring consistent views upon navigation.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Global Window Variables:&lt;/strong&gt; While not always recommended due to potential risks like accidental overwrites, global window variables can serve as a mechanism to share state or functions between micro frontends. However, care must be taken to ensure encapsulation and avoid naming collisions.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;External State Stores:&lt;/strong&gt; To achieve a shared state without relying on the main app, micro frontends can resort to external state stores or services. Backend APIs, browser databases like IndexedDB, or even cloud-based real-time databases can be employed. This allows micro frontends to fetch and update shared state independently.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;In essence, while the "Central Orchestrator Model" approach leans towards a more centralized state management system, the "Route-Driven Fragmentation" approach demands a more decentralized and strategic approach to handle state. Both methods come with their set of challenges and advantages, and the choice largely depends on the specific needs of the application and the preferences of the development team.&lt;/p&gt;

&lt;h2&gt;
  
  
  Technical Implementation
&lt;/h2&gt;

&lt;p&gt;In the realm of Micro Frontends, whether you opt for the Central Orchestrator Model or the Route-Driven Fragmentation approach, the technical implementation plays a crucial role. There are several interesting options available, from Import Maps for controlled module loading to leveraging the dynamic module capabilities of SystemJS. Module Federation offers a way to seamlessly share dependencies across builds, while Single SPA provides a comprehensive solution specifically designed for managing Micro Frontends and often suggests using SystemJS for optimal module loading. Each of these options has its own pros and cons.&lt;/p&gt;

&lt;p&gt;I conclude this article with an example, demonstrating how to use SystemJS to implement Micro Frontends without additional frameworks. The advantage of SystemJS over Webpack Module Federation is that it does not bind you to a specific bundler.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Structure of the Micro Frontend&lt;/strong&gt;:
The Micro Frontend defines two functions, &lt;code&gt;mount&lt;/code&gt; and &lt;code&gt;unmount&lt;/code&gt; in &lt;code&gt;src/main.tsx&lt;/code&gt;, which enable the main application to control the loading and unloading of the Micro Frontend.&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;

&lt;span class="c1"&gt;// src/main.tsx&lt;/span&gt;
&lt;span class="kd"&gt;let&lt;/span&gt; &lt;span class="nx"&gt;rootInstance&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;Root&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="kc"&gt;null&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="kc"&gt;null&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;mount&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;containerId&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kr"&gt;string&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;token&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kr"&gt;string&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;container&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nb"&gt;document&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;getElementById&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;containerId&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;container&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;error&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;`Container with id "&lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;containerId&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;" not found.`&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;}&lt;/span&gt;

  &lt;span class="nf"&gt;initializeFirebase&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;token&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="nx"&gt;rootInstance&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;createRoot&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;container&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="nx"&gt;rootInstance&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;render&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;ChatPartnerProvider&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;App&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;/ChatPartnerProvider&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;span class="k"&gt;export&lt;/span&gt; &lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;unmount&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;containerId&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kr"&gt;string&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="k"&gt;if &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;rootInstance&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nx"&gt;rootInstance&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;unmount&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
    &lt;span class="nx"&gt;rootInstance&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="kc"&gt;null&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;else&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;error&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;`Application not mounted to "&lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;containerId&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;"`&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;


&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Dynamic Loading through the Main Application&lt;/strong&gt;:
The main application uses SystemJS to dynamically load the Micro Frontend. The &lt;code&gt;loadMicroFrontend&lt;/code&gt; function loads the bundled Micro Frontend from a Google Cloud Storage Bucket.&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;

&lt;span class="kd"&gt;let&lt;/span&gt; &lt;span class="nx"&gt;microFrontendPromise&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;Promise&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="kr"&gt;any&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="kc"&gt;null&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="kc"&gt;null&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="kd"&gt;type&lt;/span&gt; &lt;span class="nx"&gt;MicroFe&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="na"&gt;mount&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="na"&gt;containerId&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kr"&gt;string&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="k"&gt;void&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="na"&gt;unmount&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="na"&gt;containerId&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kr"&gt;string&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="k"&gt;void&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;span class="p"&gt;};&lt;/span&gt;

&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;loadMicroFrontend&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;async &lt;/span&gt;&lt;span class="p"&gt;():&lt;/span&gt; &lt;span class="nb"&gt;Promise&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;MicroFe&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="kc"&gt;undefined&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="k"&gt;if &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;!&lt;/span&gt;&lt;span class="nx"&gt;microFrontendPromise&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nx"&gt;microFrontendPromise&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;System&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="k"&gt;import&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;https://some-bucket.com/chat-micro-fe/main-chat-fe.js&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
      &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;then&lt;/span&gt;&lt;span class="p"&gt;((&lt;/span&gt;&lt;span class="kr"&gt;module&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="p"&gt;...&lt;/span&gt;&lt;span class="kr"&gt;module&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;catch&lt;/span&gt;&lt;span class="p"&gt;((&lt;/span&gt;&lt;span class="nx"&gt;err&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="nx"&gt;microFrontendPromise&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="kc"&gt;null&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
        &lt;span class="k"&gt;throw&lt;/span&gt; &lt;span class="nx"&gt;err&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
      &lt;span class="p"&gt;});&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;

  &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nx"&gt;microFrontendPromise&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;};&lt;/span&gt;


&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Integration and Control by the Main Application&lt;/strong&gt;:
The &lt;code&gt;MicroFrontend&lt;/code&gt; component in the main application uses &lt;code&gt;useEffect&lt;/code&gt; to mount the Micro Frontend upon loading and to unmount it upon removal.&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&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;MicroFrontend&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt; &lt;span class="nx"&gt;containerId&lt;/span&gt; &lt;span class="p"&gt;}:&lt;/span&gt; &lt;span class="nx"&gt;MicroFrontendProps&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nf"&gt;useEffect&lt;/span&gt;&lt;span class="p"&gt;(()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="kd"&gt;let&lt;/span&gt; &lt;span class="na"&gt;microFe&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;MicroFe&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="kc"&gt;undefined&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;loader&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;async &lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="nx"&gt;microFe&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;loadMicroFrontend&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
      &lt;span class="nx"&gt;microFe&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span class="nx"&gt;microFe&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;mount&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;containerId&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="p"&gt;};&lt;/span&gt;
    &lt;span class="nf"&gt;loader&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;microFe&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span class="nx"&gt;microFe&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;unmount&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;containerId&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="p"&gt;},&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;containerId&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;div&lt;/span&gt; &lt;span class="nx"&gt;id&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;containerId&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="sr"&gt;/&amp;gt;&lt;/span&gt;&lt;span class="err"&gt;;
&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;


&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Handling Shared Dependencies&lt;/strong&gt;:
The main application's HTML document provides shared dependencies through a &lt;code&gt;systemjs-importmap&lt;/code&gt;.&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight html"&gt;&lt;code&gt;

&lt;span class="cp"&gt;&amp;lt;!DOCTYPE html&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;html&lt;/span&gt; &lt;span class="na"&gt;lang=&lt;/span&gt;&lt;span class="s"&gt;"en"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;head&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;script &lt;/span&gt;&lt;span class="na"&gt;type=&lt;/span&gt;&lt;span class="s"&gt;"systemjs-importmap"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
    &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;imports&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="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="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;/react.development.js&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;react-dom&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;/react-dom.development.js&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;@mui/material&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;/material-ui.production.min.js&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;
      &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;/script&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;/head&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;body&amp;gt;&lt;/span&gt;
  ...
&lt;span class="nt"&gt;&amp;lt;/body&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;/html&amp;gt;&lt;/span&gt;


&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;As always, I'm grateful for any feedback.&lt;/p&gt;

&lt;p&gt;Cheers,&lt;br&gt;
Hamed&lt;/p&gt;

</description>
      <category>javascript</category>
      <category>webdev</category>
      <category>programming</category>
      <category>react</category>
    </item>
    <item>
      <title>Delete-me</title>
      <dc:creator>Hamed Fatehi</dc:creator>
      <pubDate>Wed, 11 Oct 2023 21:40:33 +0000</pubDate>
      <link>https://dev.to/hamed-fatehi/confrontend-a-journey-through-modern-web-development-feedback-welcome-1ie3</link>
      <guid>https://dev.to/hamed-fatehi/confrontend-a-journey-through-modern-web-development-feedback-welcome-1ie3</guid>
      <description>&lt;p&gt;Delete-me&lt;/p&gt;

</description>
    </item>
    <item>
      <title>CSS-in-JS: Comparing compile-time and runtime approaches</title>
      <dc:creator>Hamed Fatehi</dc:creator>
      <pubDate>Fri, 12 May 2023 15:19:16 +0000</pubDate>
      <link>https://dev.to/hamed-fatehi/css-in-js-comparing-compile-time-and-runtime-approaches-51bn</link>
      <guid>https://dev.to/hamed-fatehi/css-in-js-comparing-compile-time-and-runtime-approaches-51bn</guid>
      <description>&lt;p&gt;Integrating CSS into JavaScript, also known as CSS-in-JS, has become an increasingly popular approach in web development in recent years. Styles are defined directly within JavaScript code. In the context of CSS-in-JS, run-time methods generate styles at application runtime, while compile-time methods generate styles during the build process. &lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight html"&gt;&lt;code&gt;

// linaria (Compile Time CSS extraction):
&lt;span class="nt"&gt;&amp;lt;style &lt;/span&gt;&lt;span class="na"&gt;type=&lt;/span&gt;&lt;span class="s"&gt;"text/css"&lt;/span&gt; &lt;span class="na"&gt;data-vite-dev-id=&lt;/span&gt;&lt;span class="s"&gt;"/src/App_1k77ml9.css"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
    &lt;span class="nc"&gt;.t1uehvp8&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="nl"&gt;color&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="n"&gt;var&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;--t1uehvp8-0&lt;/span&gt;&lt;span class="p"&gt;);}&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;/style&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;h1&lt;/span&gt; &lt;span class="na"&gt;class=&lt;/span&gt;&lt;span class="s"&gt;"t1uehvp8"&lt;/span&gt; &lt;span class="na"&gt;style=&lt;/span&gt;&lt;span class="s"&gt;"--t1uehvp8-0:#0f0;"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
    Hello World!
&lt;span class="nt"&gt;&amp;lt;/h1&amp;gt;&lt;/span&gt;


&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;In the compile-time approach (here Linaria), the CSS code is generated and extracted during the build process. The resulting CSS class (here &lt;code&gt;.t1uehvp8&lt;/code&gt;) is inserted into the HTML code in the &lt;code&gt;&amp;lt;style&amp;gt;&lt;/code&gt; tag, while the component is given a class with the generated class name. A custom CSS variable (here &lt;code&gt;--t1uehvp8-0&lt;/code&gt;) is also used here to enable dynamic values.&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight html"&gt;&lt;code&gt;

// styled-components (Runtime Styling)
&lt;span class="nt"&gt;&amp;lt;style &lt;/span&gt;&lt;span class="na"&gt;data-styled=&lt;/span&gt;&lt;span class="s"&gt;"active"&lt;/span&gt; &lt;span class="na"&gt;data-styled-version=&lt;/span&gt;&lt;span class="s"&gt;"5.3.10"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
    &lt;span class="nc"&gt;.bpatyH&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="nl"&gt;color&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="m"&gt;#f00&lt;/span&gt;&lt;span class="p"&gt;;}&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;/style&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;h1&lt;/span&gt; &lt;span class="na"&gt;color=&lt;/span&gt;&lt;span class="s"&gt;"#f00"&lt;/span&gt; &lt;span class="na"&gt;class=&lt;/span&gt;&lt;span class="s"&gt;"sc-bgqQcB bpatyH"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
    Hello World !
&lt;span class="nt"&gt;&amp;lt;/h1&amp;gt;&lt;/span&gt;


&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;In contrast, the runtime approach (styled components here) generates the CSS code at runtime of the application. The resulting CSS class (here .sc-bgqQcB bpatyH) is dynamically created and assigned to the component. The CSS code is not pre-inserted in the HTML code, it is added at runtime. (for this example I set SC_DISABLE_SPEEDY = true so that the styles are visible in the DOM. &lt;a href="https://stackoverflow.com/questions/53486470/react-styled-components-stripped-out-from-production-build" rel="noopener noreferrer"&gt;More about speedy mode&lt;/a&gt; )&lt;/p&gt;

&lt;h2&gt;
  
  
  Benefits of CSS-in-JS
&lt;/h2&gt;

&lt;p&gt;Before we dive into comparing runtime and compile-time approaches, let me first explain the general benefits of CSS-in-JS.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Encapsulation (Scoped CSS):&lt;/strong&gt; CSS-in-JS allows for the isolation of styles at the component level, reducing the risk of style conflicts and unwanted side effects.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Dynamic styling:&lt;/strong&gt; Because styles are defined directly in JavaScript, they can be easily created dynamically and changed based on application data or user interaction.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Ease of maintenance:&lt;/strong&gt; The tight coupling of components and their associated styles makes it easier to find and update styles, especially in larger projects.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Dead Code Elimination:&lt;/strong&gt; With CSS-in-JS, only the CSS code that is actually used is included in the application, which leads to a reduction in unused code and better performance.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Component-based design (colocation):&lt;/strong&gt; Integrating styles into JavaScript components encourages the development of modular and reusable user interfaces.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Advantages of runtime solution
&lt;/h2&gt;

&lt;p&gt;Here I use Styled-Components as an example. But most of the similar libraries share these properties. I'm just listing the benefits. For more information see the &lt;a href="https://styled-components.com/docs/basics" rel="noopener noreferrer"&gt;Styled-Components documentation.&lt;/a&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Automatically critical CSS&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;No class name bug&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Easier deletion of CSS&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Simple dynamic styling&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Painless maintenance&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Automatic vendor prefixing&lt;/strong&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;But like (almost) everything else in life, good things come at a price.&lt;/p&gt;

&lt;h2&gt;
  
  
  Welcome to the Dark Side
&lt;/h2&gt;

&lt;p&gt;I read this article a while ago:&lt;a href="https://dev.to/srmagura/why-were-breaking-up-wiht-css-in-js-4g9b"&gt; Why We're Breaking Up with CSS-in-JS &lt;/a&gt;. It was written by the developer of Emotion (Emotion is runtime like styled-components). In short, the author calls the following disadvantages:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;CSS-in-JS increases run-time overhead:&lt;/strong&gt; when components are rendered, the CSS-in-JS libraries have to convert their styles into plain CSS that can be injected into the document. This consumes additional CPU cycles and can affect the performance of your application.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;CSS-in-JS increases the size of your bundle:&lt;/strong&gt; Every user who visits your website must now download the JavaScript for the CSS-in-JS library. Emotion is 7.9 kB minzipped and Styled-Components is 12.7 kB. Both libraries aren't huge, but it adds up.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Frequently injecting CSS rules forces the browser to do a lot of extra work:&lt;/strong&gt; the runtime CSS-in-JS libraries work by injecting new style rules when components are rendered, and at a fundamental level this is bad for performance&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;CSS-in-JS confuses the React DevTools:&lt;/strong&gt; for each element using the CSS property renders emotion &lt;code&gt;&amp;lt;EmotionCssPropInternal&amp;gt;&lt;/code&gt; and &lt;code&gt;&amp;lt;Insertion&amp;gt;&lt;/code&gt; components. If you use the CSS property on many elements, Emotion's internal components can mess up the React DevTools.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;In the end, the author suggests using Sass modules and utility classes instead, as the runtime performance cost of Emotion far outweighs the developer experience (DX) benefits.&lt;/p&gt;

&lt;p&gt;There is also &lt;a href="https://pustelto.com/blog/css-vs-css-in-js-perf/#network-comparison" rel="noopener noreferrer"&gt;a nice article&lt;/a&gt; that compares CSS and CSS-in-JS in a real application. Let's look at some charts from this article:&lt;/p&gt;

&lt;p&gt;Lighthouse performance audit:&lt;br&gt;
&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fdsz8ancvzj7n6xpuqsz5.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fdsz8ancvzj7n6xpuqsz5.png" alt="Lighthouse performance audit"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Performance profiling:&lt;br&gt;
&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fsa8a29mo2acd2vcmn4au.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fsa8a29mo2acd2vcmn4au.png" alt="Performance profiling"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;I also created a &lt;a href="https://github.com/Confrontend/styling-test" rel="noopener noreferrer"&gt;dummy react app&lt;/a&gt; that renders 3000 colored boxes and 3000 colored short texts. In this app, you can change the theme with a click of a button. Below is the interactivity test of Linaria (a compile time library) and styled components. The test was recorded when you click the "Theme change" button. The result shows a dramatic difference in performance. But as you know, this was an exaggerated example to show the difference. &lt;/p&gt;

&lt;p&gt;Styled-Component (Runtime-Time CSS-in-JS) Interaction duration : 3.312 ms&lt;br&gt;
&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Ft5iewwdsbm42dkwnzbfe.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Ft5iewwdsbm42dkwnzbfe.png" alt="Styled-Component (Runtime-Time CSS-in-JS) Interaction duration : 3.312 ms"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Linaria (Compile-Time CSS-in-JS) Interaction duration : 528 ms&lt;br&gt;
&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fscrwv6bvqk8lvokspy0p.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fscrwv6bvqk8lvokspy0p.png" alt="Linaria (Compile-Time CSS-in-JS) Interaction duration : 528 ms"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Compile-time CSS-in-JS
&lt;/h2&gt;

&lt;p&gt;Compile-time CSS-in-JS tools like Linaria offer an intermediate solution between pure CSS-based solutions and runtime CSS-in-JS approaches. Linaria combines the best of both approaches by generating the CSS classes at compile time and extracting them into separate CSS files instead of generating them at runtime. This makes it possible to avoid the performance penalties of runtime CSS-in-JS solutions while retaining the benefits of component isolation and dynamic style matching.&lt;/p&gt;

&lt;p&gt;Advantages are:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;No Runtime Overhead:&lt;/strong&gt; Compile-time CSS-in-JS solutions generate static CSS, eliminating the need for JavaScript to handle styles at runtime. This reduces CPU load and improves performance.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Smaller bundle size:&lt;/strong&gt; Since the CSS code is extracted at compile time, no additional JavaScript library is required at runtime. This results in a smaller bundle size and faster loading times.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Cleaner React DevTools:&lt;/strong&gt; Since the styles are extracted into static CSS and no additional components are created at runtime, the React DevTools view remains tidy and uncluttered.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Optimum browser performance:&lt;/strong&gt; Static CSS extraction prevents the browser from constantly having to calculate new CSS rules, since the styles are already generated at compile time. This leads to better browser performance.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Simplified Server-Side Rendering (SSR):&lt;/strong&gt; Since the CSS code is static, there are fewer problems using SSR. Static extraction avoids potential complications that might arise with dynamic CSS-in-JS solutions.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Improved browser caching:&lt;/strong&gt; Since the extracted style files are separate, they can be cached more effectively by the browser. Even if the JavaScript changes, the static CSS files can still remain in the cache, resulting in faster load times and a better user experience.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  What about SSR (Server Side Rendering)?
&lt;/h2&gt;

&lt;p&gt;Almost all &lt;a href="https://css-tricks.com/a-thorough-analysis-of-css-in-js/#aa-ssr-server-side-rendering" rel="noopener noreferrer"&gt;CSS-in-JS libraries support SSR &lt;/a&gt;, even the compile-time libraries. For example, &lt;a href="https://styled-components.com/docs/advanced#server-side-rendering" rel="noopener noreferrer"&gt;Styled-Components uses ServerStyleSheet&lt;/a&gt; to generate critical css on the server, which can be made available to the client in a blocking request. This avoids the Flash of Unstyled Content (FOUC). &lt;/p&gt;

&lt;p&gt;This screenshot from a NextJS application using styled components with ServerStyleSheet shows how style tags are extracted and made available to the client:&lt;/p&gt;

&lt;p&gt;Styled components with ServerStyleSheet:&lt;br&gt;
&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fg1j0l6laurds0pljpjy3.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fg1j0l6laurds0pljpjy3.png" alt="styled components with ServerStyleSheet"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;This feature could, to some extent, compensate for the lack of generated CSS at compile time. A major benefit of extracted CSS before runtime is that you can use tools like &lt;a href="https://github.com/addyosmani/critical" rel="noopener noreferrer"&gt;critical&lt;/a&gt; or &lt;a href="https://github.com/pocketjoso/penthouse" rel="noopener noreferrer"&gt;penthouse&lt;/a&gt; to automatically extract the critical CSS (above the fold) and serve only that style via a blocking request, while the rest asynchronously in the background is loaded. &lt;/p&gt;

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

&lt;p&gt;The following points are the most important findings:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;CSS-in-JS compile-time methods seem to perform better, especially on low-powered devices.&lt;/li&gt;
&lt;li&gt;The migration from a runtime to a compile-time solution can take place step by step and component by component. Tools like Linaria provide syntax similar to SC to smooth the way for migration.&lt;/li&gt;
&lt;li&gt;One should only switch from the build-time to the compile-time solution when performance becomes a bottleneck. In many cases, end users may not notice the improvements.&lt;/li&gt;
&lt;li&gt;Compile-time solutions require requests to get the style files. Therefore, it is important to think about a good caching mechanism. This is especially important on first-time visits, as there is no cache for style files in the browser.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Side note:&lt;/strong&gt; This text focused on CSS-in-JS. Of course there are many other tools like utility first classes (e.g. Tailwind) that don't involve JS in styling. Other frameworks like Angular also take a similar approach, combining Sass and component-level styling. From experience I can say CSS-in-JS provides better DX. Writing complex logic in Scss could be much harder than doing it in JS. But again, in your case the styling might not need such level of dynamics. &lt;/p&gt;

&lt;p&gt;Styling in general is evolving, and there are many ways of thinking. Let me know what tools you use in your projects. 😇&lt;/p&gt;

&lt;p&gt;Thank you for reading and, as always, I appreciate your feedback. 🥳&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Cover Photo: Dall-E (Oil pastel drawing of 2 aliens putting makeup on each other)&lt;/em&gt;&lt;/p&gt;

</description>
      <category>react</category>
      <category>css</category>
      <category>javascript</category>
    </item>
    <item>
      <title>When Direct DOM Manipulation Outperforms React State Management</title>
      <dc:creator>Hamed Fatehi</dc:creator>
      <pubDate>Mon, 17 Apr 2023 16:22:00 +0000</pubDate>
      <link>https://dev.to/hamed-fatehi/when-direct-dom-manipulation-outperforms-react-state-management-3l10</link>
      <guid>https://dev.to/hamed-fatehi/when-direct-dom-manipulation-outperforms-react-state-management-3l10</guid>
      <description>&lt;p&gt;Introduction:&lt;/p&gt;

&lt;p&gt;Optimizing performance is a critical aspect of developing web applications with React. To demonstrate various techniques for improving React performance, we'll use a scroll progress bar as a real-world example. In this article, we'll explore three different approaches to implementing a scroll progress bar. We start with the worst and move are way up to the most performant approach.&lt;/p&gt;

&lt;h2&gt;
  
  
  1.The Ugly Way:
&lt;/h2&gt;

&lt;p&gt;In this initial approach, we place the scroll logic directly in the parent component and use useState. Although this may seem straightforward, it can lead to unnecessary re-renders of the parent component and its children.&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;// ParentComponent.js&lt;/span&gt;
&lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;ParentComponent&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;scrollProgress&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;setScrollProgress&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="mi"&gt;0&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;handleScroll&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;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;scrollTop&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nb"&gt;document&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;documentElement&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;scrollTop&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;windowHeight&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nb"&gt;window&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;innerHeight&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;docHeight&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nb"&gt;document&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;documentElement&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;scrollHeight&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt; &lt;span class="nx"&gt;windowHeight&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;scrollPercentage&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;scrollTop&lt;/span&gt; &lt;span class="o"&gt;/&lt;/span&gt; &lt;span class="nx"&gt;docHeight&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="mi"&gt;100&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="nf"&gt;setScrollProgress&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;scrollPercentage&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="p"&gt;};&lt;/span&gt;

  &lt;span class="nf"&gt;useEffect&lt;/span&gt;&lt;span class="p"&gt;(()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Parent component rendered&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="nb"&gt;window&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;addEventListener&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;scroll&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;handleScroll&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="nb"&gt;window&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;removeEventListener&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;scroll&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;handleScroll&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="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;Parent&lt;/span&gt; &lt;span class="nx"&gt;Component&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;ProgressBar&lt;/span&gt; &lt;span class="nx"&gt;progress&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;scrollProgress&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="nx"&gt;ChildComponent&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;/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;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;ChildComponent&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Child component rendered&lt;/span&gt;&lt;span class="dl"&gt;"&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;p&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="nx"&gt;Child&lt;/span&gt; &lt;span class="nx"&gt;Component&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="sr"&gt;/p&amp;gt;&lt;/span&gt;&lt;span class="err"&gt;;
&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;In this example, every time the user scrolls, the parent component and its children are re-rendered.&lt;/p&gt;

&lt;h2&gt;
  
  
  2. The Bad Way:
&lt;/h2&gt;

&lt;p&gt;A better approach is to encapsulate the scroll logic and state within a separate ScrollProgressBar component. By doing so, we isolate the re-rendering of the progress bar from the rest of the application.&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;// ScrollProgressBar.js&lt;/span&gt;
&lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;ScrollProgressBar&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;scrollProgress&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;setScrollProgress&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="mi"&gt;0&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;handleScroll&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;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="c1"&gt;// ... same as the previous example&lt;/span&gt;
  &lt;span class="p"&gt;};&lt;/span&gt;

  &lt;span class="nf"&gt;useEffect&lt;/span&gt;&lt;span class="p"&gt;(()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;ScrollProgressBar rendered&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="c1"&gt;// ... same as the previous example&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="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;ProgressBar&lt;/span&gt; &lt;span class="nx"&gt;progress&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;scrollProgress&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="sr"&gt;/&amp;gt;&lt;/span&gt;&lt;span class="err"&gt;;
&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="c1"&gt;// ParentComponent.js&lt;/span&gt;
&lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;ParentComponent&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Parent component rendered&lt;/span&gt;&lt;span class="dl"&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;Parent&lt;/span&gt; &lt;span class="nx"&gt;Component&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;ScrollProgressBar&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;ChildComponent&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;/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;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;ChildComponent&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Child component rendered&lt;/span&gt;&lt;span class="dl"&gt;"&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;p&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="nx"&gt;Child&lt;/span&gt; &lt;span class="nx"&gt;Component&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="sr"&gt;/p&amp;gt;&lt;/span&gt;&lt;span class="err"&gt;;
&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Although this method eliminates the unnecessary re-renderings of unrelated components (specially when they are not memoized), still each scroll event triggers a re-render of the ScrollProgressBar component itself, which could be avoided. See the last part to find out how:&lt;/p&gt;

&lt;h2&gt;
  
  
  3. The Good Way:
&lt;/h2&gt;

&lt;p&gt;The most performant approach is to directly manipulate the DOM without using useState. This eliminates unnecessary re-rendering altogether.&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;// ScrollProgressBar.js&lt;/span&gt;
&lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;ScrollProgressBar&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt; &lt;span class="nx"&gt;color&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;progressRef&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;useRef&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="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;ScrollProgressBar mounted&lt;/span&gt;&lt;span class="dl"&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;progressBarRef&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;current&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="kc"&gt;null&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;handleScroll&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;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;scrollTop&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nb"&gt;document&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;documentElement&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;scrollTop&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;windowHeight&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nb"&gt;window&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;innerHeight&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;docHeight&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nb"&gt;document&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;documentElement&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;scrollHeight&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt; &lt;span class="nx"&gt;windowHeight&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;scrollPercentage&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;scrollTop&lt;/span&gt; &lt;span class="o"&gt;/&lt;/span&gt; &lt;span class="nx"&gt;docHeight&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="mi"&gt;100&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
        &lt;span class="nx"&gt;progressRef&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;current&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;style&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;width&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;`&lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;scrollPercentage&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="nb"&gt;window&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;addEventListener&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;scroll&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;handleScroll&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="nb"&gt;window&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;removeEventListener&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;scroll&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;handleScroll&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="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;div&lt;/span&gt;
      &lt;span class="nx"&gt;ref&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;progressRef&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;
      &lt;span class="nx"&gt;style&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;{{&lt;/span&gt; &lt;span class="na"&gt;width&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;0%&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="na"&gt;height&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;5px&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="na"&gt;backgroundColor&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;color&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="p"&gt;}&lt;/span&gt;

&lt;span class="c1"&gt;// ParentComponent.js&lt;/span&gt;
&lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;ParentComponent&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Parent component rendered&lt;/span&gt;&lt;span class="dl"&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;Parent&lt;/span&gt; &lt;span class="nx"&gt;Component&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;ScrollProgressBar&lt;/span&gt; &lt;span class="nx"&gt;color&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;red&lt;/span&gt;&lt;span class="dl"&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;ChildComponent&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;/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;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;ChildComponent&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Child component rendered&lt;/span&gt;&lt;span class="dl"&gt;"&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;p&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="nx"&gt;Child&lt;/span&gt; &lt;span class="nx"&gt;Component&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="sr"&gt;/p&amp;gt;&lt;/span&gt;&lt;span class="err"&gt;;
&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;In this final example, the ScrollProgressBar component's DOM is manipulated directly, avoiding unnecessary re-renders. The console.log statements show that the parent and child components are not re-rendered during scrolling, ensuring optimal performance.&lt;/p&gt;

&lt;p&gt;Conclusion:&lt;/p&gt;

&lt;p&gt;It's essential to keep in mind that while React's state management is convenient and powerful, there are situations where direct DOM manipulation can lead to better performance, especially when dealing with frequently updating elements and heavy parent components with complex logic. Always consider the trade-offs between convenience and performance when deciding on an approach to optimize your application.&lt;/p&gt;

</description>
      <category>react</category>
      <category>performance</category>
      <category>javascript</category>
      <category>frontend</category>
    </item>
    <item>
      <title>A Developer's Guide to Mastering SEO [Part 1]- Title, Description, Canonical &amp; Robots Tags</title>
      <dc:creator>Hamed Fatehi</dc:creator>
      <pubDate>Mon, 17 Apr 2023 11:30:34 +0000</pubDate>
      <link>https://dev.to/hamed-fatehi/a-developers-guide-to-mastering-seo-part-1-title-description-canonical-robots-tags-1p1n</link>
      <guid>https://dev.to/hamed-fatehi/a-developers-guide-to-mastering-seo-part-1-title-description-canonical-robots-tags-1p1n</guid>
      <description>&lt;p&gt;&lt;strong&gt;Introduction:&lt;/strong&gt; As a developer, understanding and implementing essential SEO tags is crucial for improving a website's visibility and performance in search engine results. In this article, we will delve into four key tags: Title, Meta Description, Canonical, and Robots Meta, explaining their purpose, how they contribute to SEO, and providing examples for each.&lt;/p&gt;

&lt;h2&gt;
  
  
  Title-Tag
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;Why it exists:&lt;/strong&gt; The title tag defines the title of a webpage, which is displayed in search engine results pages (SERPs) and browser tabs. It is a critical element for both user experience and SEO, as it gives users and search engines a concise summary of the page's content.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;How it helps SEO:&lt;/strong&gt; A well-crafted title tag improves click-through rates, as users are more likely to click on a result with a relevant and engaging title. Additionally, search engines use title tags to understand the topic and context of a page, which can influence rankings.&lt;/p&gt;

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

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;&amp;lt;head&amp;gt;
  &amp;lt;title&amp;gt;Web Development Tips &amp;amp; Best Practices | YourSite&amp;lt;/title&amp;gt;
&amp;lt;/head&amp;gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Meta-Description
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;Why it exists:&lt;/strong&gt; The meta description tag provides a brief summary of a webpage's content, which is displayed below the title in SERPs. This summary helps users determine the relevance of the page to their query.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;How it helps SEO:&lt;/strong&gt; While meta descriptions are not a direct ranking factor, they can significantly impact click-through rates. An informative and enticing description can attract more clicks, signalling to search engines that the page is relevant and valuable to users.&lt;/p&gt;

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

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;&amp;lt;head&amp;gt;
  &amp;lt;meta name="description" content="Discover the latest web development tips, best practices, and expert advice to help you create user-friendly, responsive, and SEO-friendly websites."&amp;gt;
&amp;lt;/head&amp;gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Canonical-Tag
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;Why it exists:&lt;/strong&gt; The canonical tag is used to indicate the preferred version of a webpage when multiple versions exist. This can help prevent duplicate content issues, which can dilute the value of the original content and confuse search engines.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;How it helps SEO:&lt;/strong&gt; By specifying a canonical URL, you help search engines consolidate the link equity of various versions of a page, which can improve the ranking of the preferred version. It also ensures that search engines index and display the correct version in SERPs.&lt;/p&gt;

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

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;&amp;lt;head&amp;gt;
  &amp;lt;link rel="canonical" href="https://www.yoursite.com/blog/web-development-tips"&amp;gt;
&amp;lt;/head&amp;gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Canonical tags are important for SEO because Google doesn’t like duplicate content. It makes it harder for them to choose which version of a page to index and rank, and where to consolidate any “link equity.” Too much duplicate content can also affect your “crawl budget”.&lt;/p&gt;

&lt;h2&gt;
  
  
  Robots-Meta-Tag
&lt;/h2&gt;

&lt;p&gt;Why it exists: The Robots Meta Tag provides instructions to search engine crawlers on how to handle the indexing and following of links on a webpage. This tag is particularly useful for managing crawl budgets, preventing sensitive or duplicate content from being indexed, and controlling how search engines interact with your site.&lt;/p&gt;

&lt;h3&gt;
  
  
  Robots Meta Tag Attributes
&lt;/h3&gt;

&lt;p&gt;There are several key attributes that can be used within the Robots Meta Tag to guide search engine behavior:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;- index / noindex:&lt;/strong&gt;&lt;br&gt;
 These directives determine whether search engines should index a page or not. By default, all pages are assumed to be indexable unless specified otherwise using the "noindex" attribute.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;- follow / nofollow:&lt;/strong&gt;&lt;br&gt;
 These directives control whether search engine crawlers should follow the links on a page. By default, all links are assumed to be followed unless specified otherwise using the "nofollow" attribute.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;- noarchive:&lt;/strong&gt;&lt;br&gt;
 This directive tells search engines not to store a cached copy of the page.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;- nosnippet:&lt;/strong&gt;&lt;br&gt;
 This directive prevents search engines from displaying a text snippet or a video preview in search results.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;- notranslate:&lt;/strong&gt;&lt;br&gt;
 This directive asks search engines not to offer a translated version of the page in search results.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;- noimageindex&lt;/strong&gt;&lt;br&gt;
: This directive tells search engines not to index images on the page. One use case for the noimageindex parameter is when you have images on your website that you do not want to appear in image search results. For example, you might have images that are only relevant to users who are already on your website and would not make sense out of context. By using the noimageindex parameter, you can prevent these images from appearing in image search results and potentially confusing users.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;- unavailable_after:&lt;/strong&gt;&lt;br&gt;
 This directive specifies a date and time after which the page should no longer be indexed.&lt;/p&gt;

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

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;&amp;lt;head&amp;gt;
  &amp;lt;meta name="robots" content="noindex, nofollow, noarchive"&amp;gt;
&amp;lt;/head&amp;gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;In this example, the Robots Meta Tag tells search engines not to index the page, not to follow any links on it, and not to store a cached copy.&lt;/p&gt;

&lt;h3&gt;
  
  
  Implementation Best Practices
&lt;/h3&gt;

&lt;p&gt;Use the Robots Meta Tag when you want to control the indexing and following behavior of specific pages. For broader site-wide rules, consider using a robots.txt file.&lt;/p&gt;

&lt;p&gt;Be cautious when using the "noindex" and "nofollow" directives. Overusing these directives can lead to important content not being indexed or crawled, which can negatively impact your site's search engine performance.&lt;/p&gt;

&lt;p&gt;Combine multiple directives in a single Robots Meta Tag using commas, as shown in the example above.&lt;/p&gt;

&lt;p&gt;Remember that the Robots Meta Tag is not a security measure. While it can prevent certain pages from appearing in search results, it does not guarantee complete privacy. Sensitive content should be protected with appropriate access controls.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Read more:&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://developers.google.com/search/docs/advanced/robots/robots_meta_tag"&gt;Google Search Central. (n.d.). Robots meta tag, data-nosnippet, and X-Robots-Tag specifications.&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://moz.com/learn/seo/robots-meta-directives"&gt;Moz. (n.d.). Meta Robots Tag: An SEO Guide to Using the Robots Meta Tag.&lt;/a&gt; &lt;/p&gt;

&lt;p&gt;&lt;a href="https://yoast.com/robots-meta-tags/"&gt;Yoast. The ultimate guide to the meta robots tag.&lt;/a&gt; &lt;/p&gt;

&lt;p&gt;&lt;a href="https://ahrefs.com/blog/canonical-tags/"&gt;ahrefs. Canonical Tags: A Simple Guide for Beginners&lt;/a&gt;&lt;/p&gt;

</description>
      <category>seo</category>
      <category>html</category>
    </item>
    <item>
      <title>Project-Level Security: Leveraging Local Git Config and Dedicated SSH Keys for Multiple Repositories</title>
      <dc:creator>Hamed Fatehi</dc:creator>
      <pubDate>Tue, 11 Apr 2023 18:58:47 +0000</pubDate>
      <link>https://dev.to/hamed-fatehi/project-level-security-leveraging-local-git-config-and-dedicated-ssh-keys-for-multiple-repositories-5254</link>
      <guid>https://dev.to/hamed-fatehi/project-level-security-leveraging-local-git-config-and-dedicated-ssh-keys-for-multiple-repositories-5254</guid>
      <description>&lt;p&gt;Developing multiple projects often requires the use of different Git repositories. As a developer, you might have access to various repositories, each with different access levels and security requirements. In such cases, it's essential to maintain a secure and organized development environment. One way to achieve this is by using a separate SSH private key for each repository and configuring local Git config files accordingly.&lt;/p&gt;

&lt;p&gt;When each repository has its dedicated SSH key, it becomes easier to manage access rights. Revoking or granting access to a specific repository can be achieved by simply managing the corresponding SSH key.&lt;/p&gt;

&lt;p&gt;Configuring Local Git Config for Each Repository:&lt;/p&gt;

&lt;p&gt;To set up a dedicated SSH key for each repository, you need to create and configure the local Git config file for each project. The local Git config file, located at &lt;code&gt;.git/config&lt;/code&gt; within the repository, contains repository-specific settings. Here's how to configure the local Git config file to use a separate SSH private key for each repository:&lt;/p&gt;

&lt;p&gt;Generate a new SSH key pair for each repository you want to secure:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;$ ssh-keygen -t rsa -b 4096 -C "your_email@example.com" -f /path/to/your/private_key
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Add the generated public key to the corresponding repository's SSH settings.&lt;/p&gt;

&lt;p&gt;Configure the local Git config file for each project by adding the following lines to the .git/config file:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;[core]
  sshCommand = "ssh -i /path/to/your/private_key"
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;You can also set the core.sshCommand configuration for a specific repository via the terminal using the following command:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;git config core.sshCommand "ssh -i /path/to/your/private_key"
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The sshCommand directive specifies the path to the private key associated with the repository. Replace &lt;code&gt;/path/to/your/private_key&lt;/code&gt; with the actual path to the private key you generated in step 1.&lt;/p&gt;

&lt;p&gt;Save the changes to the local Git config file.&lt;br&gt;
Now, when you interact with the repository (e.g., git pull, git push), Git will use the specified private key for authentication, ensuring that each repository has its dedicated SSH key.&lt;/p&gt;

&lt;p&gt;Conclusion:&lt;/p&gt;

&lt;p&gt;By using dedicated SSH keys for each Git repository and configuring the local Git config file accordingly, you can improve your development environment's security and organization. This approach simplifies access management and makes it easier to troubleshoot authentication issues. As a result, you can focus on your development tasks with confidence, knowing that your repositories are secure and well-organized.&lt;/p&gt;

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