<?xml version="1.0" encoding="utf-8"?><feed xmlns="http://www.w3.org/2005/Atom" xml:lang="en-US"><generator uri="https://jekyllrb.com/" version="3.10.0">Jekyll</generator><link href="https://adasq.github.io/feed.xml" rel="self" type="application/atom+xml" /><link href="https://adasq.github.io/" rel="alternate" type="text/html" hreflang="en-US" /><updated>2025-07-22T15:40:11+07:00</updated><id>https://adasq.github.io/feed.xml</id><title type="html">Adam Płócieniak</title><subtitle>Interested in javascript / reactjs More on &lt;a href=&quot;https://github.com/adasq&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;@github&lt;/a&gt;.</subtitle><author><name>Adam Płócieniak</name></author><entry><title type="html">How Does React Work? Brief History - PART 1</title><link href="https://adasq.github.io/how-does-react-work-part-1/" rel="alternate" type="text/html" title="How Does React Work? Brief History - PART 1" /><published>2021-08-12T13:00:00+07:00</published><updated>2021-08-12T13:00:00+07:00</updated><id>https://adasq.github.io/how-does-react-work-part-1</id><content type="html" xml:base="https://adasq.github.io/how-does-react-work-part-1/"><![CDATA[<p>Read full article at Hotjar’s tech blog: <br />
<a href="https://dev.to/hotjar/how-does-react-work-brief-history-part-1-1d12">dev.to/hotjar/how-does-react-work-brief-history-part-1-1d12</a></p>]]></content><author><name>Adam Płócieniak</name></author><category term="javascript" /><category term="react" /><category term="react fiber" /><summary type="html"><![CDATA[How Does React Work? Brief History - PART 1]]></summary></entry><entry><title type="html">Scheduling in React 16.x</title><link href="https://adasq.github.io/scheduling-in-react-16-x/" rel="alternate" type="text/html" title="Scheduling in React 16.x" /><published>2020-06-24T16:00:00+07:00</published><updated>2020-06-24T16:00:00+07:00</updated><id>https://adasq.github.io/scheduling-in-react-16-x</id><content type="html" xml:base="https://adasq.github.io/scheduling-in-react-16-x/"><![CDATA[<h1 id="what-is-scheduler">What is scheduler?</h1>

<figure>
<img src="/assets/img/scheduling-in-react-16-x/background.jpeg" alt="queue" />
<figcaption>Fig 1. queue</figcaption>
</figure>

<p>Let’s start with some theory.</p>

<p>JavaScript is a single-threaded language. This means we have one call stack which can perform one piece of code at the time. Among executing your code, the browser needs to perform a different kind of work. This includes:</p>

<ul>
  <li>managing events (user clicks handlers, <code class="language-plaintext highlighter-rouge">setTimeout</code> callbacks, etc.)</li>
  <li>layout calculations (building DOM / CSSOM) and</li>
  <li>repaints (based on the layout calculations)</li>
</ul>

<p>Let’s focus on the last one. Within one second, browsers usually repaint 60 times, which means there is a single repaint every 16.6 ms (more or less, depending on the environment).</p>

<p>When you run a piece of synchronous code for about one second, you will accidentally drop ~60 frames which introduce delays, hits UX, and makes your app unresponsive.</p>

<p>So, the primary objective of the scheduler is to balance between all the activities being performed within the browser, not starve any of them as well as keeps your app repaint-aware.</p>

<p>But, as developers, should we care? No doubt, we should be aware of the problem. Nowadays, we outsource quite a lot of responsibilities to third party entities while developing our apps.</p>

<p>Web frameworks do a lot for us, they manage routing and state, provide change-detection mechanisms, two-way-data-binding (Angular/Vue.js), update DOM directly, and many, many more. They act as a middleware between us and the browser, so it seems to be a great place for scheduling problem to be solved, right?</p>

<p>And web frameworks do so. There is no exception for React as well (at least, React 16.x).</p>

<h1 id="trying-to-implement-a-simple-scheduler">Trying to implement a simple scheduler</h1>

<p>I will explain how it is managed by React, but, to understand the underlying problem, let’s write some simple piece of code…</p>

<p>Let’s simulate a heavy browser app:</p>

<div class="language-js highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="nx">setInterval</span><span class="p">(()</span> <span class="o">=&gt;</span> <span class="p">{</span>
    <span class="nb">document</span><span class="p">.</span><span class="nx">body</span><span class="p">.</span><span class="nx">appendChild</span><span class="p">(</span><span class="nb">document</span><span class="p">.</span><span class="nx">createTextNode</span><span class="p">(</span><span class="dl">'</span><span class="s1">hi</span><span class="dl">'</span><span class="p">))</span>
<span class="p">},</span> <span class="mi">3</span><span class="p">)</span>
</code></pre></div></div>

<p>It forces the browser to do a repaint (caused by DOM manipulations being made each 3 ms). Now, consider this code:</p>

<div class="language-js highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="nx">setInterval</span><span class="p">(()</span> <span class="o">=&gt;</span> <span class="p">{</span>
    <span class="nb">document</span><span class="p">.</span><span class="nx">body</span><span class="p">.</span><span class="nx">appendChild</span><span class="p">(</span><span class="nb">document</span><span class="p">.</span><span class="nx">createTextNode</span><span class="p">(</span><span class="dl">'</span><span class="s1">hi</span><span class="dl">'</span><span class="p">))</span>
<span class="p">},</span> <span class="mi">3</span><span class="p">)</span>

<span class="nx">render</span><span class="p">()</span>

<span class="kd">function</span> <span class="nx">render</span><span class="p">()</span> <span class="p">{</span>
    <span class="k">for</span> <span class="p">(</span><span class="kd">let</span> <span class="nx">i</span> <span class="o">=</span> <span class="mi">0</span><span class="p">;</span> <span class="nx">i</span> <span class="o">&lt;</span> <span class="mi">20</span><span class="p">;</span> <span class="nx">i</span><span class="o">++</span><span class="p">)</span> <span class="p">{</span>
        <span class="nx">performUnitOfWork</span><span class="p">()</span>
    <span class="p">}</span>
<span class="p">}</span>

<span class="kd">function</span> <span class="nx">performUnitOfWork</span><span class="p">()</span> <span class="p">{</span>
    <span class="nx">sleep</span><span class="p">(</span><span class="mi">5</span><span class="p">)</span>
<span class="p">}</span>

<span class="kd">function</span> <span class="nx">sleep</span><span class="p">(</span><span class="nx">milliseconds</span><span class="p">)</span> <span class="p">{</span>
    <span class="c1">// sleep for given {milliseconds} period (synchronous)</span>
<span class="p">}</span>
</code></pre></div></div>

<p>What is the impact of our browser rendering mechanism? Well, <code class="language-plaintext highlighter-rouge">render</code> is synchronous, so it freezes browser for 100ms (20 * 5ms = 100ms). No repaint can be made within the time. User input event callbacks neither. Let’s take a look into Chrome’s “Performance tool” output for a given code:</p>

<figure>
<img src="/assets/img/scheduling-in-react-16-x/performance-1.png" alt="Performance listing" />
<figcaption>Fig 2. Performance listing (blocking thread with sleep function)</figcaption>
</figure>

<p>In the example, we drop frames for more than 100ms (see vertical dotted lines, they show you when the frame ends). As mentioned earlier — the browser does a repaint each ~16.6 ms (60 frames per second). In this case, repaints are delayed which freezes any animation performing at the time. User input handlers are delayed as well. This is not what we want, right?</p>

<p>Now, let’s assume the provided <code class="language-plaintext highlighter-rouge">render</code> function is a React 15.x implementation of render mechanism. During the process, React tracks changes, calls our life-cycle methods, compares props, etc. It is a time-consuming process that might take a long time to compute, especially in heavy apps.</p>

<p>Does the React 15.x have a scheduler mechanism at all? Nope, it does not, so there is no difference between our synchronous <code class="language-plaintext highlighter-rouge">render</code> function and React 15.x <code class="language-plaintext highlighter-rouge">render</code> implementation. Here is <a href="https://claudiopro.github.io/react-fiber-vs-stack-demo/stack.html">an example React 15.x application</a> , which do a lot of computation, without scheduler implementation:</p>

<figure>
<img src="/assets/img/scheduling-in-react-16-x/react-stack.png" alt="React 15.x heavy computation app" />
<figcaption>Fig 3. React 15.x heavy computation app</figcaption>
</figure>

<p>Quiet laggy, right? Let’s go back to our example… How can we improve this synchronous-based rendering mechanism? How about adding <code class="language-plaintext highlighter-rouge">setTimeout</code>?</p>

<div class="language-js highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="p">...</span>
<span class="kd">function</span> <span class="nx">render</span><span class="p">()</span> <span class="p">{</span>
    <span class="nx">performUnitOfWork</span><span class="p">()</span>
    <span class="nx">setTimeout</span><span class="p">(</span><span class="nx">render</span><span class="p">,</span> <span class="mi">0</span><span class="p">)</span>
<span class="p">}</span>
<span class="p">...</span>
</code></pre></div></div>

<p>What are the results?</p>

<figure>
<img src="/assets/img/scheduling-in-react-16-x/performance-2.png" alt="Performance listing" />
<figcaption>Fig 4. Performance listing (with setTimeout)</figcaption>
</figure>

<p>Yep, way better, our frames are no longer delayed. Our <code class="language-plaintext highlighter-rouge">performUnitOfWork</code> function is being handled separately, on each frame. Repaints are being made regularly — with no frame delay.</p>

<p>So, is it the way the scheduling problem is being solved for React 16.x apps? Not really. Among entire internal engine rewrite (so-called React Fiber) React team has introduced a dedicated module - “React Scheduler” - to address scheduling issues. How it works? I will explain it soon, but firs t— we need to introduce… <a href="https://developer.mozilla.org/en-US/docs/Web/API/Channel_Messaging_API">Channel Messaging API</a>.</p>

<h1 id="messagechannel-based-scheduling">MessageChannel-based scheduling</h1>

<p>What it does is a simple thing. It lets you communicate across different JavaScript contexts, i.e. between your code and iframe, or between your code a web worker’s context.</p>

<p>Consider the following example:</p>

<div class="language-js highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="c1">// index.html</span>
<span class="o">&lt;</span><span class="nx">iframe</span> <span class="nx">src</span><span class="o">=</span><span class="dl">"</span><span class="s2">iframe-page.html</span><span class="dl">"</span><span class="o">&gt;&lt;</span><span class="sr">/iframe</span><span class="err">&gt;
</span><span class="o">&lt;</span><span class="nx">script</span><span class="o">&gt;</span>
<span class="kd">var</span> <span class="nx">iframe</span> <span class="o">=</span> <span class="nb">document</span><span class="p">.</span><span class="nx">querySelector</span><span class="p">(</span><span class="dl">'</span><span class="s1">iframe</span><span class="dl">'</span><span class="p">)</span>
<span class="kd">var</span> <span class="nx">channel</span> <span class="o">=</span> <span class="k">new</span> <span class="nx">MessageChannel</span><span class="p">()</span>
<span class="nx">iframe</span><span class="p">.</span><span class="nx">addEventListener</span><span class="p">(</span><span class="dl">'</span><span class="s1">load</span><span class="dl">'</span><span class="p">,</span> <span class="p">()</span> <span class="o">=&gt;</span> <span class="p">{</span>
    <span class="nx">channel</span><span class="p">.</span><span class="nx">port1</span><span class="p">.</span><span class="nx">onmessage</span> <span class="o">=</span> <span class="nx">e</span> <span class="o">=&gt;</span> <span class="nx">console</span><span class="p">.</span><span class="nx">log</span><span class="p">(</span><span class="nx">e</span><span class="p">.</span><span class="nx">data</span><span class="p">)</span>
    <span class="nx">iframe</span><span class="p">.</span><span class="nx">contentWindow</span><span class="p">.</span><span class="nx">postMessage</span><span class="p">(</span><span class="dl">'</span><span class="s1">hi!</span><span class="dl">'</span><span class="p">,</span> <span class="dl">'</span><span class="s1">*</span><span class="dl">'</span><span class="p">,</span> <span class="p">[</span><span class="nx">channel</span><span class="p">.</span><span class="nx">port2</span><span class="p">])</span>
<span class="p">})</span>
<span class="o">&lt;</span><span class="sr">/script</span><span class="err">&gt;
</span><span class="c1">// iframe-page.html</span>
<span class="o">&lt;</span><span class="nx">script</span><span class="o">&gt;</span>
<span class="nb">window</span><span class="p">.</span><span class="nx">addEventListener</span><span class="p">(</span><span class="dl">'</span><span class="s1">message</span><span class="dl">'</span><span class="p">,</span> <span class="nx">event</span> <span class="o">=&gt;</span> <span class="p">{</span>
    <span class="nx">console</span><span class="p">.</span><span class="nx">log</span><span class="p">(</span><span class="nx">event</span><span class="p">.</span><span class="nx">data</span><span class="p">)</span>
    <span class="nx">event</span><span class="p">.</span><span class="nx">ports</span><span class="p">[</span><span class="mi">0</span><span class="p">].</span><span class="nx">postMessage</span><span class="p">(</span>
        <span class="dl">'</span><span class="s1">Message back from the IFrame</span><span class="dl">'</span>
    <span class="p">)</span>
<span class="p">})</span>
<span class="o">&lt;</span><span class="sr">/script</span><span class="err">&gt;
</span></code></pre></div></div>

<p>What you need to do is to set a listener on one port (<code class="language-plaintext highlighter-rouge">port1</code>), and transfer another (<code class="language-plaintext highlighter-rouge">port2</code>, which will be used by sender) into another context (i.e. to iframe) using <code class="language-plaintext highlighter-rouge">postMessage</code> API. Then you can communicate in both directions.</p>

<p>But do we need to communicate with iframe or WebWorker in our app? Not really, but the API (alongside communication capabilities) has another advantage. It lets you kindly schedule work that respects other browser activities, such as rendering, DOM calculation, etc.</p>

<p>How? By the so-called “messages loop” mechanism. Now, let me replace the previous implementation of synchronous <em>render</em> function with this:</p>

<div class="language-js highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="nx">setInterval</span><span class="p">(()</span> <span class="o">=&gt;</span> <span class="p">{</span>
    <span class="nb">document</span><span class="p">.</span><span class="nx">body</span><span class="p">.</span><span class="nx">appendChild</span><span class="p">(</span><span class="nb">document</span><span class="p">.</span><span class="nx">createTextNode</span><span class="p">(</span><span class="dl">'</span><span class="s1">hi</span><span class="dl">'</span><span class="p">))</span>
<span class="p">},</span> <span class="mi">3</span><span class="p">)</span>

<span class="kd">const</span> <span class="nx">channel</span> <span class="o">=</span> <span class="k">new</span> <span class="nx">MessageChannel</span><span class="p">()</span>

<span class="nx">render</span><span class="p">()</span>

<span class="kd">function</span> <span class="nx">render</span><span class="p">()</span> <span class="p">{</span>
    <span class="nx">channel</span><span class="p">.</span><span class="nx">port1</span><span class="p">.</span><span class="nx">onmessage</span> <span class="o">=</span> <span class="nx">onMessageReceived</span>
    <span class="nx">channel</span><span class="p">.</span><span class="nx">port2</span><span class="p">.</span><span class="nx">postMessage</span><span class="p">(</span><span class="kc">null</span><span class="p">)</span>
<span class="p">}</span>

<span class="kd">function</span> <span class="nx">onMessageReceived</span><span class="p">(</span><span class="nx">event</span><span class="p">)</span> <span class="p">{</span>
    <span class="nx">performUnitOfWork</span><span class="p">()</span>
    <span class="nx">channel</span><span class="p">.</span><span class="nx">port2</span><span class="p">.</span><span class="nx">postMessage</span><span class="p">(</span><span class="kc">null</span><span class="p">)</span>
<span class="p">}</span>

<span class="kd">function</span> <span class="nx">performUnitOfWork</span><span class="p">()</span> <span class="p">{</span>
    <span class="nx">sleep</span><span class="p">(</span><span class="mi">5</span><span class="p">)</span>
<span class="p">}</span>
</code></pre></div></div>

<p>Our render function was updated to take advantage of MessageChannel API. We just created the “message loop”. Sending a message on <code class="language-plaintext highlighter-rouge">port2</code> (inside <code class="language-plaintext highlighter-rouge">render</code> function) forces <code class="language-plaintext highlighter-rouge">onmessage</code> (which is <code class="language-plaintext highlighter-rouge">onMessageReceived</code>) to be called, which do some calculations (<code class="language-plaintext highlighter-rouge">performUnitOfWork</code>). Then once again it forces sending a message on <code class="language-plaintext highlighter-rouge">port2</code>, which eventually… yep… you see the pattern, right? That is how the message loop is created.</p>

<p>Now let’s look at our performance profile:</p>

<figure>
<img src="/assets/img/scheduling-in-react-16-x/performance-3.png" alt="Performance listing" />
<figcaption>Fig 5. Performance listing (with message-loop)</figcaption>
</figure>

<p>Repaints are being made each 14ms / 19ms. During the single frame, we can see <code class="language-plaintext highlighter-rouge">performUnitOfWork</code> is executed even 3 times which is better than <code class="language-plaintext highlighter-rouge">setTimeout</code> approach. What is more, in the <code class="language-plaintext highlighter-rouge">setTimeout</code> solution there were lots more empty spaces between “execution bars” where the browser does nothing. It’s not the case in the message loop.</p>

<h1 id="scheduling-in-react-16x">Scheduling in React 16.x</h1>

<p>And here comes the fun part. I just described to you how does the most recent implementation of React Scheduler works. It uses the MessageGlobal API to achieve their in-browser scheduling goals. This approach is even better comparing to the <code class="language-plaintext highlighter-rouge">setTimeout</code> implementation, as it is eventually able to perform even more work within the frame.</p>

<p>Now, this approach requires splitting a work into smaller chunks. Our example implementation of render function performs computation (<code class="language-plaintext highlighter-rouge">performUnitOfWork</code>) for about 5ms. And there is no difference for React implementation — it also splits work into smaller chunks to be executed within 5ms.</p>

<p>Why do we want to break our execution into smaller chunks? To let the main thread to execute pending events / do repaints / manage animation in the meantime, so there are no UX lags.</p>

<p>Consider this piece of React <a href="https://github.com/facebook/react/blob/v16.13.1/packages/react-reconciler/src/ReactFiberWorkLoop.js#L1467-L1472">code</a>:</p>

<figure>
<img src="/assets/img/scheduling-in-react-16-x/work-loop-concurrent.png" alt="workLoopConcurrent implementation" />
<figcaption>Fig 6. React's workLoopConcurrent function</figcaption>
</figure>

<p>This is one of the most important fragment of React code. Main work loop. As mentioned earlier, the latest version of React (in the contrary to React 15.x) lets you split work into small chunks (<code class="language-plaintext highlighter-rouge">workInProgress</code>). Each of them is being handled (<code class="language-plaintext highlighter-rouge">performUnitOfWork</code>) one by one, as long as:</p>

<ol>
  <li>we have some work to do (<code class="language-plaintext highlighter-rouge">workInProgress !== null</code>)</li>
  <li>and <code class="language-plaintext highlighter-rouge">shouldYield()</code> returns false.</li>
</ol>

<p>So many synchronous work is being made within the <code class="language-plaintext highlighter-rouge">performUnitOfWork</code>. This piece of code comes from React’s “reconciler” mechanism. If you would like to find out more how React works under the hood, I strongly recommend you to search for “React Fiber” phrase. For the sake of the article, let’s assume <code class="language-plaintext highlighter-rouge">performUnitOfWork</code> is a function that walks our component tree, do change-detection computations, including call lifecycle methods, side-effects marking. It is a heart of React render process.</p>

<p>React Fiber is designed in the way, that each finished work result is being saved on the heap, so we can interrupt a <code class="language-plaintext highlighter-rouge">workLoopConcurrent</code> loop any time, and return to this later on.</p>

<p>But how do we know when to interrupt this work?</p>

<p>Here comes the <code class="language-plaintext highlighter-rouge">shouldYield</code> function which is a part of a “Scheduler” module. It has one responsibility — to decide whether to stop or continue working on tasks (<code class="language-plaintext highlighter-rouge">performUnitOfWork</code>). It returns <code class="language-plaintext highlighter-rouge">true</code> when we should stop computation and yield to the main thread, or <code class="language-plaintext highlighter-rouge">false</code> when we should proceed with our computation.</p>

<p>What is <a href="https://github.com/facebook/react/blob/v16.13.1/packages/scheduler/src/forks/SchedulerHostConfig.default.js#L164-L166">an implementation of shouldYield</a>?</p>

<figure>
<img src="/assets/img/scheduling-in-react-16-x/should-yield-to-host.png" alt="shouldYieldToHost function" />
<figcaption>Fig 7. React's shouldYieldToHost function</figcaption>
</figure>

<p>It checks whether we exceeded the deadline. What is the deadline? It is a <code class="language-plaintext highlighter-rouge">currentTime + 5ms</code>, so it appears, React scheduler breaks the execution each
5 ms, so the same, as presented in our example earlier in the article. There is <a href="https://github.com/facebook/react/blob/v16.13.1/packages/scheduler/src/forks/SchedulerHostConfig.default.js#L115-L119">a descriptive comment in the source code</a> presenting the way it works:</p>

<figure>
<img src="/assets/img/scheduling-in-react-16-x/yield-interval.png" alt="yieldInterval implementation" />
<figcaption>Fig 8. React's yieldInterval constant</figcaption>
</figure>

<p>Ok, where is a code presenting MessageChannel loop?</p>

<figure>
<img src="/assets/img/scheduling-in-react-16-x/perform-work-until-deadline.png" alt="performWorkUntilDeadline implementation" />
<figcaption>Fig 9. React's performWorkUntilDeadline function</figcaption>
</figure>

<p>It’s a little bit more complicated, but at <a href="https://github.com/facebook/react/blob/v16.13.1/packages/scheduler/src/forks/SchedulerHostConfig.default.js#L189-L226">the very bottom of the code listing</a>, we have a channel setup. You can briefly walk through the code comments to see the flow. Inside <code class="language-plaintext highlighter-rouge">performWorkUntilDeadline</code> there is <code class="language-plaintext highlighter-rouge">port.postMessage(null);</code> which keeps the message loop running.</p>

<p>We have also a piece of code, which prepares deadline (<code class="language-plaintext highlighter-rouge">deadline = currentTime + yieldInterval;</code>)</p>

<p>What is <code class="language-plaintext highlighter-rouge">scheduledHostCallback</code>? Long story short, it eventually triggers <code class="language-plaintext highlighter-rouge">workLoopConcurrent</code> presented earlier, which is the main work loop for the React render process. But the function is designed to return information, whether work is done or we should continue in the next message loop iteration (<code class="language-plaintext highlighter-rouge">hasMoreWork</code>).</p>

<p>Remember React 15.x app example which presents <a href="https://claudiopro.github.io/react-fiber-vs-stack-demo/stack.html">scheduling problem</a>?</p>

<figure>
<img src="/assets/img/scheduling-in-react-16-x/react-stack.png" alt="React 15.x heavy computation app" />
<figcaption>Fig 10. React 15.x heavy computation app</figcaption>
</figure>

<p><a href="https://claudiopro.github.io/react-fiber-vs-stack-demo/fiber.html">Here</a> you can see the same app but powered with React 16.x and its new React Fiber approach. Way better, right?</p>

<h1 id="reacts-scheduler-module">React’s Scheduler Module</h1>

<p><code class="language-plaintext highlighter-rouge">shouldYield</code> is not the only API exposed to the internal use for React devs.</p>

<figure>
<img src="/assets/img/scheduling-in-react-16-x/scheduler-api.png" alt="Scheduler API " />
<figcaption>Fig 11. Scheduler API</figcaption>
</figure>

<p>Considering the naming convention of <a href="https://github.com/facebook/react/blob/v16.13.1/packages/scheduler/src/Scheduler.js#L415-L434">the exposed functions</a>, we can conclude the module is still in development stage and API might change at the time.</p>

<p>Beware! This API is not intended to be used by the developers (like you and I). It is only for the team members/contributors internal usage. Of course, we use it, but indirectly.</p>

<p>You can see that the module exports function <code class="language-plaintext highlighter-rouge">runWithPriority</code> as well as some predefined constants (<code class="language-plaintext highlighter-rouge">UserBlockingPriority</code>, <code class="language-plaintext highlighter-rouge">NormalPriority</code>, <code class="language-plaintext highlighter-rouge">LowPriority</code>). It is not yet widely used in React, but the purpose of this is to let React schedule work with different priorities. We can expect more use cases to be supported with this API in further React releases.</p>

<p>What is the goal of such logic? To prioritize render of specific elements. In the Facebook app, it is more important to see news feed in the first place rather than header, footer or authenticated user section. In this case, we might render news feed related components with higher priority.</p>

<p>That’s the goal, hope to see some real use cases in upcoming React releases. It’s the future, but how about now? Where do we schedule a task using the Scheduler Module?</p>

<p>Well, hook’s effects <a href="https://github.com/facebook/react/blob/v16.13.1/packages/react-reconciler/src/ReactFiberWorkLoop.js#L2190-L2193">are being scheduled</a> using React Scheduler Module.</p>

<p>There is an enigmatic <code class="language-plaintext highlighter-rouge">enqueuePendingPassiveHookEffectMount</code> <a href="https://github.com/facebook/react/blob/v16.13.1/packages/react-reconciler/src/ReactFiberWorkLoop.js#L2182-L2196">function</a> which schedules <code class="language-plaintext highlighter-rouge">scheduleCallback</code> tasks with <code class="language-plaintext highlighter-rouge">NormalPriority</code>.</p>

<p>Let’s focus on the function name (<code class="language-plaintext highlighter-rouge">enqueuePendingPassiveHookEffectMount</code>) and find out what each name piece means:</p>

<ul>
  <li><code class="language-plaintext highlighter-rouge">enqueuePending</code>…: Scheduler module under the hood builds a list of callbacks (and assigned to it priorities) that needs to be called, so enqueue prefix is accurate in this context.</li>
  <li>…<code class="language-plaintext highlighter-rouge">PassiveHookEffect</code>…: This is real fun. What are <em>passive hook effects</em>?:</li>
</ul>

<p>We have two categories of effects, <em>passive</em> (<em>useEffect</em>) and <em>layout</em> (<em>useLayout</em>). Imagine this component:</p>

<div class="language-js highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="kd">const</span> <span class="nx">App</span> <span class="o">=</span> <span class="p">()</span> <span class="o">=&gt;</span> <span class="p">{</span>
    <span class="nx">useEffect</span><span class="p">(()</span> <span class="o">=&gt;</span> <span class="p">{</span>
        <span class="nx">console</span><span class="p">.</span><span class="nx">log</span><span class="p">(</span><span class="dl">'</span><span class="s1">passive effect</span><span class="dl">'</span><span class="p">)</span>
    <span class="p">},</span> <span class="p">[])</span>
    <span class="nx">useLayout</span><span class="p">(()</span> <span class="o">=&gt;</span> <span class="p">{</span>
        <span class="nx">console</span><span class="p">.</span><span class="nx">log</span><span class="p">(</span><span class="dl">'</span><span class="s1">layout effect</span><span class="dl">'</span><span class="p">)</span>
    <span class="p">},</span> <span class="p">[])</span>
<span class="p">}</span>
</code></pre></div></div>

<p>Which of the effects will be called first? <em>layout effect</em>. Why? As mentioned in docs, layout effect is being called just <em>after DOM mutation</em>, but before <em>browser render</em>. <em>Passive effects</em>, on the other hand, are deferred (using scheduler module) to be called <em>after browser render</em>.</p>

<ul>
  <li><em>…Mount</em>: The easiest way to understand <em>mount</em>, as well as <em>unmount</em> hook effect is the example:</li>
</ul>

<div class="language-js highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="nx">useEffect</span><span class="p">(()</span> <span class="o">=&gt;</span> <span class="p">{</span>
    <span class="c1">// this is "mount" passive hook</span>
    <span class="k">return</span> <span class="p">()</span> <span class="o">=&gt;</span> <span class="p">{</span>
        <span class="c1">// this is "unmount" passive hook</span>
    <span class="p">}</span>
<span class="p">},</span> <span class="p">[])</span>
</code></pre></div></div>

<p>Depending on the state of the component, React Reconciler module calls <em>mount</em> or <em>unmount</em> (i.e. while destroying component).</p>

<p>To sum it up all <em>passive effect</em> hooks are being called <em>asynchronously</em> — after browser repaint. This is a different approach comparing to the old implementation of <em>componentDidMount</em> or <em>componentDidUpdate</em> which block the browser from repainting. It is also worth noticing, that we have no alternative for <em>componentWillMount</em> or <em>componentWillUpdate</em> in hooks world. Those methods used to be a great place to introduce side-effects by developers (which might delay repaint process) so that they decide to deprecate it.</p>

<p>So, all the code you put inside <em>passive effect</em> goes through the React Scheduler.</p>

<h1 id="what-is-isinputpending">What is ‘isInputPending’?</h1>

<p>This feature is a result of Facebook engineers’ struggles to shorten a time a user input (i.e. click, mouse, keyboard events) are being performed.</p>

<p>Let’s look at the example:</p>

<div class="language-js highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="k">while</span> <span class="p">(</span><span class="nx">workQueue</span><span class="p">.</span><span class="nx">length</span> <span class="o">&gt;</span> <span class="mi">0</span><span class="p">)</span> <span class="p">{</span>
    <span class="k">if</span> <span class="p">(</span><span class="nb">navigator</span><span class="p">.</span><span class="nx">scheduling</span><span class="p">.</span><span class="nx">isInputPending</span><span class="p">())</span> <span class="p">{</span>
        <span class="c1">// Stop doing work if we have to handle an input event.</span>
        <span class="k">break</span><span class="p">;</span>
    <span class="p">}</span>
    <span class="kd">let</span> <span class="nx">job</span> <span class="o">=</span> <span class="nx">workQueue</span><span class="p">.</span><span class="nx">shift</span><span class="p">();</span>
    <span class="nx">job</span><span class="p">.</span><span class="nx">execute</span><span class="p">();</span>
<span class="p">}</span>
</code></pre></div></div>

<p>Via <code class="language-plaintext highlighter-rouge">navigator.scheduling.isInputPending()</code> we can find out whether there is a pending user event (click, mouse, keyboard, drag&amp;drop, etc.) so we can quickly react by yielding execution to the main thread (i.e. via the <code class="language-plaintext highlighter-rouge">break</code> statement) to handle the event.</p>

<p>Of course, it’s an experiment, not the official standard. It was available at the Chrome browser from version 74 to 78 (until Dec 4, 2019) as a part of <a href="https://developers.chrome.com/origintrials/#/view_trial/4544132024016830465">Chrome Origin Trials</a>.</p>

<p>You can read more about it both on <a href="https://github.com/WICG/is-input-pending">Gihub</a> as well as on <a href="https://engineering.fb.com/developer-tools/isinputpending-api/">Facebook’s engineering blog</a>.</p>

<p>But why do I describe this thing here, in scheduler-based article? Well, the interesting fact is, that <a href="https://github.com/facebook/react/blob/v16.13.1/packages/scheduler/src/forks/SchedulerHostConfig.default.js#L127-L161">the current implementation</a> of React Scheduler takes advantage of the feature:</p>

<figure>
<img src="/assets/img/scheduling-in-react-16-x/is-input-pending.png" alt="isInputPending implementation" />
<figcaption>Fig 12. React's isInputPending fallback implementation</figcaption>
</figure>

<p>After meeting specific requirements:</p>

<ul>
  <li>our React app build has a feature flag enabled (<code class="language-plaintext highlighter-rouge">enableIsInputPending</code>)</li>
  <li>we use Google Chrome with experimental <code class="language-plaintext highlighter-rouge">navigator.scheduling.isInputPending</code> feature enabled</li>
</ul>

<p>our React Scheduler module provides an improved version of <code class="language-plaintext highlighter-rouge">shouldYield</code> implementation, which yields execution to the main thread when there is any pending event waiting to be executed.</p>

<h1 id="history-of-scheduling-in-react">History of scheduling in React</h1>

<p>The problem with React 15.x was that the entire rendering process was being made synchronously. One, large, time-consuming, synchronous, and recursive (!) piece of code. This can’t co-operate with other browser activities, right?</p>

<p>At the very beginning of React Fiber’s development (v. 16.x), the React team was using <code class="language-plaintext highlighter-rouge">requestIdleCallback</code>. But, it appeared to be — as <a href="https://github.com/facebook/react/issues/11171#issuecomment-335431662">Dan Abramov said</a> — not as aggressive as the team wanted to.</p>

<figure>
<img src="/assets/img/scheduling-in-react-16-x/dan-said.png" alt="Dan's github post about requestIdleCallback" />
<figcaption>Fig 13. Dan about requestIdleCallback</figcaption>
</figure>

<p>The next step was to simulate <code class="language-plaintext highlighter-rouge">requestIdleCallback</code> with <code class="language-plaintext highlighter-rouge">requestAnimationFrame</code>. They tried to guess frame size and align React render mechanism with vsync cycle. And it was ok, until the latest made (by Andrew Clark) which gets rid of <code class="language-plaintext highlighter-rouge">requestAnimationFrame</code>, as described <a href="https://github.com/facebook/react/pull/16271">here</a>).</p>

<h1 id="summary">Summary</h1>

<p>As presented earlier, we have a couple of API which might be helpful while trying to implement scheduling mechanism, like <code class="language-plaintext highlighter-rouge">requestAnimationFrame</code>, <code class="language-plaintext highlighter-rouge">requestIdleCallback</code>, <em>message loop</em> (MessageChannel), or even <code class="language-plaintext highlighter-rouge">setTimeout</code>.</p>

<p>But hey — there were designed for slightly different purposes, weren’t they?</p>

<p>No doubt, the scheduling problem is on the table, some of the concepts have been announced lately within the browser vendor environments. If you are interested in the topic — I recommend <a href="https://github.com/WICG/main-thread-scheduling">WICG/main-thread-scheduling</a> repo as well as its “<a href="https://github.com/WICG/main-thread-scheduling#further-reading--viewing">Further Reading</a>” section.</p>]]></content><author><name>Adam Płócieniak</name></author><category term="javascript" /><category term="react" /><category term="react fiber" /><summary type="html"><![CDATA[How React Scheduler Works? What is the history of scheduling in React?]]></summary><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="https://adasq.github.io/assets/img/scheduling-in-react-16-x/background.jpeg" /><media:content medium="image" url="https://adasq.github.io/assets/img/scheduling-in-react-16-x/background.jpeg" xmlns:media="http://search.yahoo.com/mrss/" /></entry><entry><title type="html">Angular Router Protection Issues</title><link href="https://adasq.github.io/angular-router-protection-issues/" rel="alternate" type="text/html" title="Angular Router Protection Issues" /><published>2017-09-02T16:00:00+07:00</published><updated>2017-09-02T16:00:00+07:00</updated><id>https://adasq.github.io/angular-router-protection-issues</id><content type="html" xml:base="https://adasq.github.io/angular-router-protection-issues/"><![CDATA[<p>Angular router is not perfect, yet. At least latest stable version, <code class="language-plaintext highlighter-rouge">4.3.6</code> which is a scope of this article. You will notice it while struggling to prototype more sophisticated routing architecture. Nested structure full of <code class="language-plaintext highlighter-rouge">resolve</code> and <code class="language-plaintext highlighter-rouge">canActivation</code> guards is a must sometimes, especially when your application grows. In this article, I will try shed light on some the difficulties I had to face lately while working with Angular Router.</p>

<figure>
<img src="/assets/img/angular-router-protection-issues/background.jpeg" alt="fence" />
<figcaption>Fig 1. Fence</figcaption>
</figure>

<p>But for now, let’s start with some basic stuff. Imagine we have an information page with two car brands: <code class="language-plaintext highlighter-rouge">tesla</code> and <code class="language-plaintext highlighter-rouge">arrinera</code>. Routing might look like:</p>

<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>/cars
/cars/tesla
/cars/arrinera
</code></pre></div></div>

<p>All right, let’s define routing for it:</p>

<div class="language-js highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="p">{</span> 
    <span class="nl">path</span><span class="p">:</span> <span class="dl">'</span><span class="s1">cars</span><span class="dl">'</span><span class="p">,</span>
    <span class="nx">component</span><span class="p">:</span> <span class="nx">CarsComponent</span><span class="p">,</span>
    <span class="nx">children</span><span class="p">:</span> <span class="p">[</span>
        <span class="p">{</span> <span class="na">path</span><span class="p">:</span> <span class="dl">'</span><span class="s1">:cid</span><span class="dl">'</span><span class="p">,</span> <span class="na">component</span><span class="p">:</span> <span class="nx">CarComponent</span> <span class="p">}</span>
    <span class="p">]</span> 
<span class="p">}</span>
</code></pre></div></div>

<p>Quiet simple, huh? Now, we need some information about cars, let’s create a <code class="language-plaintext highlighter-rouge">CarsResolver</code>, as a data provider:</p>

<div class="language-js highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="p">@</span><span class="nd">Injectable</span><span class="p">()</span>
<span class="kd">class</span> <span class="nx">CarsResolver</span> <span class="kr">implements</span> <span class="nx">Resolve</span><span class="o">&lt;</span><span class="nx">any</span><span class="o">&gt;</span> <span class="p">{</span>
    <span class="kr">public</span> <span class="nx">resolve</span><span class="p">()</span> <span class="p">{</span>
        <span class="k">return</span> <span class="nx">Observable</span><span class="p">.</span><span class="k">of</span><span class="p">([{</span><span class="na">name</span><span class="p">:</span> <span class="dl">'</span><span class="s1">tesla</span><span class="dl">'</span><span class="p">},</span> <span class="p">{</span><span class="na">name</span><span class="p">:</span> <span class="dl">'</span><span class="s1">arrinera</span><span class="dl">'</span><span class="p">}]);</span>
    <span class="p">}</span>
<span class="p">}</span>
</code></pre></div></div>

<p>And update route definition:</p>

<div class="language-js highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="p">{</span> 
    <span class="nl">path</span><span class="p">:</span> <span class="dl">'</span><span class="s1">cars</span><span class="dl">'</span><span class="p">,</span>
    <span class="nx">component</span><span class="p">:</span> <span class="nx">CarsComponent</span><span class="p">,</span>
    <span class="nx">resolve</span><span class="p">:</span> <span class="p">{</span> <span class="nl">cars</span><span class="p">:</span> <span class="nx">CarsResolver</span> <span class="p">},</span>
    <span class="nx">children</span><span class="p">:</span> <span class="p">[</span>
        <span class="p">{</span> <span class="na">path</span><span class="p">:</span> <span class="dl">'</span><span class="s1">:cid</span><span class="dl">'</span><span class="p">,</span> <span class="na">component</span><span class="p">:</span> <span class="nx">CarComponent</span> <span class="p">}</span>
    <span class="p">]</span>
<span class="p">}</span>
</code></pre></div></div>

<p>Imagine now, that we want to protect our <code class="language-plaintext highlighter-rouge">:cid</code> route to have only two values: <code class="language-plaintext highlighter-rouge">tesla</code> and <code class="language-plaintext highlighter-rouge">arrinera</code>, as provided by <code class="language-plaintext highlighter-rouge">CarsResolver</code>. Our primary objective:</p>

<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>/cars/tesla -&gt; ok!
/cars/arrinera -&gt; ok!
/cars/ford -&gt; not allowed!
</code></pre></div></div>

<p><em>Simple</em>, you might think,_ Let’s use CanActivate_. Ok, let’s give it a try. It should check whether provided by user car brand (<code class="language-plaintext highlighter-rouge">:cid</code>) is available in resolved by parent route <code class="language-plaintext highlighter-rouge">cars</code> list. If so, allow component to be initialized, prohibit otherwise.</p>

<div class="language-js highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="p">{</span> 
    <span class="nl">path</span><span class="p">:</span> <span class="dl">'</span><span class="s1">cars</span><span class="dl">'</span><span class="p">,</span>
    <span class="nx">component</span><span class="p">:</span> <span class="nx">CarsComponent</span><span class="p">,</span>
    <span class="nx">resolve</span><span class="p">:</span> <span class="p">{</span> <span class="nl">cars</span><span class="p">:</span> <span class="nx">CarsResolve</span> <span class="p">},</span>
    <span class="nx">children</span><span class="p">:</span> <span class="p">[</span>
        <span class="p">{</span> 
            <span class="na">path</span><span class="p">:</span> <span class="dl">'</span><span class="s1">:cid</span><span class="dl">'</span><span class="p">,</span>
            <span class="na">canActivate</span><span class="p">:</span> <span class="p">[</span> <span class="nx">CarGuard</span> <span class="p">],</span>
            <span class="na">component</span><span class="p">:</span> <span class="nx">CarComponent</span> 
        <span class="p">}</span>
    <span class="p">]</span>
<span class="p">}</span>
</code></pre></div></div>

<p>Definition of <code class="language-plaintext highlighter-rouge">CarGuard</code>:</p>

<div class="language-js highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="p">@</span><span class="nd">Injectable</span><span class="p">()</span>
<span class="kd">class</span> <span class="nx">CarGuard</span> <span class="kr">implements</span> <span class="nx">CanActivate</span><span class="o">&lt;</span><span class="nx">boolean</span><span class="o">&gt;</span> <span class="p">{</span>
    <span class="kr">public</span> <span class="nx">resolve</span><span class="p">(</span><span class="na">route</span><span class="p">:</span> <span class="nx">ActivatedRouteSnapshot</span><span class="p">)</span> <span class="p">{</span>
        <span class="kd">const</span> <span class="nx">resolvedCars</span> <span class="o">=</span> <span class="nx">route</span><span class="p">.</span><span class="nx">parent</span><span class="p">.</span><span class="nx">data</span><span class="p">.</span><span class="nx">cars</span><span class="p">;</span>
        <span class="kd">const</span> <span class="nx">carId</span> <span class="o">=</span> <span class="nx">route</span><span class="p">.</span><span class="nx">params</span><span class="p">.</span><span class="nx">cid</span><span class="p">;</span>
        <span class="kd">const</span> <span class="nx">car</span> <span class="o">=</span> <span class="nx">resolvedCars</span><span class="p">.</span><span class="nx">find</span><span class="p">(</span><span class="nx">car</span> <span class="o">=&gt;</span> <span class="nx">car</span><span class="p">.</span><span class="nx">name</span> <span class="o">===</span> <span class="nx">carId</span><span class="p">);</span>
        
        <span class="k">return</span> <span class="nx">Observable</span><span class="p">.</span><span class="k">of</span><span class="p">(</span><span class="o">!!</span><span class="nx">car</span><span class="p">);</span>
    <span class="p">}</span>
<span class="p">}</span>
</code></pre></div></div>

<p>Quite simple: access <code class="language-plaintext highlighter-rouge">cars</code> data resolved by <code class="language-plaintext highlighter-rouge">CarsResolver</code> on parent route. Find in list car brand object, by provided by a user in URL <code class="language-plaintext highlighter-rouge">cid</code>, and resolve boolean value, representing car availability.</p>

<p>Saving, running and bang! It does not work. <code class="language-plaintext highlighter-rouge">route.parent.data.cars</code> is not defined. Why? Because <code class="language-plaintext highlighter-rouge">CarsResolve</code> has not started yet. Under the hood, Angular calls <code class="language-plaintext highlighter-rouge">CanActivate</code> guards before data resolution (<code class="language-plaintext highlighter-rouge">resolve</code>) process steps in, so we have no access to resolved data. <code class="language-plaintext highlighter-rouge">canActivate</code> approach is more like: <em>Are we allowed to navigate route? If so, run resolvers, then initialize component</em>. To make things worse, even when we have two <code class="language-plaintext highlighter-rouge">canActivate</code> guards (one defined in child route, another in parent route), both of them are being called at the same time. It’s <a href="https://github.com/angular/angular/issues/15670">well-known issue</a>, which is already fixed in <a href="https://github.com/angular/angular/blob/master/CHANGELOG.md#500-beta1-2017-07-27">5.0.0-beta.1</a>, but leave it for now. The truth is, that in this specific circumstance, we can’t take advantages of Angular Guards capabilities.</p>

<p>What we need here is some hybrid of <code class="language-plaintext highlighter-rouge">Resolve</code> and <code class="language-plaintext highlighter-rouge">canActivate</code> guard. <code class="language-plaintext highlighter-rouge">Resolve</code> is allowed to access data resolved by parent route. It’s a huge advantage over <code class="language-plaintext highlighter-rouge">canActivate</code>. Guards, on the other hand, can prevent a component from being initialized, but how is it achieved? Let’s look through some framework innards…</p>

<p>When any user defined <code class="language-plaintext highlighter-rouge">canActivate</code> resolves to <code class="language-plaintext highlighter-rouge">false</code> (<a href="https://github.com/angular/angular/blob/4.3.6/packages/router/src/apply_redirects.ts#L309-L320">look here</a>), under the hood, <code class="language-plaintext highlighter-rouge">canLoadFails</code> function is being called. This function, calls another shared function, <code class="language-plaintext highlighter-rouge">navigationCancelingError</code> which <a href="https://github.com/angular/angular/blob/4.3.6/packages/router/src/shared.ts#L99-L105">produces an Observable error</a>, which emits interesting instance of <code class="language-plaintext highlighter-rouge">Error</code> object, with <code class="language-plaintext highlighter-rouge">ngNavigationCancelingError</code> property set to <code class="language-plaintext highlighter-rouge">true</code>. Such well-shaped Error forces <code class="language-plaintext highlighter-rouge">Angular</code>, to not initialize component. This is what we need to protect our route! We can use this knowledge, to define our custom resolve, which will act like a <code class="language-plaintext highlighter-rouge">canActivate</code> and <code class="language-plaintext highlighter-rouge">resolve</code> at once. Let’s name it <code class="language-plaintext highlighter-rouge">CarResolve</code>.</p>

<p>Replace non-working <code class="language-plaintext highlighter-rouge">canActivate</code> with our new <code class="language-plaintext highlighter-rouge">CarResolve</code>:</p>

<div class="language-js highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="p">{</span> 
    <span class="nl">path</span><span class="p">:</span> <span class="dl">'</span><span class="s1">cars</span><span class="dl">'</span><span class="p">,</span>
    <span class="nx">component</span><span class="p">:</span> <span class="nx">CarsComponent</span><span class="p">,</span>
    <span class="nx">resolve</span><span class="p">:</span> <span class="p">{</span> <span class="nl">cars</span><span class="p">:</span> <span class="nx">CarsResolve</span> <span class="p">},</span>
    <span class="nx">children</span><span class="p">:</span> <span class="p">[</span>
        <span class="p">{</span> 
            <span class="na">path</span><span class="p">:</span> <span class="dl">'</span><span class="s1">:cid</span><span class="dl">'</span><span class="p">,</span>
            <span class="na">resolve</span><span class="p">:</span> <span class="p">{</span> <span class="na">car</span><span class="p">:</span> <span class="nx">CarResolve</span> <span class="p">},</span>
            <span class="na">component</span><span class="p">:</span> <span class="nx">CarComponent</span> 
        <span class="p">}</span>
    <span class="p">]</span>
<span class="p">}</span>
</code></pre></div></div>

<p>And define <code class="language-plaintext highlighter-rouge">CarResolve</code> as:</p>

<div class="language-js highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="p">@</span><span class="nd">Injectable</span><span class="p">()</span>
<span class="kd">class</span> <span class="nx">CarResolve</span> <span class="kr">implements</span> <span class="nx">Resolve</span><span class="o">&lt;</span><span class="nx">any</span><span class="o">&gt;</span> <span class="p">{</span>
    <span class="kr">public</span> <span class="nx">resolve</span><span class="p">(</span><span class="na">route</span><span class="p">:</span> <span class="nx">ActivatedRouteSnapshot</span><span class="p">)</span> <span class="p">{</span>
        
        <span class="kd">const</span> <span class="nx">resolvedCars</span> <span class="o">=</span> <span class="nx">route</span><span class="p">.</span><span class="nx">parent</span><span class="p">.</span><span class="nx">data</span><span class="p">.</span><span class="nx">cars</span><span class="p">;</span>
        <span class="kd">const</span> <span class="nx">cid</span> <span class="o">=</span> <span class="nx">route</span><span class="p">.</span><span class="nx">params</span><span class="p">.</span><span class="nx">cid</span><span class="p">;</span>
        <span class="kd">const</span> <span class="nx">car</span> <span class="o">=</span> <span class="nx">resolvedCars</span><span class="p">.</span><span class="nx">find</span><span class="p">(</span><span class="nx">car</span> <span class="o">=&gt;</span> <span class="nx">car</span><span class="p">.</span><span class="nx">name</span> <span class="o">===</span> <span class="nx">cid</span><span class="p">);</span>
        <span class="k">if</span> <span class="p">(</span><span class="nx">car</span><span class="p">)</span> <span class="p">{</span>
            <span class="k">return</span> <span class="nx">Observable</span><span class="p">.</span><span class="k">of</span><span class="p">(</span><span class="nx">car</span><span class="p">);</span>
        <span class="p">}</span> <span class="k">else</span> <span class="p">{</span>
            <span class="k">return</span> <span class="nx">Observable</span><span class="p">.</span><span class="k">throw</span><span class="p">({</span> 
                <span class="na">ngNavigationCancelingError</span><span class="p">:</span> <span class="kc">true</span> 
            <span class="p">});</span>
        <span class="p">}</span>
    <span class="p">}</span>
<span class="p">}</span>
</code></pre></div></div>

<p>How it works? As it’s a <code class="language-plaintext highlighter-rouge">resolve</code>, we have access to resolved by parent route <code class="language-plaintext highlighter-rouge">cars</code> list. On the other hand, while throwing object with <code class="language-plaintext highlighter-rouge">ngNavigationCancelingError</code> property set, we act like <code class="language-plaintext highlighter-rouge">canActivate</code> guard. This forces Angular to reject component initialization. Eventually, <code class="language-plaintext highlighter-rouge">NavigationCancel</code> route event is being produced and sent. It will be helpful later, but for now, let’s test our routing transitions from source to target:</p>

<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>/cars -&gt; /cars/tesla          // allowed!
/cars/tesla -&gt; /cars/arrinera // allowed!
/cars/arrinera -&gt; /cars/ford  // not allowed!
</code></pre></div></div>

<p>It works like a charm for state transitions! As described above, we have already source state activated (<code class="language-plaintext highlighter-rouge">/cars</code>, <code class="language-plaintext highlighter-rouge">/cars/tesla</code>, <code class="language-plaintext highlighter-rouge">/cars/arrinera</code>), and then we are trying to navigate a target route. It might succeed or fail. But what happens internally when it fails? <code class="language-plaintext highlighter-rouge">resetUrlToCurrentUrlTree</code> function is <a href="https://github.com/angular/angular/blob/4.3.6/packages/router/src/router.ts#L760-L763">being called</a>. What it does is trivial URL replacement for source route URL. So, when have already state activated (let’s say: <code class="language-plaintext highlighter-rouge">/cars</code>) and we are trying to navigate the invalid route, <code class="language-plaintext highlighter-rouge">/cars/ford</code>, after canceling transition, this function reverts URL to latest activated route, which is <code class="language-plaintext highlighter-rouge">/cars</code> in this case. From user perspective, nothing has changed, we stay on source route.</p>

<p>But what happens, when we have no source state activated? Is it possible? Yes, it is. We can achieve it by opening new browser tab, and pasting <code class="language-plaintext highlighter-rouge">http://localhost:4200/cars/ford</code> in an address bar. Angular router is trying to activate <code class="language-plaintext highlighter-rouge">/cars/ford</code> state, and it fails… Unfortunately, as we have no source state activated, a blank page is displayed, at least the root <code class="language-plaintext highlighter-rouge">&lt;route-outlet&gt;</code> element is not filled at all. Not sure whether it’s intended behavior, what’s more, this problem occurs also for <code class="language-plaintext highlighter-rouge">canActivate</code> guards.</p>

<p>How can we bypass this issue? Just by watching source URL, after route activation rejection. Let’s apply subscription for <code class="language-plaintext highlighter-rouge">NavigationCancel</code> event like this:</p>

<div class="language-js highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="k">this</span><span class="p">.</span><span class="nx">router</span><span class="p">.</span><span class="nx">events</span>
    <span class="p">.</span><span class="nx">filter</span><span class="p">(</span><span class="nx">event</span> <span class="o">=&gt;</span> <span class="nx">event</span> <span class="k">instanceof</span> <span class="nx">NavigationCancel</span><span class="p">)</span>
    <span class="p">.</span><span class="nx">subscribe</span><span class="p">(</span><span class="nx">event</span> <span class="o">=&gt;</span> <span class="p">{</span>
         <span class="kd">const</span> <span class="p">{</span> <span class="nx">url</span> <span class="p">}</span> <span class="o">=</span> <span class="k">this</span><span class="p">.</span><span class="nx">router</span><span class="p">.</span><span class="nx">currentRouterState</span><span class="p">.</span><span class="nx">snapshot</span><span class="p">;</span>
         <span class="k">if</span> <span class="p">(</span><span class="nx">url</span> <span class="o">===</span> <span class="dl">''</span><span class="p">)</span> <span class="p">{</span> 
             <span class="k">this</span><span class="p">.</span><span class="nx">router</span><span class="p">.</span><span class="nx">navigate</span><span class="p">([</span><span class="dl">'</span><span class="s1">/cars</span><span class="dl">'</span><span class="p">]);</span>
         <span class="p">}</span>
    <span class="p">});</span>
</code></pre></div></div>

<p>So, when we receive <code class="language-plaintext highlighter-rouge">NavigationCancel</code> event, and <code class="language-plaintext highlighter-rouge">ActivatedRouteSnapshot</code>’s <code class="language-plaintext highlighter-rouge">url</code> property points to an empty string it means, that a user opened url (which points to invalid application state) in new browser tab. We can redirect the user to specific route, preventing the blank page from being displayed. And yes, we can put this redirection inside <code class="language-plaintext highlighter-rouge">CarResolve</code> definition, but I think, that <code class="language-plaintext highlighter-rouge">resolve</code> should only resolve data (or throw an error) without additional tricky redirection logic.</p>

<p><a href="http://plnkr.co/edit/yilxe6XsHF88IrnoAq6A?p=preview">Click here</a> to open plunker with an example application embodying described issues. Review code and necessarily click <em>Launch the preview in a separate window</em> icon in order to play with routing capabilities in new browser tab. Observe console output.</p>]]></content><author><name>Adam Płócieniak</name></author><category term="javascript" /><category term="angular" /><summary type="html"><![CDATA[Angular router is not perfect, yet. At least latest stable version, `4.3.6` which is a scope of this article.]]></summary><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="https://adasq.github.io/assets/img/angular-router-protection-issues/background.jpeg" /><media:content medium="image" url="https://adasq.github.io/assets/img/angular-router-protection-issues/background.jpeg" xmlns:media="http://search.yahoo.com/mrss/" /></entry></feed>