<?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: okmttdhr</title>
    <description>The latest articles on DEV Community by okmttdhr (@okmttdhr).</description>
    <link>https://dev.to/okmttdhr</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%2F42234%2Fee13a45e-3fca-4970-a5ff-846b279f46d5.jpg</url>
      <title>DEV Community: okmttdhr</title>
      <link>https://dev.to/okmttdhr</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/okmttdhr"/>
    <language>en</language>
    <item>
      <title>What is "Lane" in React?</title>
      <dc:creator>okmttdhr</dc:creator>
      <pubDate>Thu, 15 Jul 2021 00:49:54 +0000</pubDate>
      <link>https://dev.to/okmttdhr/what-is-lane-in-react-4np7</link>
      <guid>https://dev.to/okmttdhr/what-is-lane-in-react-4np7</guid>
      <description>&lt;p&gt;A concept called "Lane" is used inside React.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://github.com/facebook/react/pull/18796"&gt;Initial Lanes implementation by acdlite · Pull Request #18796 · facebook/react&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;React 18 alpha was recently released, and many of the concurrent features are based on the Lane.&lt;/p&gt;

&lt;p&gt;Lane is a 32-bit representation of a task at reconcile time, and the actual code for Lane is as follows;&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;// https://github.com/facebook/react/blob/9212d994ba939f20a04220a61e9776b488381596/packages/react-reconciler/src/ReactFiberLane.new.js&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;NoLane&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;Lane&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mb"&gt;0b0000000000000000000000000000000&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;SyncLane&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;Lane&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mb"&gt;0b0000000000000000000000000000001&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;TransitionLanes&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;Lanes&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mb"&gt;0b0000000001111111111111111000000&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;IdleLane&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;Lanes&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mb"&gt;0b0100000000000000000000000000000&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;OffscreenLane&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;Lane&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mb"&gt;0b1000000000000000000000000000000&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;As you can see, lanes exist for each type of task, with the exception of NoLane (when there is no task), but basically lanes with higher priority are represented by smaller numbers.&lt;/p&gt;

&lt;p&gt;By using 32 bits, bitmask can be used to manipulate lanes. For example, if multiple lanes are bitmasked into one lane, there is no need to compare all lanes relative to each other, which simplifies implementation and saves memory.&lt;/p&gt;

&lt;p&gt;Let's take a look at the actual function that performs bitmasking.&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;export&lt;/span&gt; &lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nx"&gt;mergeLanes&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;a&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;Lanes&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="nx"&gt;Lane&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;b&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;Lanes&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="nx"&gt;Lane&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt; &lt;span class="nx"&gt;Lanes&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;a&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="nx"&gt;b&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 function, as the name suggests, merges lanes and returns them. For example, it can be used as follows.&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="nx"&gt;mergeLanes&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
  &lt;span class="nx"&gt;NoLane&lt;/span&gt; &lt;span class="cm"&gt;/*0b0000000000000000000000000000000*/&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="nx"&gt;OffscreenLane&lt;/span&gt; &lt;span class="cm"&gt;/*0b1000000000000000000000000000000*/&lt;/span&gt;
&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="c1"&gt;// =&amp;gt; 0b1000000000000000000000000000000&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;In the above example, a Lane with no tasks (NoLane) is updated to an OffscreenLane. Since Lanes are attached to Fiber, we can update the Lane of the target Fiber as follows.&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="nx"&gt;fiber&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;lanes&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;mergeLanes&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
  &lt;span class="nx"&gt;fiber&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;lanes&lt;/span&gt; &lt;span class="cm"&gt;/* NoLane */&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; 
  &lt;span class="nx"&gt;OffscreenLane&lt;/span&gt;
&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="c1"&gt;// =&amp;gt; OffscreenLane&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Let's take another look at the function &lt;code&gt;isSubsetOfLanes&lt;/code&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;export&lt;/span&gt; &lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nx"&gt;isSubsetOfLanes&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kd"&gt;set&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;Lanes&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;subset&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;Lanes&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="kd"&gt;set&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&lt;/span&gt; &lt;span class="nx"&gt;subset&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;===&lt;/span&gt; &lt;span class="nx"&gt;subset&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 function returns whether or not the result of the AND operation of Lane matches the subset. It is not clear what makes it useful, so I will try to write some more specific patterns.&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="nx"&gt;isSubsetOfLanes&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
  &lt;span class="nx"&gt;NonIdleLanes&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="cm"&gt;/*0b0001111111111111111111111111111*/&lt;/span&gt;
  &lt;span class="nx"&gt;SyncLane&lt;/span&gt; &lt;span class="cm"&gt;/*0b0000000000000000000000000000001*/&lt;/span&gt;
&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="c1"&gt;// =&amp;gt; true. SyncLane is not Idle task&lt;/span&gt;

&lt;span class="nx"&gt;isSubsetOfLanes&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
  &lt;span class="nx"&gt;NonIdleLanes&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="cm"&gt;/*0b0001111111111111111111111111111*/&lt;/span&gt;
  &lt;span class="nx"&gt;OffscreenLane&lt;/span&gt; &lt;span class="cm"&gt;/*0b1000000000000000000000000000000*/&lt;/span&gt;
&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="c1"&gt;// =&amp;gt; false. OffscreenLane is Idle task&lt;/span&gt;

&lt;span class="nx"&gt;isSubsetOfLanes&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
  &lt;span class="nx"&gt;TransitionLanes&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="cm"&gt;/*0b0000000001111111111111111000000*/&lt;/span&gt;
  &lt;span class="nx"&gt;TransitionLane1&lt;/span&gt; &lt;span class="cm"&gt;/*0b0000000000000000000000001000000*/&lt;/span&gt;
&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="c1"&gt;// =&amp;gt; true. TransitionLane1 is included in TransitionLanes&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;As mentioned above, &lt;code&gt;isSubsetOfLanes&lt;/code&gt; allows you to determine if the corresponding Lane is a subset of the target Fiber. &lt;/p&gt;

&lt;p&gt;For example, there is a function &lt;code&gt;scheduleWorkOnParentPath&lt;/code&gt;. This function, roughly speaking, is responsible for notifying the upper level parent that the lower level child has a task.&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;// https://github.com/facebook/react/blob/a8964649bb6332cf1f8d723f81ce97cc5a1886ff/packages/react-reconciler/src/ReactFiberNewContext.new.js#L142&lt;/span&gt;
&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nx"&gt;scheduleWorkOnParentPath&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
  &lt;span class="nx"&gt;parent&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;Fiber&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="nx"&gt;renderLanes&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;Lanes&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="c1"&gt;// Update the child lanes of all the ancestors, including the alternates.&lt;/span&gt;
  &lt;span class="kd"&gt;let&lt;/span&gt; &lt;span class="nx"&gt;node&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;parent&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="k"&gt;while&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;node&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="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;alternate&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;node&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;alternate&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;isSubsetOfLanes&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;node&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;childLanes&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;renderLanes&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="nx"&gt;node&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;childLanes&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;mergeLanes&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;node&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;childLanes&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;renderLanes&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;alternate&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="nx"&gt;alternate&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;childLanes&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;mergeLanes&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;alternate&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;childLanes&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;renderLanes&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;else&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;alternate&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;&amp;amp;&amp;amp;&lt;/span&gt;
      &lt;span class="o"&gt;!&lt;/span&gt;&lt;span class="nx"&gt;isSubsetOfLanes&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;alternate&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;childLanes&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;renderLanes&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;alternate&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;childLanes&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;mergeLanes&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;alternate&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;childLanes&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;renderLanes&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="c1"&gt;// Neither alternate was updated, which means the rest of the&lt;/span&gt;
      &lt;span class="c1"&gt;// ancestor path already has sufficient priority.&lt;/span&gt;
      &lt;span class="k"&gt;break&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="nx"&gt;node&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;node&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="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Here, &lt;code&gt;node.return&lt;/code&gt; is the Fiber of a parent or multiple parents, so you can see that it is a function that updates childLanes by following the path of the parent in order. For example, it can be used to tell the parent when the React.Context is updated in children.&lt;/p&gt;

&lt;p&gt;In this function, &lt;code&gt;isSubsetOfLanes&lt;/code&gt; is used.&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;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;isSubsetOfLanes&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;node&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;childLanes&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;renderLanes&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="nx"&gt;node&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;childLanes&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;mergeLanes&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;node&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;childLanes&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;renderLanes&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;alternate&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="nx"&gt;alternate&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;childLanes&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;mergeLanes&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;alternate&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;childLanes&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;renderLanes&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;else&lt;/span&gt; &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Since node represents parent here, we can see that we are doing something like this: "If parent.childLanes (&lt;code&gt;node.childLanes&lt;/code&gt; in the code) is not a subset of the target Lane, update parent.childLanes to the value merged with the target Lane." By doing this, we can move the lanes of children to the parent side. As a result, if you look at fiber.childrenLanes at reconcile time, you will know that the lower layer needs to be re-rendered.&lt;/p&gt;

&lt;p&gt;In this way, Lanes make it easy to group multiple tasks together and still determine their priority in a few passes; when reconciliation, we can just refer to / update / merge Lanes and focus on the main algorithm. As a result, an architecture that matches the idea of Fiber and Suspense can be realized.&lt;/p&gt;

&lt;p&gt;In addition to Lane, there are several other core PR that will be implemented in React 18 alpha, which are detailed in the following thread.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://twitter.com/rickhanlonii/status/1402771549808214016"&gt;https://twitter.com/rickhanlonii/status/1402771549808214016&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://twitter.com/dan_abramov/status/1402927593406582787"&gt;https://twitter.com/dan_abramov/status/1402927593406582787&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://twitter.com/acdlite/status/1402982843962343425"&gt;https://twitter.com/acdlite/status/1402982843962343425&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Isn't it amazing to think that after all the design, implementation, verification, and design iterations, a major version upgrade has finally been made since Fiber was announced?&lt;/p&gt;

</description>
      <category>react</category>
      <category>javascript</category>
    </item>
    <item>
      <title>Rewrite React Fiber core algorithm in 300 lines</title>
      <dc:creator>okmttdhr</dc:creator>
      <pubDate>Mon, 21 Jun 2021 05:24:52 +0000</pubDate>
      <link>https://dev.to/okmttdhr/rewrite-react-fiber-core-algorithm-in-300-lines-mpd</link>
      <guid>https://dev.to/okmttdhr/rewrite-react-fiber-core-algorithm-in-300-lines-mpd</guid>
      <description>&lt;p&gt;Rewrote the React Fiber algorithm.&lt;/p&gt;


&lt;div class="ltag-github-readme-tag"&gt;
  &lt;div class="readme-overview"&gt;
    &lt;h2&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%2Fassets%2Fgithub-logo-5a155e1f9a670af7944dd5e12375bc76ed542ea80224905ecaf878b9157cdefc.svg" alt="GitHub logo"&gt;
      &lt;a href="https://github.com/okmttdhr" rel="noopener noreferrer"&gt;
        okmttdhr
      &lt;/a&gt; / &lt;a href="https://github.com/okmttdhr/my-own-react" rel="noopener noreferrer"&gt;
        my-own-react
      &lt;/a&gt;
    &lt;/h2&gt;
    &lt;h3&gt;
      Rewrite React Fiber core algorithm in 300 lines with links to the React source code
    &lt;/h3&gt;
  &lt;/div&gt;
&lt;/div&gt;


&lt;p&gt;It's about 300 lines long, but I've tried to re-implement the real React as closely as possible, including the naming and function's scope. The implementation was focused on the following points;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;The data structure and algorithm of Fiber&lt;/li&gt;
&lt;li&gt;An interruptible unit of work (conceptually same as concurrent mode)&lt;/li&gt;
&lt;li&gt;Render and commit phase&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Architecture;&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%2Flo423dw2egteuwi13xpi.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%2Flo423dw2egteuwi13xpi.png" alt="architecture"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;I have also commented a link to the React source code, so you can compare it for a better understanding. (For example, in this case, &lt;code&gt;requestIdleCallback&lt;/code&gt; is used to implement pseudo-scheduling, but React is using its own Scheduler).&lt;/p&gt;

&lt;p&gt;Since there is already a lot of information about the architecture of Fiber, this article will only introduce some pieces of code.&lt;/p&gt;

&lt;h3&gt;
  
  
  performUnitOfWork
&lt;/h3&gt;

&lt;p&gt;Traverse the Fiber to determine the next unit of work.&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;// https://github.com/okmttdhr/react/blob/84c06fef8168e779d15cc9450f67888445f7b4f4/packages/react-reconciler/src/ReactFiberBeginWork.new.js#L3206&lt;/span&gt;
&lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;beginWork&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;fiber&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;isFunctionComponent&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt;
    &lt;span class="nx"&gt;fiber&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;type&lt;/span&gt; &lt;span class="k"&gt;instanceof&lt;/span&gt; &lt;span class="nb"&gt;Function&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;isFunctionComponent&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nf"&gt;updateFunctionComponent&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;fiber&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="nf"&gt;updateHostComponent&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;fiber&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;fiber&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;child&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;fiber&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;child&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;

  &lt;span class="kd"&gt;let&lt;/span&gt; &lt;span class="nx"&gt;nextFiber&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;fiber&lt;/span&gt;
  &lt;span class="k"&gt;while &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;nextFiber&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;nextFiber&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;sibling&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;nextFiber&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;sibling&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="nx"&gt;nextFiber&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;nextFiber&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;parent&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="c1"&gt;// https://github.com/facebook/react/blob/84c06fef8168e779d15cc9450f67888445f7b4f4/packages/react-reconciler/src/ReactFiberWorkLoop.new.js#L1574&lt;/span&gt;
&lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;performUnitOfWork&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;fiber&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nx"&gt;nextUnitOfWork&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;beginWork&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;fiber&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;nextUnitOfWork&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nf"&gt;commitRoot&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
    &lt;span class="nf"&gt;completeUnitOfWork&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;h3&gt;
  
  
  workLoop
&lt;/h3&gt;

&lt;p&gt;Loop until it runs out of work.&lt;br&gt;
When the browser gets busy, stop the loop and come back when it's done.&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;// https://github.com/facebook/react/blob/84c06fef8168e779d15cc9450f67888445f7b4f4/packages/react-reconciler/src/ReactFiberWorkLoop.old.js#L1567&lt;/span&gt;
&lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;workLoop&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;deadline&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="kd"&gt;let&lt;/span&gt; &lt;span class="nx"&gt;shouldYield&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="kc"&gt;false&lt;/span&gt;
  &lt;span class="k"&gt;while &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;workInProgressRoot&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span class="o"&gt;!&lt;/span&gt;&lt;span class="nx"&gt;shouldYield&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nf"&gt;performUnitOfWork&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;nextUnitOfWork&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="nx"&gt;shouldYield&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;deadline&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;timeRemaining&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;
  &lt;span class="nf"&gt;requestIdleCallback&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;workLoop&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  reconcileChildren
&lt;/h3&gt;

&lt;p&gt;Diffing and updating Fiber&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;// https://github.com/facebook/react/blob/84c06fef8168e779d15cc9450f67888445f7b4f4/packages/react-reconciler/src/ReactFiberBeginWork.new.js#L255&lt;/span&gt;
&lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;reconcileChildren&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;workInProgressFiber&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;elements&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="kd"&gt;let&lt;/span&gt; &lt;span class="nx"&gt;index&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;
  &lt;span class="kd"&gt;let&lt;/span&gt; &lt;span class="nx"&gt;oldFiber&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt;
    &lt;span class="nx"&gt;workInProgressFiber&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;alternate&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span class="nx"&gt;workInProgressFiber&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;alternate&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;child&lt;/span&gt;
  &lt;span class="kd"&gt;let&lt;/span&gt; &lt;span class="nx"&gt;prevSibling&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="kc"&gt;null&lt;/span&gt;

  &lt;span class="k"&gt;while &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="nx"&gt;index&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt; &lt;span class="nx"&gt;elements&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;length&lt;/span&gt; &lt;span class="o"&gt;||&lt;/span&gt;
    &lt;span class="nx"&gt;oldFiber&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="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;element&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;elements&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;index&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
    &lt;span class="kd"&gt;let&lt;/span&gt; &lt;span class="nx"&gt;newFiber&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="kc"&gt;null&lt;/span&gt;

    &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;sameType&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt;
      &lt;span class="nx"&gt;oldFiber&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt;
      &lt;span class="nx"&gt;element&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt;
      &lt;span class="nx"&gt;element&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;type&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="nx"&gt;oldFiber&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;type&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;sameType&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="nx"&gt;newFiber&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="na"&gt;type&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;oldFiber&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;type&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="nx"&gt;element&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;props&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="na"&gt;dom&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;oldFiber&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;dom&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="na"&gt;parent&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;workInProgressFiber&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="na"&gt;alternate&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;oldFiber&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="na"&gt;flag&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;UPDATE&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="nx"&gt;element&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span class="o"&gt;!&lt;/span&gt;&lt;span class="nx"&gt;sameType&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="nx"&gt;newFiber&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="na"&gt;type&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;element&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;type&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="nx"&gt;element&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;props&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="na"&gt;dom&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="na"&gt;parent&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;workInProgressFiber&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="na"&gt;alternate&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="na"&gt;flag&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;PLACEMENT&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="nx"&gt;oldFiber&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span class="o"&gt;!&lt;/span&gt;&lt;span class="nx"&gt;sameType&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="nx"&gt;oldFiber&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;flag&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;DELETION&lt;/span&gt;
      &lt;span class="nx"&gt;deletions&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;push&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;oldFiber&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;oldFiber&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="nx"&gt;oldFiber&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;oldFiber&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;sibling&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;index&lt;/span&gt; &lt;span class="o"&gt;===&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="nx"&gt;workInProgressFiber&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;child&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;newFiber&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;else&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;element&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="nx"&gt;prevSibling&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;sibling&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;newFiber&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;

    &lt;span class="nx"&gt;prevSibling&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;newFiber&lt;/span&gt;
    &lt;span class="nx"&gt;index&lt;/span&gt;&lt;span class="o"&gt;++&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  commitWork
&lt;/h3&gt;

&lt;p&gt;Update DOM (Commit phase)&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;// https://github.com/facebook/react/blob/84c06fef8168e779d15cc9450f67888445f7b4f4/packages/react-reconciler/src/ReactFiberCommitWork.new.js#L1814&lt;/span&gt;
&lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;commitWork&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;fiber&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;fiber&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="kd"&gt;let&lt;/span&gt; &lt;span class="nx"&gt;parentFiber&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;fiber&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;parent&lt;/span&gt;
  &lt;span class="k"&gt;while &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;!&lt;/span&gt;&lt;span class="nx"&gt;parentFiber&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;dom&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nx"&gt;parentFiber&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;parentFiber&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;parent&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;parentDom&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;parentFiber&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;dom&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;fiber&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;flag&lt;/span&gt; &lt;span class="o"&gt;===&lt;/span&gt; &lt;span class="nx"&gt;PLACEMENT&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt;
    &lt;span class="nx"&gt;fiber&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;dom&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="nf"&gt;commitPlacement&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;fiber&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;parentDom&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="k"&gt;if &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="nx"&gt;fiber&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;flag&lt;/span&gt; &lt;span class="o"&gt;===&lt;/span&gt; &lt;span class="nx"&gt;UPDATE&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt;
    &lt;span class="nx"&gt;fiber&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;dom&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="nf"&gt;commitUpdate&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
      &lt;span class="nx"&gt;fiber&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;dom&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="nx"&gt;fiber&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;alternate&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;props&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="nx"&gt;fiber&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;props&lt;/span&gt;
    &lt;span class="p"&gt;)&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;else&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;fiber&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;flag&lt;/span&gt; &lt;span class="o"&gt;===&lt;/span&gt; &lt;span class="nx"&gt;DELETION&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nf"&gt;commitDeletion&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;fiber&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;parentDom&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;

  &lt;span class="nf"&gt;commitWork&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;fiber&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;child&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
  &lt;span class="nf"&gt;commitWork&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;fiber&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;sibling&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="c1"&gt;// https://github.com/facebook/react/blob/84c06fef8168e779d15cc9450f67888445f7b4f4/packages/react-reconciler/src/ReactFiberWorkLoop.new.js#L1693&lt;/span&gt;
&lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;commitRoot&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nx"&gt;deletions&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;forEach&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;commitWork&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
  &lt;span class="nf"&gt;commitWork&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;workInProgressRoot&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;child&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;Comments and PRs are welcome!&lt;/p&gt;

&lt;h3&gt;
  
  
  Resources
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://reactjs.org/docs/codebase-overview.html#fiber-reconciler" rel="noopener noreferrer"&gt;https://reactjs.org/docs/codebase-overview.html#fiber-reconciler&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/facebook/react/issues/7942" rel="noopener noreferrer"&gt;https://github.com/facebook/react/issues/7942&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/pomber/didact" rel="noopener noreferrer"&gt;https://github.com/pomber/didact&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

</description>
      <category>react</category>
      <category>javascript</category>
    </item>
    <item>
      <title>Micro Frontends Patterns#14: Reading List</title>
      <dc:creator>okmttdhr</dc:creator>
      <pubDate>Thu, 28 Jan 2021 09:53:05 +0000</pubDate>
      <link>https://dev.to/okmttdhr/micro-frontends-patterns-14-reading-list-5d7c</link>
      <guid>https://dev.to/okmttdhr/micro-frontends-patterns-14-reading-list-5d7c</guid>
      <description>&lt;p&gt;&lt;iframe class="tweet-embed" id="tweet-1132493678730252288-827" src="https://platform.twitter.com/embed/Tweet.html?id=1132493678730252288"&gt;
&lt;/iframe&gt;

  // Detect dark theme
  var iframe = document.getElementById('tweet-1132493678730252288-827');
  if (document.body.className.includes('dark-theme')) {
    iframe.src = "https://platform.twitter.com/embed/Tweet.html?id=1132493678730252288&amp;amp;theme=dark"
  }



&lt;/p&gt;

&lt;h2&gt;
  
  
  Essentials
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://martinfowler.com/articles/micro-frontends.html" rel="noopener noreferrer"&gt;Micro Frontends - martinfowler.com&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://micro-frontends.org/" rel="noopener noreferrer"&gt;micro-frontends.org&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Books
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://www.manning.com/books/micro-frontends-in-action" rel="noopener noreferrer"&gt;Micro Frontends in Action&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://www.oreilly.com/library/view/building-micro-frontends/9781492082989" rel="noopener noreferrer"&gt;Building Micro-Frontends&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://www.oreilly.com/library/view/building-microservices/9781491950340/" rel="noopener noreferrer"&gt;Building Microservices (Chapter 4)&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://www.oreilly.com/library/view/monolith-to-microservices/9781492047834/" rel="noopener noreferrer"&gt;Monolith to Microservices (Chapter 3)&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Videos
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://www.youtube.com/watch?v=E0s3EGCefB0&amp;amp;list=WL&amp;amp;index=59&amp;amp;t=0s" rel="noopener noreferrer"&gt;The frontend taboo: a story of full stack microservices - Moritz Grauel - YouTube&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://www.youtube.com/watch?v=bOkZ7327FLg" rel="noopener noreferrer"&gt;Mateusz Chrzonstowski — Server-side rendered micro-frontends on AWS Lambda [EN] — WarsawJS - YouTube&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://www.youtube.com/watch?v=wCHYILvM7kU" rel="noopener noreferrer"&gt;Michael Geers - Micro Frontends - The Nitty Gritty Details or Frontend, Backend, 🌈 Happyend - YouTube&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://www.youtube.com/watch?v=asqgKaUMXq0" rel="noopener noreferrer"&gt;Liron Cohen - Micro-frontends: Is it a Silver Bullet? | React Next 2019 - YouTube&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://www.youtube.com/watch?v=fT-5RHTtFNg" rel="noopener noreferrer"&gt;AWS re:Invent 2019: [REPEAT 1] Building serverless micro frontends at the edge (NET310-R1) - YouTube&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://www.youtube.com/watch?v=JhokA9fWVo0&amp;amp;feature=youtu.be" rel="noopener noreferrer"&gt;Building the Next Generation of Airlines Websites - Iván Olivares (Globant) - YouTube&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Articles
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://scs-architecture.org/" rel="noopener noreferrer"&gt;SCS: Self-Contained Systems&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://docs.microsoft.com/en-us/dotnet/architecture/microservices/architect-microservice-container-applications/microservice-based-composite-ui-shape-layout" rel="noopener noreferrer"&gt;Creating composite UI based on microservices | Microsoft Docs&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://medium.com/dazn-tech/adopting-a-micro-frontends-architecture-e283e6a3c4f3" rel="noopener noreferrer"&gt;Adopting a Micro-frontends architecture | by luca mezzalira | DAZN Engineering | Medium&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://medium.com/@lucamezzalira/micro-frontends-decisions-framework-ebcd22256513" rel="noopener noreferrer"&gt;Micro-frontends decisions framework | by luca mezzalira | Medium&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://medium.com/dazn-tech/orchestrating-micro-frontends-a5d2674cbf33" rel="noopener noreferrer"&gt;Orchestrating micro-frontends. Following the previous posts on… | by luca mezzalira | DAZN Engineering | Medium&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://medium.com/@lucamezzalira/i-dont-understand-micro-frontends-88f7304799a9" rel="noopener noreferrer"&gt;I don’t understand micro-frontends. | by luca mezzalira | Medium&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://www.slideshare.net/kevingoldsmith/how-spotify-builds-products-organization-architecture-autonomy-accountability" rel="noopener noreferrer"&gt;How Spotify Builds Products (Organization. Architecture, Autonomy, Ac…&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://engineering.zalando.com/posts/2018/12/front-end-micro-services.html?gh_src=4n3gxh1?gh_src=4n3gxh1" rel="noopener noreferrer"&gt;Front-End Micro Services&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://www.infoq.com/news/2018/08/experiences-micro-frontends/" rel="noopener noreferrer"&gt;Experiences Using Micro Frontends at IKEA&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="http://microservice-websites.netlify.com/" rel="noopener noreferrer"&gt;Microservice Websites&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://dev.to/buzzfeedtech/why-we-use-micro-frontends-at-buzzfeed-1k9o"&gt;Why we use Micro Frontends at BuzzFeed - DEV&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://tech.buzzfeed.com/micro-frontends-at-buzzfeed-b8754b31d178" rel="noopener noreferrer"&gt;Micro Frontends at BuzzFeed. How we leverage the Micro Frontend… | by Ian Feather | BuzzFeed Tech&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://devblogs.microsoft.com/premier-developer/supporting-micro-frontends-with-asp-net-core-mvc/" rel="noopener noreferrer"&gt;Supporting Micro-frontends with ASP.NET Core MVC | Premier Developer&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://devblogs.microsoft.com/premier-developer/scaling-user-experiences-with-micro-frontends/" rel="noopener noreferrer"&gt;Scaling User experiences with Micro frontends | Developer Support&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://engineering.hellofresh.com/front-end-microservices-at-hellofresh-23978a611b87" rel="noopener noreferrer"&gt;Front-end Microservices at HelloFresh | by Pepijn Senders | HelloTech&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://itnext.io/strangling-a-monolith-to-micro-frontends-decoupling-presentation-layer-18a33ddf591b" rel="noopener noreferrer"&gt;Strangling a Monolith application with Micro Frontends using Server Side Includes | by Felipe Guizar Diaz | ITNEXT&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://medium.com/hacking-talent/two-years-of-micro-frontends-a-retrospective-522526f76df4" rel="noopener noreferrer"&gt;Two years of micro-frontends: A retrospective | by Brody McKee | Hacking Talent | Medium&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://medium.com/js-dojo/micro-frontends-using-vue-js-react-js-and-hypernova-af606a774602" rel="noopener noreferrer"&gt;Micro-frontends using Vue.js, React.js, and Hypernova | by Felipe Guizar Diaz | Vue.js Developers | Medium&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://blog.bitsrc.io/state-of-micro-frontends-9c0c604ed13a" rel="noopener noreferrer"&gt;The State of Micro Frontends. One of the more controversial topics in… | by Florian Rappl | Bits and Pieces&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://medium.com/@tomsoderlund/micro-frontends-a-microservice-approach-to-front-end-web-development-f325ebdadc16" rel="noopener noreferrer"&gt;Micro frontends—a microservice approach to front-end web development | by Tom Söderlund | Medium&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://blog.bitsrc.io/serverless-microfrontends-in-aws-999450ed3795" rel="noopener noreferrer"&gt;Serverless Microfrontends in AWS. How to use AWS serverless technologies… | by Ashan Fernando | Bits and Pieces&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://dev.to/florianrappl/11-popular-misconceptions-about-micro-frontends-463p"&gt;11 Popular Misconceptions About Micro Frontends - DEV&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://altkomsoftware.pl/en/blog-en/ui-in-microservices-world/" rel="noopener noreferrer"&gt;UI in Microservices World – Micro Frontends pattern and Web Components - Altkom Software &amp;amp; Consulting&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://medium.com/swlh/webpack-5-module-federation-a-game-changer-to-javascript-architecture-bcdd30e02669" rel="noopener noreferrer"&gt;Webpack 5 Federation. A Game-changer to Javascript architecture. | The Startup&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://speakerdeck.com/qsona/motivation-for-micro-frontends" rel="noopener noreferrer"&gt;Micro Frontendsのモチベーション Motivation for Micro Frontends - Speaker Deck&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://speakerdeck.com/nobuhikosawai/the-theory-and-practice-of-micro-frontends" rel="noopener noreferrer"&gt;Micro Frontends の理論と実践 -価値提供を高速化する真のマイクロサービスのあり方 - The Theory and Practice of Micro Frontends - Speaker Deck&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://www.otto.de/jobs/technology/techblog/artikel/on-monoliths-and-microservices_2015-09-30.php" rel="noopener noreferrer"&gt;On Monoliths and Microservices&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://medium.com/finc-engineering/backends-for-frontends-and-its-similar-pattern-from-the-microservices-perspective-572254a0196e" rel="noopener noreferrer"&gt;マイクロサービスの思想から捉える Backends for Frontendsとその類似パターン | by qsona | FiNC Tech Blog | Medium&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://hack.nikkei.com/blog/rnikkei_microfrontends_pwa/" rel="noopener noreferrer"&gt;日経電子版のマイクロフロントエンドとPWA — HACK The Nikkei&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://blog.bitsrc.io/how-we-build-micro-front-ends-d3eeeac0acfc" rel="noopener noreferrer"&gt;How We Build Micro Frontends. Building micro-frontends to speed up… | by Jonathan Saring | Aug, 2020 | Bits and Pieces&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://silverbirder180.hatenablog.com/entry/2020/08/23/183713" rel="noopener noreferrer"&gt;Ara-Framework で Micro Frontends with SSR - LifeHack Engineering Blog&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://dev.to/florianrappl/communication-between-micro-frontends-41fe"&gt;Communication Between Micro Frontends - DEV&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/vercel/next.js/issues/6040" rel="noopener noreferrer"&gt;Feasibility of micro frontends · Issue #6040 · vercel/next.js&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://speakerdeck.com/karszawa/micro-frontends-with-tailor" rel="noopener noreferrer"&gt;Micro Frontends with Tailor - Speaker Deck&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  OSS
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://ara-framework.github.io/website/" rel="noopener noreferrer"&gt;Ara Framework · Build Micro-frontends easily using Airbnb Hypernova&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/opencomponents/oc" rel="noopener noreferrer"&gt;opencomponents/oc: OpenComponents, serverless in the front-end world for painless micro-frontends delivery&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://www.mosaic9.org/" rel="noopener noreferrer"&gt;Project Mosaic—Frontend Microservices&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://podium-lib.io/" rel="noopener noreferrer"&gt;Podium · Easy server side composition of microfrontends&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/puzzle-js/puzzle-js" rel="noopener noreferrer"&gt;puzzle-js/puzzle-js: ⚡ Micro frontend framework for scalable and blazing fast websites.&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://webpack.js.org/concepts/module-federation/" rel="noopener noreferrer"&gt;Module Federation | webpack&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/single-spa/single-spa" rel="noopener noreferrer"&gt;single-spa/single-spa: The router for easy microfrontends&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/umijs/qiankun" rel="noopener noreferrer"&gt;umijs/qiankun: 📦 🚀 Blazing fast, simple and completed solution for micro frontends.&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/ice-lab/icestark" rel="noopener noreferrer"&gt;ice-lab/icestark: Micro Frontends solution for large application（面向大型应用的微前端解决方案）&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/smapiot/piral" rel="noopener noreferrer"&gt;smapiot/piral: Framework for next generation web apps using microfrontends.&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/SAP/luigi" rel="noopener noreferrer"&gt;SAP/luigi: Micro frontend framework&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

</description>
    </item>
    <item>
      <title>Micro Frontends Patterns#13: Build Time Composition</title>
      <dc:creator>okmttdhr</dc:creator>
      <pubDate>Thu, 28 Jan 2021 09:50:20 +0000</pubDate>
      <link>https://dev.to/okmttdhr/micro-frontends-patterns-14-build-time-composition-3kol</link>
      <guid>https://dev.to/okmttdhr/micro-frontends-patterns-14-build-time-composition-3kol</guid>
      <description>&lt;p&gt;Build Time Composition assembles Fragments at build time, not at client or server.&lt;/p&gt;

&lt;h2&gt;
  
  
  Shared libraries
&lt;/h2&gt;

&lt;p&gt;One way to do Build Time Composition is to create shared libraries using npm or similar. In this case, each Micro Frontends will use the shared library. For example, UI components used in the company are provided as component libraries.&lt;/p&gt;

&lt;p&gt;We need to consider about how to bundle duplicate code and limit styles' scope. The interface will also need to be carefully designed to maintain consistency across applications.&lt;/p&gt;

&lt;p&gt;Also, which team will be in charge of development should be discussed before implementation. For example, there is a distributed development pattern where everyone is a contributor, an OSS pattern where a "platform team" is set up with a main maintainer and reviewer, and a pattern where one team is in charge of all development.&lt;/p&gt;

&lt;p&gt;It is important to be careful to make the library meaningful, following "Duplication is far cheaper than the wrong abstraction".&lt;/p&gt;

&lt;h2&gt;
  
  
  SSG
&lt;/h2&gt;

&lt;p&gt;This is the way to use SSG technology described in the chapter of JAMstack. For example, the following flow can be considered.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--XU60zGn5--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/ltz44inrg36t21foqhkq.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--XU60zGn5--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/ltz44inrg36t21foqhkq.png" alt="ikc8elguwbkbkrq0umifs75ez0rv"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;In this case, APIzed Fragments are converted to static content at build time.&lt;/p&gt;

&lt;h2&gt;
  
  
  Bit
&lt;/h2&gt;

&lt;p&gt;Bit is a tool for component-driven development that allows you to easily build, versioning, deploy, etc. from CLI.&lt;/p&gt;

&lt;p&gt;For example, you can see which avatar component or nav-item component is being used by which component, so that you can perform appropriate versioning.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--H6-NnqqQ--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/55p4uknzhrnypfhyrdnm.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--H6-NnqqQ--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/55p4uknzhrnypfhyrdnm.png" alt="omogfd2trl4mgdfxqjztujudkhg5"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;One of the advantages of using Bit is that it provides a kind of framework for the development flow of Build Time Composition.&lt;/p&gt;

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

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

&lt;p&gt;The advantage of Build Time Composition is that it provides SEO and performance advantages without taking server resources into account. It is only with Build Time Composition that you can enjoy the benefits of Server Side Composition while reducing the various runtime considerations.&lt;/p&gt;

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

&lt;p&gt;Build Time Composition does not allow deployments to be loosely coupled. This is a big disadvantage in terms of Micro Frontends. For example, a library that uses Build Time Composition needs to be deployed after the libraries' updates.&lt;/p&gt;

&lt;p&gt;Also, depending on the application, it may be necessary to design the interface in such a way that it does not depend on the Framework.&lt;/p&gt;

&lt;h2&gt;
  
  
  Summary
&lt;/h2&gt;

&lt;p&gt;With Build Time Composition, we looked at Micro Frontends using the SSG and shared libraries. We would like to consider this as one of the options depending on the use-cases.&lt;/p&gt;

</description>
      <category>microfrontends</category>
      <category>microservices</category>
      <category>javascript</category>
    </item>
    <item>
      <title>Micro Frontends Patterns#12: Server Side Composition</title>
      <dc:creator>okmttdhr</dc:creator>
      <pubDate>Wed, 27 Jan 2021 00:55:21 +0000</pubDate>
      <link>https://dev.to/okmttdhr/micro-frontends-patters-13-server-side-composition-1of5</link>
      <guid>https://dev.to/okmttdhr/micro-frontends-patters-13-server-side-composition-1of5</guid>
      <description>&lt;p&gt;Server Side Composition, as the name suggests, is a pattern that assembles Fragments on the server side.&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%2Fi%2Fkr7puzqla3cddnge07sw.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%2Fi%2Fkr7puzqla3cddnge07sw.png" alt="byugsxdacdzx50nj9rev75ssd7w1"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Here are some of the architectures which I know.&lt;/p&gt;

&lt;h2&gt;
  
  
  Layout Server + Fragments Server
&lt;/h2&gt;

&lt;p&gt;Layout Server + Fragments Server is a simple Server Side Composition.&lt;/p&gt;

&lt;p&gt;The Fragments Server here means the server that returns the Fragments by each Micro Frontends team, and the Layout Server is the server side application such as Rails, PHP, Node.js, etc. that assembles the Fragments and returns the final HTML, CSS, and JS.&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%2Fi%2Fx5o29xpg4zl7cp7xd75s.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%2Fi%2Fx5o29xpg4zl7cp7xd75s.png" alt="kb5akftfra4whwgkmqlhyem0oyp5"&gt;&lt;/a&gt; &lt;/p&gt;

&lt;p&gt;First, let's consider the Node.js Layout Server + Fragments Server.&lt;/p&gt;

&lt;p&gt;For example, if there are two Fragment servers, one exposing React components and the other exposing Vue components, the Layout Server can parse and assemble them.&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%2Fi%2Fk1d46968xm1v21y3xi0d.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%2Fi%2Fk1d46968xm1v21y3xi0d.png" alt="d7kaawp0lzq6bdjdn1shorejpnst"&gt;&lt;/a&gt; &lt;/p&gt;

&lt;p&gt;So, what if your existing application is written in a language other than Node.js? In fact, I think that's the pattern in many cases.&lt;/p&gt;

&lt;p&gt;In this case, it's difficult to handle framework-specific Fragments, so we'll take an HTML string and assemble the Fragments.&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%2Fi%2Ff4177y52w2wf2wpm0026.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%2Fi%2Ff4177y52w2wf2wpm0026.png" alt="8rsdd73puevzlutkxv4jtfjnllzd"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Both of these patterns seem to work well at first glance.&lt;/p&gt;

&lt;p&gt;However, let's consider the case where we want to pass the data from the server to the component and then SSR it. In this case, the Fragments server itself needs to have an interface that can receive data and return a response. It is necessary to have some common understanding within the organization. Also, if you want to return HTML string, you need to implement it in such a way that the component is rendered and converted to a string after receiving the data. Versioning should be done well, too. Isn't it getting tedious to do like this?&lt;/p&gt;

&lt;p&gt;The Layout Server + Fragments Server pattern is straightforward, but the difficulty increases when you try to deal with a variety of requirements.&lt;/p&gt;

&lt;h2&gt;
  
  
  Layout Server + Fragment Gateway
&lt;/h2&gt;

&lt;p&gt;The Layout Server + Fragment Gateway pattern is similar to the Gateway Aggregation pattern introduced in previous chapter. The role of the Fragment Gateway here is similar to that of the API Gateway in Gateway Aggregation. It takes care of the access to multiple Fragments, separates the responsibilities from the Layout Server, and unifies the interfaces from Frontend.&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%2Fi%2Fi3nh7i9kqsds6sl6dq90.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%2Fi%2Fi3nh7i9kqsds6sl6dq90.png" alt="unp0iqgv64spyuxb4kd2b26qk0ex"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Let's look at a example. The following figure shows an architecture using &lt;a href="https://github.com/airbnb/hypernova" rel="noopener noreferrer"&gt;Hypernova&lt;/a&gt; for 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%2Fi%2Fvjasbku4d6b0gntfl7cw.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%2Fi%2Fvjasbku4d6b0gntfl7cw.png" alt="mvt5j3l8mm7832qeicjlsgqmwof6"&gt;&lt;/a&gt; &lt;/p&gt;

&lt;p&gt;Here, the Layout Server is made of Rails and the Fragment Gateway is made of Node.&lt;/p&gt;

&lt;p&gt;1) Layout Server creates data for the server, 2) requests it to Fragment Gateway, 3) then Fragment Gateway pours the data into the component, and finally 4) HTML with the data is returned&lt;sup id="fnref1"&gt;1&lt;/sup&gt;.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;The role of the Fragment Gateway is to abstract Fragments as an API from the perspective of the Layout Server&lt;/strong&gt;, allowing it to become the gateway for handling a wide variety of Fragments as SSR-enabled components. In addition, no matter what framework is used on the Fragments side, the Fragment Gateway can handle it without changing existing server architecture&lt;sup id="fnref2"&gt;2&lt;/sup&gt;.&lt;/p&gt;

&lt;p&gt;The above is the basic architecture of Layout Server + Fragment Gateway. There are several frameworks that can do Server Side Composition with this pattern, including OpenComponents, Podium, and PuzzleJs.&lt;/p&gt;

&lt;h2&gt;
  
  
  Tailor
&lt;/h2&gt;

&lt;p&gt;Here, I would like to introduce a library called &lt;a href="https://github.com/zalando/tailor" rel="noopener noreferrer"&gt;Tailor&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Tailor is not a Layout Server + Fragment Gateway pattern, but rather a more sophisticated Layout Server, with some unique features in terms of assembling Fragments.&lt;/p&gt;

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

&lt;p&gt;In Tailor, you can resolve Fragments by doing the following&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight html"&gt;&lt;code&gt;&lt;span class="nt"&gt;&amp;lt;html&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;"fragment"&lt;/span&gt; &lt;span class="na"&gt;src=&lt;/span&gt;&lt;span class="s"&gt;"http://assets.domain.com"&lt;/span&gt;&lt;span class="nt"&gt;&amp;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;fragment&lt;/span&gt; &lt;span class="na"&gt;src=&lt;/span&gt;&lt;span class="s"&gt;"http://header.domain.com"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&amp;lt;/fragment&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;fragment&lt;/span&gt; &lt;span class="na"&gt;src=&lt;/span&gt;&lt;span class="s"&gt;"http://content.domain.com"&lt;/span&gt; &lt;span class="na"&gt;primary&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&amp;lt;/fragment&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;fragment&lt;/span&gt; &lt;span class="na"&gt;src=&lt;/span&gt;&lt;span class="s"&gt;"http://footer.domain.com"&lt;/span&gt; &lt;span class="na"&gt;async&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&amp;lt;/fragment&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;Each Fragment is requested asynchronously and can be prioritized as &lt;code&gt;primary&lt;/code&gt; &lt;code&gt;async&lt;/code&gt;.&lt;/p&gt;

&lt;h3&gt;
  
  
  Streaming
&lt;/h3&gt;

&lt;p&gt;Fragments are delivered as a stream, so you don't have to wait for all Fragments to be completed, which speeds up Time to First Byte.&lt;/p&gt;

&lt;h3&gt;
  
  
  Assets
&lt;/h3&gt;

&lt;p&gt;Fragments to be SSR need Rehydration, which means we need JS/CSS assets.&lt;/p&gt;

&lt;p&gt;Tailor will respond with the asset information in the Link Header. The nice thing about this is that you can tell Tailor which assets to load. For example, consider the following response for an asset with a hash&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;fragment.ctfvygbh.js
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;In this case, even if you generate different hashes for different client versions, you can still read the assets that are responded to, making it easier to use a caching strategy.&lt;/p&gt;

&lt;h3&gt;
  
  
  Summary
&lt;/h3&gt;

&lt;p&gt;Using a library like Tailor that focuses on Layout Server functionality reduces the number of considerations on the part of the Micro Frontends consumer, while optimizing for TTFB and asset management.&lt;/p&gt;

&lt;h2&gt;
  
  
  Ara Framework
&lt;/h2&gt;

&lt;p&gt;The Ara Framework is based on Hypernova, and provides a CLI and a set of modules for building Micro Frontends. Among them, the architecture of Server Side Composition is unique.&lt;/p&gt;

&lt;p&gt;The whole picture is as follows.&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%2Fi%2Fro8bz0grh6c4c7qxoyox.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%2Fi%2Fro8bz0grh6c4c7qxoyox.png" alt="cvnm7f37lxko4jjv1uurqmalv61j"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;For details, please refer to &lt;a href="https://ara-framework.github.io/website/docs/nova-architecture" rel="noopener noreferrer"&gt;Doc&lt;/a&gt;, but here I will just give an overview.&lt;/p&gt;

&lt;h3&gt;
  
  
  Strangler Pattern
&lt;/h3&gt;

&lt;p&gt;First of all, &lt;a href="https://itnext.io/strangling-a-monolith-to-micro-frontends-decoupling-presentation-layer-18a33ddf591b" rel="noopener noreferrer"&gt;Author's Medium&lt;/a&gt; shows that the Ara Framework is designed with the Strangler Pattern in mind.&lt;/p&gt;

&lt;p&gt;For example, imagine a monolithic application built in Rails or Laravel and gradually refactor it into an architecture suitable for 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%2Fi%2Fnj3n5rhantu9q0tsig32.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%2Fi%2Fnj3n5rhantu9q0tsig32.png" alt="l30ca579plb1d3j5dtnmsmhb6qoj (1)"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;(From &lt;a href="https://docs.microsoft.com/en-us/azure/architecture/patterns/strangler" rel="noopener noreferrer"&gt;Microsoft Cloud Design Patterns&lt;/a&gt;)&lt;/p&gt;

&lt;p&gt;The following is a description based on this assumption.&lt;/p&gt;

&lt;h3&gt;
  
  
  Nova Proxy
&lt;/h3&gt;

&lt;p&gt;The Nova Proxy is a reverse proxy that sits between the existing application, which takes request from the browser, and render HTML.&lt;/p&gt;

&lt;p&gt;The PHP server communicates with the data layer, and when generating the HTML, placeholders are embedded in advance and returned to the Nova Proxy.&lt;/p&gt;

&lt;p&gt;The Nova Proxy parses the HTML it receives and requests the data embedded in the placeholders as a payload to the Nova Cluster. Its job is then to replace the placeholders with the returned Fragments. This layer is also responsible for handling fallbacks and timeouts, for example.&lt;/p&gt;

&lt;h3&gt;
  
  
  Nova Cluster
&lt;/h3&gt;

&lt;p&gt;Nova Cluster is the Fragment Gateway in this chapter.&lt;/p&gt;

&lt;p&gt;Nova Cluster receives data from Nova Proxy to multiple Fragments at once. Based on the requests it receives, Nova Cluster queries each Fragment, generate HTML, and returns it to Nova Proxy.&lt;/p&gt;

&lt;h3&gt;
  
  
  Summary
&lt;/h3&gt;

&lt;p&gt;With this architecture, existing servers can reduce their awareness of Micro Frontends and focus on building the data. It may also be possible to break down the responsibilities, gradually moving the existing rendering logic to the Nova Proxy, and decoupling the Backend layer as an API.&lt;/p&gt;

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

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

&lt;p&gt;One of the things that Server Side Composition can accomplish is SSR. Another advantage is that it can be implemented in Stream. In addition, by providing a Fragment Gateway, for example, the client no longer has to make multiple requests to Fragments. This kind of performance and SEO requirements may be mandatory for some applications, in which case Server Side Composition will need to be implemented.&lt;/p&gt;

&lt;p&gt;Also, if you have an existing monolithic server side application that you want to decompose into microservices, you need to make the Frontend and Backend loosely coupled. As shown in the example of Ara Framework, Server Side Composition can flexibly handle the case where a legacy monolithic application is gradually refactored.&lt;/p&gt;

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

&lt;p&gt;One of the disadvantages, as you may have noticed, is the increase in complexity. You need to consider an architecture that is not only in Frontend, and since there will be server resources, you will also need to design for availability and scalability. It is always important to be aware of how these will ultimately improve the development efficiency of the organization.&lt;/p&gt;

&lt;p&gt;This is also true for Micro Frontends in general, but there is no de facto technology yet. Since the existing systems and the sense of challenges differ from organization to organization, I believe that the situation is such that each company implements the best, and the companies that have the strength makes their software Open Source (therefore, the architecture of the libraries introduced in this chapter varies). It is necessary to understand the design concept of the library or framework, determine whether it fits your company's challenges, and if not, you need to implement it by yourself.&lt;/p&gt;

&lt;h2&gt;
  
  
  Summary
&lt;/h2&gt;

&lt;p&gt;In this chapter, I introduced Server Side Composition and the architecture of some libraries. I believe that with Server Side Composition, we can adopt a flexible architecture that will be helpful while thinking real-world complex challenges.&lt;/p&gt;




&lt;ol&gt;

&lt;li id="fn1"&gt;
&lt;p&gt;&lt;code&gt;hypernova-${client}&lt;/code&gt; (in this case &lt;code&gt;hypernova-ruby&lt;/code&gt;) can be used to abstract requests to &lt;code&gt;hypernova/server&lt;/code&gt;. See &lt;a href="https://github.com/airbnb/hypernova" rel="noopener noreferrer"&gt;GitHub&lt;/a&gt; for details. ↩&lt;/p&gt;
&lt;/li&gt;

&lt;li id="fn2"&gt;
&lt;p&gt;I'm sure this will be discussed in the case of Microservices as well, but I think the organization needs to have a common understanding of whether to align the frameworks. First of all, it can be seen that it is more natural to have Framework Agnostic as an interface. The fact that each team can select technologies independently is also close to the original idea of Micro Frontends. However, in reality, there is more to think about with different frameworks (complexity of coupling layers, bundle size, reinventing the wheel within the company), and there is also the benefit of being able to share information in a "Guild" style. It is my opinion that you need to think about the use case on the user side and consider which is more suitable. ↩&lt;/p&gt;
&lt;/li&gt;

&lt;/ol&gt;

</description>
      <category>microfrontends</category>
      <category>microservices</category>
      <category>javascript</category>
    </item>
    <item>
      <title>Micro Frontends Patterns#11: Edge Side Composition</title>
      <dc:creator>okmttdhr</dc:creator>
      <pubDate>Mon, 04 Jan 2021 09:21:02 +0000</pubDate>
      <link>https://dev.to/okmttdhr/micro-frontends-patterns-11-23h0</link>
      <guid>https://dev.to/okmttdhr/micro-frontends-patterns-11-23h0</guid>
      <description>&lt;p&gt;Edge Side Composition is a technology that combines content at the edge layer, such as CDN.&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%2Fi%2F86h8okuiwntckcv8m3kg.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%2Fi%2F86h8okuiwntckcv8m3kg.png" alt="1yzrvzfkqdw2qi2a0eutljscqbat"&gt;&lt;/a&gt; &lt;/p&gt;

&lt;p&gt;Edge Side Composition here is assumed to be a process that assembles and renders Fragments at the Edge Side.&lt;/p&gt;

&lt;h2&gt;
  
  
  Edge Side Includes
&lt;/h2&gt;

&lt;p&gt;The ESI in the previous section can be a kind of Edge Side Composition.&lt;/p&gt;

&lt;h2&gt;
  
  
  Edge Side Rendering
&lt;/h2&gt;

&lt;p&gt;In this section, SSR running on the Edge Side are called Edge Side Rendering. For example, Edge Side Rendering &lt;a href="https://www.serverless.com/blog/serverless-nextjs" rel="noopener noreferrer"&gt;with Next.js using Lambda@Edge and Serverless Framework&lt;/a&gt;, Edge Side Rendering with &lt;a href="https://blog.cloudflare.com/rendering-react-on-the-edge-with-flareact-and-cloudflare-workers/" rel="noopener noreferrer"&gt;Cloudflare Workers using a framework called Flareact&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;The Edge Side FaaS can take care of the dynamic Backends that the server is usually in charge of, and can also deliver the static content.&lt;/p&gt;

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

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

&lt;p&gt;As the name suggests, Edge Side Composition does not require any server resources for composition. Since everything is done on the Edge Side, there is no need to prepare and manage a computing environment for a simple rendering server. Also, in terms of latency, since it delivers just static contents on the Edge Side, it will have an advantage over a simple Node server.&lt;/p&gt;

&lt;p&gt;There are also advantages in terms of scaling. For example, when using SSR with React, the nature of Node.js can cause CPU-bound. Edge Side Composition is designed for serverless computing environments, so it reduces the need for infrastructure scaling considerations. In addition, AWS Lambda, for example, scales horizontally on a per-request basis, so the possibility of CPU-bound can be reduced as well.&lt;/p&gt;

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

&lt;p&gt;We will use some kind of FaaS actually. Because it is managed service, its quota can be a disadvantage. For example, in AWS Lambda, the following limitations exist;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Timeout - 15 minutes, 5 seconds for Viewer and 30 seconds for Origin in Lambda Edge&lt;/li&gt;
&lt;li&gt;Response size - 6MB, 40KB for Viewer and 1MB for Origin in Lambda Edge&lt;/li&gt;
&lt;li&gt;Size of the function itself - 50MB, 1MB for Viewer and 50MB for Origin in Lambda Edge&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;For example, in terms of function size, it is necessary to compactly package modules related to rendering. Also, when using configuration management tools such as CloudFormation, you need to consider the limit on the number of resources and the design of IaC. Cold start is another point that needs to be considered. Thus, when using FaaS, it will be necessary to investigate and agree in advance whether it will meet the actual application requirements.&lt;/p&gt;

&lt;p&gt;If you don't want to be bothered by the above limitations, you might want to consider an architecture such as Fargate + CDN, or scaling with ECS or EKS in the first place.&lt;/p&gt;

&lt;h2&gt;
  
  
  Summary
&lt;/h2&gt;

&lt;p&gt;Edge Side Composition is a dream architecture that gives JAMstack the weapon of a computing environment, but I think it needs to be used with a good understanding.&lt;/p&gt;

</description>
      <category>microservices</category>
      <category>microfrontends</category>
      <category>javascript</category>
    </item>
    <item>
      <title>Micro Frontends Patterns#10: Edge Side Includes</title>
      <dc:creator>okmttdhr</dc:creator>
      <pubDate>Fri, 01 Jan 2021 05:14:45 +0000</pubDate>
      <link>https://dev.to/okmttdhr/micro-frontends-patterns-10-edge-side-includes-3m75</link>
      <guid>https://dev.to/okmttdhr/micro-frontends-patterns-10-edge-side-includes-3m75</guid>
      <description>&lt;p&gt;Edge Side Includes (ESI) is a technology or a markup language used to assemble content at the edge layer, such as CDN.&lt;/p&gt;

&lt;p&gt;Specifically, content is resolved at the Edge Side by writing the following&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight html"&gt;&lt;code&gt;&lt;span class="nt"&gt;&amp;lt;html&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;body&amp;gt;&lt;/span&gt;
    This is my fragment: &lt;span class="nt"&gt;&amp;lt;esi:include&lt;/span&gt; &lt;span class="na"&gt;src=&lt;/span&gt;&lt;span class="s"&gt;"https://our.fragments.com/fragment.html"&lt;/span&gt;&lt;span class="nt"&gt;/&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;ESI is a relatively old technology, the specification was &lt;a href="https://www.w3.org/TR/esi-lang/"&gt;developed&lt;/a&gt; by a group of companies like Akamai and Oracle. It's implemented by some CDN vendors like Akamai, Cloudflare, Fastly, Varnish, and others. In the context of Micro Frontends, this is used to compose Fragments.&lt;/p&gt;

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

&lt;p&gt;There are a limited number of CDN vendors that can be used, so you need to consider whether you can tolerate that before implementing. And you need to be careful about ESI's resource acquisition logic differs depending on the vendor.&lt;/p&gt;

&lt;p&gt;Also, since ESI is a simple specification, it may not be flexible. For example, data retrieved on the server side cannot be passed to Fragments on the Edge. Furthermore, it is difficult to render applications that require CSR like SPA.&lt;/p&gt;

&lt;p&gt;From a development point of view, local development can be tricky. In practice, you may need to consider a wrapper such as &lt;a href="https://github.com/Schibsted-Tech-Polska/nodesi"&gt;nodesi&lt;/a&gt;. (Personally, I also don't like the fact that the application logic depends on the Edge Side specification).&lt;/p&gt;

&lt;p&gt;However, the fact that it can be written simply and has minimal features such as Fallback and Timeout is an advantage. It is also attractive that you don't have to think about the server while you don't need to care about Fragments on client-side code. Also, since you can cache a part of UI, ESI is unique in that you can take a flexible caching strategy, such as when you want to cache only static content on a screen where dynamic and static content live together.&lt;/p&gt;

&lt;h2&gt;
  
  
  Summary
&lt;/h2&gt;

&lt;p&gt;In this article, we have shown how ESI can be used to compose Fragments on the Edge Side. Although the simplicity of ESI makes it not very flexible, it is a good option if it fits your use case.&lt;/p&gt;

</description>
      <category>microservices</category>
      <category>microfrontends</category>
      <category>javascript</category>
    </item>
    <item>
      <title>Micro Frontends Patterns#9: Client Side Composition</title>
      <dc:creator>okmttdhr</dc:creator>
      <pubDate>Wed, 30 Dec 2020 03:14:57 +0000</pubDate>
      <link>https://dev.to/okmttdhr/micro-frontends-patterns-5gc2</link>
      <guid>https://dev.to/okmttdhr/micro-frontends-patterns-5gc2</guid>
      <description>&lt;p&gt;The next pattern is called Client Side Composition, but before that, let's talk about the concept of &lt;code&gt;Fragments&lt;/code&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  What are Fragments?
&lt;/h2&gt;

&lt;p&gt;Fragments is a element that builds a page in 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%2Fi%2F1jjn0x0crz7q89mljgjk.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%2Fi%2F1jjn0x0crz7q89mljgjk.png" alt="qxbp63jli71essce4nvdvdlxigzo"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The above is borrowed from micro-frontends.org, and each of these different colored elements is a Fragment. This is pretty close to what we imagine the name Micro Frontends.&lt;/p&gt;

&lt;p&gt;Fragments are not just UI components, but rather elements which provide some functionality for the business domain. In the example above, there are Team Product, Team Checkout, and Team Inspire, with separate development teams and deployments, each of which is a &lt;strong&gt;vertical decomposition&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;Fragments are not applications on their own, so there must be a composition layer somewhere. In the example above, Team Product is the owner of the "Product Detail Page", which is combined with other Fragments. Client Side Composition, which we will now discuss, is one of those composition patterns.&lt;/p&gt;

&lt;p&gt;Fragments can be called in different ways depending on the Micro Frontends library. For example, Podium uses &lt;code&gt;Podlets&lt;/code&gt;, OpenComponents uses &lt;code&gt;Components&lt;/code&gt;, and PuzzleJs and Tailor use &lt;code&gt;Fragments&lt;/code&gt;. In this article, I will refer to the aforementioned concepts as &lt;code&gt;Fragments&lt;/code&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  What is Client Side Composition?
&lt;/h2&gt;

&lt;p&gt;Client Side Composition is one of the patterns that combine Fragments on client-side, and as the name suggests.&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%2Fi%2F7rc3w0i75fqgh6v7hf90.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%2Fi%2F7rc3w0i75fqgh6v7hf90.png" alt="8psomahhlq5ounexk813ptcvgn0w"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;It uses HTML, CSS, and JavaScript to render Fragments at runtime. Let's look at some concrete examples.&lt;/p&gt;

&lt;h2&gt;
  
  
  Web Components
&lt;/h2&gt;

&lt;p&gt;This is a pattern that uses Web Components.&lt;/p&gt;

&lt;p&gt;Prepare the following markup, and JavaScript on the client-side render the UI.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight html"&gt;&lt;code&gt;&lt;span class="nt"&gt;&amp;lt;my-fragment&amp;gt;&amp;lt;/my-fragment&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;





&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;MyFragment&lt;/span&gt; &lt;span class="kd"&gt;extends&lt;/span&gt; &lt;span class="nc"&gt;HTMLElement&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nf"&gt;connectedCallback&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;innerHTML&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;`&amp;lt;h1&amp;gt;Hello world&amp;lt;/h1&amp;gt;`&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="nx"&gt;customElements&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;define&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;my-fragment&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;MyFragment&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Framework Specific
&lt;/h2&gt;

&lt;p&gt;This is the pattern of using some framework or library, for example, React can render Fragments for markup like this, which is not so different from Web Components.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight html"&gt;&lt;code&gt;&lt;span class="nt"&gt;&amp;lt;div&lt;/span&gt; &lt;span class="na"&gt;id=&lt;/span&gt;&lt;span class="s"&gt;"app"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&amp;lt;/div&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;





&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;MyFragment&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="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;Hello&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;world&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="sr"&gt;/h1&amp;gt;&lt;/span&gt;&lt;span class="err"&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;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;MyFragment&lt;/span&gt; &lt;span class="o"&gt;/&amp;gt;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nb"&gt;document&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;getElementById&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;app&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;));&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Using the library
&lt;/h2&gt;

&lt;p&gt;There are several libraries that enable Client Side Composition, most of them are in the style of using Fragments in the App Shell, and some of them provide CLI and so on to make the development more efficient.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://github.com/single-spa/single-spa" rel="noopener noreferrer"&gt;single-spa/single-spa&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/frintjs/frint" rel="noopener noreferrer"&gt;frintjs/frint&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/smapiot/piral" rel="noopener noreferrer"&gt;smapiot/piral&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

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

&lt;p&gt;Client Side Composition is a simple Micro Frontends. It can be used by simply loading markup and JavaScript, and can be achieved with familiar web standard technologies. (Web Components has the disadvantage that there is no standard way to do SSR, so it is difficult to adopt if you want to do SSR in the future).&lt;/p&gt;

&lt;p&gt;However, since FCP and TTI tend to be large, performance considerations such as Lazy load are necessary. Also, if each Fragments uses a framework, you need to be careful about the bundle size. In some cases, libraries that provide an App Shell layer may be considered to cover such details.&lt;/p&gt;

&lt;h2&gt;
  
  
  Summary
&lt;/h2&gt;

&lt;p&gt;We have seen the Composition pattern called Client Side Composition. I think the runtime composition is easy to understand and is a technique that Frontend engineers are familiar with.&lt;/p&gt;

</description>
      <category>microservices</category>
      <category>microfrontends</category>
      <category>javascript</category>
    </item>
    <item>
      <title>Micro Frontends Patterns#8: Unified SPA</title>
      <dc:creator>okmttdhr</dc:creator>
      <pubDate>Tue, 29 Dec 2020 03:32:26 +0000</pubDate>
      <link>https://dev.to/okmttdhr/micro-frontends-patterns-8-2d46</link>
      <guid>https://dev.to/okmttdhr/micro-frontends-patterns-8-2d46</guid>
      <description>&lt;p&gt;Unified SPA is similar to Linked Application, but it navigates multiple SPAs.&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%2Fi%2Flafai3opwndinei5up1m.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%2Fi%2Flafai3opwndinei5up1m.png" alt="qmz7yj4upkzrzm3xdldz3f99x5uo"&gt;&lt;/a&gt; &lt;/p&gt;

&lt;p&gt;In the case of a simple hyperlink transition, it will be the same as a Linked Application. The transition between SPAs will be server-side rendering, so there will be a round trip.&lt;/p&gt;

&lt;p&gt;There is another pattern for Unified SPA. It is the pattern of creating an App Shell layer that binds the SPAs together.&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%2Fi%2F5rbxoakcxmulrvi6ipxj.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%2Fi%2F5rbxoakcxmulrvi6ipxj.png" alt="dkzpm5ua79gig4kayjux94o7funr"&gt;&lt;/a&gt; &lt;/p&gt;

&lt;p&gt;In this case, since the client-side rendering between SPAs is done in the App Shell layer, the performance overhead, which is one of the disadvantages of Linked Application, is reduced.&lt;/p&gt;

&lt;p&gt;This can be achieved by using a library such as &lt;a href="https://single-spa.js.org/" rel="noopener noreferrer"&gt;single-spa&lt;/a&gt; called meta-framework. An example code for the configuration part is shown below, which combines separately deployed applications.&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="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;registerApplication&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;start&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;single-spa&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="nf"&gt;registerApplication&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
  &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;app2&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="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="s1"&gt;@my-company/app2/main.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="nx"&gt;location&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;location&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;/app2&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
  &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="na"&gt;some&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;value&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;registerApplication&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;
  &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;app1&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="na"&gt;app&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="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="s1"&gt;@my-company/app1/main.js&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
  &lt;span class="na"&gt;activeWhen&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;/app1&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="na"&gt;customProps&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="na"&gt;some&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;value&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="nf"&gt;start&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;If you are interested in other libraries, please refer to &lt;code&gt;Reading List&lt;/code&gt; which will be the last section of this series.&lt;/p&gt;

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

&lt;p&gt;Because it is an SPA, the interactivity of the Frontend will be improved compared to Linked Application, and the fact that you can achieve Micro Frontends by simply merging SPAs together is also a good thing. It is also possible to create common parts using the &lt;a href="https://single-spa.js.org/docs/parcels-overview" rel="noopener noreferrer"&gt;Parcels&lt;/a&gt; mechanism of &lt;code&gt;single-spa&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;One of the disadvantages of Linked Application is that it tends to be a single point of failure in the application layer; if there is a bug in the App Shell layer, it will spread to the entire application, and the impact of version upgrades will be large.&lt;/p&gt;

&lt;h2&gt;
  
  
  Summary
&lt;/h2&gt;

&lt;p&gt;We looked at the Unified SPA pattern, which is an extension of the Linked Application pattern, and while introducing an App Shell layer has its disadvantages. As a simple Micro Frontends, this is the first one you can consider adopting.&lt;/p&gt;

</description>
      <category>microservices</category>
      <category>microfeontends</category>
      <category>javascript</category>
    </item>
    <item>
      <title>Micro Frontends Patterns#7: Linked Application</title>
      <dc:creator>okmttdhr</dc:creator>
      <pubDate>Sun, 27 Dec 2020 02:03:48 +0000</pubDate>
      <link>https://dev.to/okmttdhr/micro-frontends-patters-linked-application-56ij</link>
      <guid>https://dev.to/okmttdhr/micro-frontends-patters-linked-application-56ij</guid>
      <description>&lt;p&gt;Linked Application is a simple architecture that navigates multiple applications with hyperlinks.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--WB_yRdPv--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/hydq8pt1nescfszxp89d.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--WB_yRdPv--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/hydq8pt1nescfszxp89d.png" alt="eh5p3gt0o3zi5o0ne4rayv7b3onn"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;A common example is a standalone user account application that is linked from multiple applications. In this case, services related to a user account are done only in the account application, and other applications hyperlink to it from a header, user menu, etc. "Google Account" can be an example.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--LEccBv6c--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/kp7qqyip18h1q9jtycl7.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--LEccBv6c--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/kp7qqyip18h1q9jtycl7.png" alt="ec2jydjawg8r936atbjgf1mv2hmd"&gt;&lt;/a&gt; &lt;/p&gt;

&lt;p&gt;It is also possible that applications can be in the same domain. In this case, each page has its own independent development team and deploy pipeline.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--kKVuKAHq--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/zczllsj3mv0n2wuojszu.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--kKVuKAHq--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/zczllsj3mv0n2wuojszu.png" alt="nxpq75hzdroqa2i6cidpbaa96xnd"&gt;&lt;/a&gt; &lt;/p&gt;

&lt;p&gt;Linked Application is one of the easiest Micro Frontends to get started with, and I'm sure we've all seen it at least once.&lt;/p&gt;

&lt;h2&gt;
  
  
  iframe
&lt;/h2&gt;

&lt;p&gt;Although not a Linked Application, we can accomplish Micro Frontends with iframes, as Spotify does. Compared to Linked Application, you can use it more flexibly by embedding it in a part of the page, and since it is a old technology, it is supported by all browsers. However, there are some issues that need to be considered, such as performance overhead, SEO considerations, accessibility, and motivation of engineers.&lt;/p&gt;

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

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

&lt;p&gt;The main advantage of this pattern, which seems not to be cool, is that it allows applications to be loosely coupled. The fact that the applications are isolated also means that each system is robust. If one application goes down, the others are unaffected.&lt;/p&gt;

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

&lt;p&gt;On the other hand, there is the problem of communication difficulties due to the isolation. As the name suggests, applications can only communicate with each other through "links". Also, although it is a simple architecture, it makes it difficult to manage common parts such as headers, and it also creates redundancies such as duplicate development for each team. The hyperlink experience is also not great for users.&lt;/p&gt;

&lt;h2&gt;
  
  
  Summary
&lt;/h2&gt;

&lt;p&gt;Linked Application has been one of the most common patterns for a long time because it is quick to implement, but it is important to understand its drawbacks.&lt;/p&gt;

</description>
      <category>microservices</category>
      <category>microfrontends</category>
      <category>javascript</category>
    </item>
    <item>
      <title>Micro Frontends Patterns#6: Isomorphic JavaScript</title>
      <dc:creator>okmttdhr</dc:creator>
      <pubDate>Wed, 23 Dec 2020 00:29:10 +0000</pubDate>
      <link>https://dev.to/okmttdhr/micro-frontends-patterns-isomorphic-javascript-3d7g</link>
      <guid>https://dev.to/okmttdhr/micro-frontends-patterns-isomorphic-javascript-3d7g</guid>
      <description>&lt;p&gt;Isomorphic JavaScript (Universal JavaScript) refers to JavaScript or JavaScript applications that work on both the client and server.&lt;/p&gt;

&lt;p&gt;This chapter show you some use cases and technologies.&lt;/p&gt;

&lt;h2&gt;
  
  
  Server Side Rendering
&lt;/h2&gt;

&lt;p&gt;A typical example is Server Side Rendering (SSR) in React applications, which uses ReactDOMServer to generate markups on the server side and return dynamic views from the server side.&lt;/p&gt;

&lt;p&gt;This solves the performance bottleneck of Client Side Rendering, SEO optimization and OGP issues. It also allows the use of Virtual DOM libraries such as React as "templates", avoiding the traditional inefficient client side programming with template engines.&lt;/p&gt;

&lt;p&gt;SSR in this context includes a technique called Rehydration. The ability to do rehydration means that, for example, Client Side Rendering is also possible. The SSR application is displayed for initial rendering only, followed by rehydration on the client side, and Client Side Rendering thereafter.&lt;/p&gt;

&lt;h2&gt;
  
  
  BFF
&lt;/h2&gt;

&lt;p&gt;BFF, or Node.js as an API Gateway layer, can be considered as an extension of Isomorphic JavaScript as SSR. Basically, let Backend Microservices do the CPU-heavy processing, and BFF communicates with them via API. I think it fits well as a BFF layer &lt;sup id="fnref1"&gt;1&lt;/sup&gt;, partly because &lt;del&gt;Node.js doesn't have very nice ORM&lt;/del&gt; I personally don't like Node.js ORM as much as those in other languages &lt;sup id="fnref2"&gt;2&lt;/sup&gt;.&lt;/p&gt;

&lt;p&gt;As I mentioned in the Microservice Architecture chapter, the Gateway layer needs some work to keep it simple. Node.js's ease of implementing asynchronous &amp;amp; non-blocking I/O and TypeScript's strong type support are not bad for a language that runs on this layer.&lt;/p&gt;

&lt;h2&gt;
  
  
  Next.js
&lt;/h2&gt;

&lt;p&gt;SSR had some technical complications. For example, there are processes for fetching data that you want to run only on the server side, and processes for rehydrating data in a state management layer such as Redux.&lt;/p&gt;

&lt;p&gt;Frameworks such as Next.js and Nuxt.js have emerged as technologies to cover these troublesome issues. They were not just for SSR, but they had an impact at the time simply because they wrapped up the difficulties of SSR.&lt;/p&gt;

&lt;p&gt;In addition, &lt;code&gt;API route&lt;/code&gt; in Next.js allows for backend implementation, so we can expect to see uses such as BFFs and endpoints for SSG, which I mentioned in the JAMstack chapter. The fact that you can use universal bundling with almost zero configuration is also attractive.&lt;/p&gt;

&lt;p&gt;It is also unique in that it can be used to build a hybrid of SSR, SSG, and Incremental Static Regeneration. For more information, please visit &lt;a href="https://nextjs.org"&gt;https://nextjs.org&lt;/a&gt;.&lt;/p&gt;

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

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

&lt;p&gt;The fact that the Gateway layer can be developed in one language and the "frontend" of the application can be taken care of using only JavaScript will reduce switching costs and will be effective in team development of distributed systems. It is also good at handling large numbers of requests due to the aforementioned asynchronous and non-blocking I/O nature.&lt;/p&gt;

&lt;p&gt;Although it not about the Web, it also has high portability as a program, in that it can run on relatively any device, anywhere. The client is implemented in JavaScript, and can often be used as a set.&lt;/p&gt;

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

&lt;p&gt;Rather than the disadvantages of Isomorphic JavaScript itself, you need to understand the weak points of Node.js and JavaScript. For example, one of the biggest ones is the aforementioned CPU-heavy characteristics.&lt;/p&gt;

&lt;p&gt;As for JavaScript as a language, I feel that it has a complex build process and ecosystem. In today's JS world, considering TypeScript, testing, etc., building is a prerequisite, and considering understanding and using the surrounding ecosystem and compiler specifications, it is a relatively complex world compared to other languages. TypeScript is certainly wonderful, but I think the complexity of it is difficult to understand for different language people.&lt;/p&gt;

&lt;p&gt;And it is too free as a language, that can be both an advantage and a disadvantage. JavaScript is a multi-paradigm language that can be written in many different ways, and some engineers may find it difficult to implement asynchronous processing or package structures.&lt;/p&gt;

&lt;h2&gt;
  
  
  Summary
&lt;/h2&gt;

&lt;p&gt;Isomorphic JavaScript offers the choice to provide the entire Frontend of an application with JavaScript. When used in the right way for the right use case, it has proven to have advantages that are second to none to other languages.&lt;/p&gt;




&lt;ol&gt;

&lt;li id="fn1"&gt;
&lt;p&gt;I don't like NoSQL as an escape either. ↩&lt;/p&gt;
&lt;/li&gt;

&lt;li id="fn2"&gt;
&lt;p&gt;I have only used Sequelize and TypeORM. ↩&lt;/p&gt;
&lt;/li&gt;

&lt;/ol&gt;

</description>
      <category>microfrontends</category>
      <category>microservices</category>
      <category>javascript</category>
    </item>
    <item>
      <title>Micro Frontends Patterns#5: Microservice Architecture</title>
      <dc:creator>okmttdhr</dc:creator>
      <pubDate>Tue, 22 Dec 2020 00:46:33 +0000</pubDate>
      <link>https://dev.to/okmttdhr/micro-frontends-patterns-microservice-architecture-1j36</link>
      <guid>https://dev.to/okmttdhr/micro-frontends-patterns-microservice-architecture-1j36</guid>
      <description>&lt;p&gt;The Microservice Architecture is an architecture that combines applications with the following characteristics&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Loosely coupled, Highly cohesive&lt;/li&gt;
&lt;li&gt;Can be deployed independently&lt;/li&gt;
&lt;li&gt;Bounded by a business domain&lt;/li&gt;
&lt;li&gt;Accessible via some communication protocol&lt;/li&gt;
&lt;li&gt;Developed by an autonomous team&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;If you want to know more about Microservice Architecture, please refer to the book &lt;a href="https://learning.oreilly.com/library/view/building-microservices/9781491950340/" rel="noopener noreferrer"&gt;Building Microservices&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;In this section, I'll show you some of the patterns in communicating with Microservices, focusing on the Frontend.&lt;/p&gt;

&lt;h2&gt;
  
  
  Service Discovery
&lt;/h2&gt;

&lt;p&gt;Service Discovery is a pattern that creates an abstraction layer of multiple interfaces on the Frontend side and interacts with the Backend.&lt;/p&gt;

&lt;p&gt;The pattern is to create a layer that abstracts multiple interfaces on the Frontend and interact with the Backend. &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%2Fi%2Fjb68zgcihieaest153we.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%2Fi%2Fjb68zgcihieaest153we.png"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;For example, you can imagine JSON like the following. In practice, you may want to create a layer of abstraction for the request, such as a Repository Pattern.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight json"&gt;&lt;code&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"micro_service_foo"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"v1"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"https://api.foo.service.com/v1"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"special"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"https://api.foo.service.com/special"&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"micro_service_bar"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"v1"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"https://api.bar.service.com/v1"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"v2"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"https://api.bar.service.com/v2"&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;One of the nice things about Service Discovery is that you can freely combine them in the Frontend; in the context of Micro Frontends, multiple components may each request different Microservices, and it may be convenient to change them freely in the App Shell layer.&lt;/p&gt;

&lt;p&gt;We can also get JSON returned by the API.&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%2Fi%2Fv1s5vdhzisn4sjppfbue.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%2Fi%2Fv1s5vdhzisn4sjppfbue.png"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;In this case, it is easier to do version upgrades or changes on the server side. This pattern is inspired by &lt;a href="https://microservices.io/patterns/client-side-discovery.html" rel="noopener noreferrer"&gt;Client-side service discovery&lt;/a&gt; used in Backend Microservices.&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%2Fi%2Fi23qn38ot4r1nppqf6fb.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%2Fi%2Fi23qn38ot4r1nppqf6fb.png"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Gateway Aggregation
&lt;/h2&gt;

&lt;p&gt;Gateway Aggregation is a pattern that combines requests to multiple Microservices into a single endpoint (API Gateway) (from &lt;a href="https://docs.%20microsoft.com/en-us/azure/architecture/patterns/gateway-aggregation" rel="noopener noreferrer"&gt;Microsoft Cloud Design Patterns&lt;/a&gt;.&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%2Fi%2Fdkjlkuv6trsqauazr4c8.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%2Fi%2Fdkjlkuv6trsqauazr4c8.png"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The abstraction layer at the client, as it was in Service Discovery, is gone and simplified, and performance overhead is improved.&lt;/p&gt;

&lt;h2&gt;
  
  
  Backends for Frontends
&lt;/h2&gt;

&lt;p&gt;Backends for Frontends (BFF) is a pattern that is similar to Gateway Aggregation, but provides an interface for each specific Frontend application (from &lt;a href="https://docs.microsoft.com/en-us/azure/architecture/patterns/backends-for-frontends" rel="noopener noreferrer"&gt;Microsoft Cloud Design Patterns&lt;/a&gt;).&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%2Fi%2F0wpyh4in6bn0h1xukwow.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%2Fi%2F0wpyh4in6bn0h1xukwow.png"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;With Gateway Aggregation,  we had the following problems.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Different data that different Frontend teams wants causes the data manipulation process in Frontend.&lt;/li&gt;
&lt;li&gt;Data that is only used by one application can be added to the interface, which can be redundant.&lt;/li&gt;
&lt;li&gt;Difficulty in updating Backend APIs by considering all platforms.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The goal of this pattern is to provide a more application-specific interface, so that the interactions are optimized for each of them.&lt;/p&gt;

&lt;h2&gt;
  
  
  The case of Netflix
&lt;/h2&gt;

&lt;p&gt;Netflix is using GraphQL Federation for their API Gateway.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://netflixtechblog.com/how-netflix-scales-its-api-with-graphql-federation-part-1-ae3557c187e2" rel="noopener noreferrer"&gt;How Netflix Scales its API with GraphQL Federation | Netflix TechBlog&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;For more information on GraphQL Federation, please see the following&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://www.apollographql.com/docs/federation/" rel="noopener noreferrer"&gt;Introduction to Apollo Federation - Apollo Federation - Apollo GraphQL Docs&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://www.apollographql.com/docs/federation/federation-spec/" rel="noopener noreferrer"&gt;Apollo Federation specification - Apollo Federation - Apollo GraphQL Docs&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Netflix is facing the following problems with a simple API Gateway&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Lack of domain knowledge on the part of the Gateway team&lt;/li&gt;
&lt;li&gt;The connection to the Gateway had to be done manually.&lt;/li&gt;
&lt;li&gt;A lot of things to do for the Gateway team due to the above&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;In order to solve this problem, they have taken an approach to merge each schema with GraphQL Federation and reduce the scope of responsibility of Gateway. In the end, the architecture became the following "federated gateway architecture" to realize One Graph API.&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%2Fi%2Fk8tykx4w4qcv9vguavkj.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%2Fi%2Fk8tykx4w4qcv9vguavkj.png" alt="4feftderqxvgwpah6onv60hr31v2"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Each Microservices team, which is familiar with the domain, provides its own schema, and the Gateway team is responsible for managing the Graph. I feel that this leads to the topic of "Who develops the BFF?" which will be discussed later.&lt;/p&gt;

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

&lt;p&gt;One of the topics of creating an API Gateway is "Who will develop the API Gateway?". For example, if you are creating a BFF, it seems correct for the Frontend engineer to have a responsibility of it, but in reality, you will consider the engineer's skills and development costs.&lt;/p&gt;

&lt;p&gt;Another topic is the common function; in a BFF, only application-specific logic should be placed, but there may be an increase in duplicated code in multiple BFFs. For these, the basic idea is &lt;code&gt;Duplication over the wrong abstraction&lt;/code&gt;, but how should it be extracted? Should we really extract them? Which team will be responsible for it? These will be a point of discussion. It is also necessary to design it so that it is loosely coupled with the Microservices it calls.&lt;/p&gt;

&lt;p&gt;In the context of Micro Frontends, we could be talking about, at what level do you want to use the API Gateway? or should use Service Discovery?&lt;/p&gt;

&lt;h2&gt;
  
  
  Summary
&lt;/h2&gt;

&lt;p&gt;In this article, we introduced how to interact with Microservices from the Frontend in the recent situation.&lt;/p&gt;

&lt;p&gt;Instead of interacting with multiple Microservices directly, there is a trend to abstract the complexity by providing one interface for one Frontend app.&lt;/p&gt;

</description>
      <category>microservices</category>
      <category>microfrontends</category>
      <category>javascript</category>
    </item>
  </channel>
</rss>
