<?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: Paulo Santos</title>
    <description>The latest articles on DEV Community by Paulo Santos (@gitpaulo).</description>
    <link>https://dev.to/gitpaulo</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%2F666129%2F9078036c-fc2c-4005-a3f5-466cf4957e0c.jpg</url>
      <title>DEV Community: Paulo Santos</title>
      <link>https://dev.to/gitpaulo</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/gitpaulo"/>
    <language>en</language>
    <item>
      <title>Reactive Programming 🌫️ - Demystified using RxJS</title>
      <dc:creator>Paulo Santos</dc:creator>
      <pubDate>Fri, 23 Jul 2021 22:38:48 +0000</pubDate>
      <link>https://dev.to/gitpaulo/reactive-programming-demystified-using-rxjs-53g5</link>
      <guid>https://dev.to/gitpaulo/reactive-programming-demystified-using-rxjs-53g5</guid>
      <description>&lt;p&gt;If you're looking for a RxJS quick start then this article is &lt;strong&gt;not&lt;/strong&gt; for you!&lt;/p&gt;

&lt;p&gt;Here, I will be tackling Reactive Programming with the goal of shedding some light over its unreasonably illusive world using RxJS as an example.&lt;/p&gt;

&lt;p&gt;I will be explaining the core Reactive Programming concepts, relating them to RxJS and how they work in practice. Hopefully, by the end of the read, you'll have a truer understanding of RxJS and should be able to quickly pick up any Rx Implementation to start coding with.&lt;/p&gt;

&lt;h2&gt;
  
  
  Statement
&lt;/h2&gt;

&lt;blockquote&gt;
&lt;p&gt;RxJS is an API for asynchronous programming&lt;br&gt;
with observable streams. &lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;To understand what this means we need to define what is meant by &lt;em&gt;asynchronous programming&lt;/em&gt; and &lt;em&gt;observable streams&lt;/em&gt;.&lt;/p&gt;

&lt;p&gt;The best starting point can only be Reactive Programming itself!&lt;/p&gt;

&lt;h2&gt;
  
  
  Reactive Programming
&lt;/h2&gt;

&lt;p&gt;Reactive Programming (not to be confused with &lt;a href="http://conal.net/papers/icfp97/" rel="noopener noreferrer"&gt;Functional Reactive Programming&lt;/a&gt;!!) is a subset of &lt;strong&gt;Asynchronous Programming&lt;/strong&gt; and a paradigm where the availability of new information drives the logic forward rather than having control flow driven by a thread-of-execution.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Asynchronous Programming&lt;/strong&gt; is a means of parallel programming in which a unit of work runs separately from the main application thread. Generally, this is achieved via a messaging system where threads of execution competing for a shared resource don’t need to wait by blocking (preventing the thread of execution from performing other work until current work is done), and can as such perform other useful work while the resource is occupied. This concept is vital for Reactive Programming because it allows for non-blocking code to be written. Bellow a visualisation of the process:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F4od7mbiuhm8joe78e9l2.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F4od7mbiuhm8joe78e9l2.png" alt="" width="675" height="600"&gt;&lt;/a&gt;&lt;a href="https://www.lightbend.com/white-papers-and-reports/reactive-programming-versus-reactive-systems" title="Async" rel="noopener noreferrer"&gt;Asynchronous Message System&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Synchronous, blocking communication (left) is resource inefficient and easily bottlenecked. The Reactive approach (right) reduces risk, conserves valuable resources, and requires less hardware/infrastructure. &lt;/p&gt;

&lt;h3&gt;
  
  
  Messages vs Events
&lt;/h3&gt;

&lt;p&gt;Reactive Programming is generally Event-driven. &lt;strong&gt;Events are simply undirected messages&lt;/strong&gt;. At their core, they are (for all intents and purposes) an extension of an event. &lt;/p&gt;

&lt;p&gt;The Application Program Interface (API) for Reactive Programming libraries are generally either:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Callback-based:&lt;/strong&gt; where anonymous, side-effecting callbacks are attached to event sources and are being invoked when events pass through the dataflow chain.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Declarative:&lt;/strong&gt; through functional composition, usually using well-established combinators like map, filter, fold etc.&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Reactive Systems
&lt;/h3&gt;

&lt;p&gt;&lt;a href="https://www.reactivemanifesto.org/" rel="noopener noreferrer"&gt;The Reactive Manifesto&lt;/a&gt; defines that reactive systems are: &lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Responsive:&lt;/strong&gt; responsive systems focus on providing rapid and consistent response times. &lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Resilient:&lt;/strong&gt; resilient systems handle problems as they occur and stay responsive in the face of failure.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Elastic:&lt;/strong&gt; elastic systems stays responsive under the varying workload and ergo have the ability to scale.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Message Driven:&lt;/strong&gt; message-driven systems rely on asynchronous message-passing to establish to ensure that change is propagated between components without interruptions.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fx1thn17zb33wg7glzdvz.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fx1thn17zb33wg7glzdvz.png" alt="" width="800" height="303"&gt;&lt;/a&gt;&lt;a href="https://www.reactivemanifesto.org/" title="RM" rel="noopener noreferrer"&gt;Principles of Reactive Systems&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  Reactive Programming &amp;amp; Reactive Systems
&lt;/h3&gt;

&lt;p&gt;How do these two relate? In summary:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Reactive Programming&lt;/strong&gt; is a technique for managing internal logic and dataflow transformation within components of a system. It is a way of providing clarity, performance and resource efficiency of code.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Reactive Systems&lt;/strong&gt; is a set of architectural principles. It puts emphasis on distributed communication and gives us tools to tackle resilience and elasticity in distributed systems.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;em&gt;Reactive Programming should be used as one of the tools to construct a Reactive System.&lt;/em&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  Defining the Paradigm in Practice
&lt;/h3&gt;

&lt;p&gt;Right, so, what is &lt;strong&gt;exactly&lt;/strong&gt; is Reactive Programming? There are &lt;em&gt;many&lt;/em&gt; definitions out there... some of which I think not even their authors understand what they mean. In the wise words of &lt;a href="https://twitter.com/andrestaltz" rel="noopener noreferrer"&gt;@andrestaltz&lt;/a&gt; - "Lets cut the bullshit"&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Reactive programming is programming with asynchronous data streams.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Beautiful, concise and above all explainable! In fact, this definition is almost the same as the statement about RxJS I presented before. That is because RxJS is within the Reactive Programming paradigm. &lt;/p&gt;

&lt;p&gt;From now on we assume Reactive programming &lt;strong&gt;with streams&lt;/strong&gt;. There are other types of implementations that can also be considered within the paradigm, such as: &lt;a href="https://en.wikipedia.org/wiki/Futures_and_promises" rel="noopener noreferrer"&gt;Promises/Futures&lt;/a&gt; and &lt;a href="https://en.wikipedia.org/wiki/Oz_(programming_language)#Dataflow_variables_and_declarative_concurrency" rel="noopener noreferrer"&gt;Dataflow variables&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Now, as promised, I'll be showing you guys what is meant by 'asynchronous data streams'.&lt;/p&gt;

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

&lt;p&gt;The key idea in Reactive Programming is that &lt;em&gt;everything&lt;/em&gt; (for the most part) can be a stream. Streams are &lt;strong&gt;cheap&lt;/strong&gt; and &lt;strong&gt;ubiquitous&lt;/strong&gt;. &lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;A stream is a sequence of ongoing events ordered in time. It can only emit 3 things: a data typed value, an error, or a termination signal.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;This definition is important to remember since it remains the same no matter the implementation of the paradigm.&lt;/p&gt;

&lt;p&gt;The way I like to think about streams is by visualising a water pipe with a closing mechanism where each water molecule (or set of) is an emitted value. &lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fvk61sg0fug3pr8p00hh6.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fvk61sg0fug3pr8p00hh6.png" alt="" width="800" height="274"&gt;&lt;/a&gt;Water pipe stream analogy&lt;/p&gt;

&lt;p&gt;The closing mechanism can be triggered manually by turning the tap, representing a termination signal, or implicitly, if the pipe fails to do its function, representing an error. A closed pipe can no longer push out water and we call it a completed stream.&lt;/p&gt;

&lt;p&gt;Now, let us focus on the first sentence of our definition: 'A stream is a sequence of &lt;strong&gt;ongoing events ordered in time&lt;/strong&gt;.' &lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Febnd36etq6fzhutntpd5.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Febnd36etq6fzhutntpd5.png" alt="" width="250" height="355"&gt;&lt;/a&gt;Capturing values analogy&lt;/p&gt;

&lt;p&gt;In other words, water droplets (data) are being pushed out of the pipe (stream) as time (program execution) passes. How do we capture these droplets to act on them? &lt;/p&gt;

&lt;p&gt;In most implementations of Reactive Programming, we capture these emitted events only asynchronously, by defining functions that are called and passed one of the three appropriate outputs as a parameter:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;On value emission:&lt;/strong&gt; Each time a value is pushed through the stream it will be emitted and captured here. Can happen multiple times.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;On error emission:&lt;/strong&gt; When the stream error it will be captured here and the stream terminates. Happens only once.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;On termination:&lt;/strong&gt; When the stream is terminated it will be captured here. Happens only once.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;That covers capturing. It's time to move into the manipulation of streams themselves. We do this via &lt;strong&gt;Operators&lt;/strong&gt;.&lt;/p&gt;

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

&lt;p&gt;Operators offer a way to manipulate streams by transforming them. A transformation, in our context, is simply a function &lt;code&gt;f&lt;/code&gt; that maps a stream into another stream, i.e. &lt;code&gt;f: S1 → S2&lt;/code&gt; This function we call an operator.&lt;/p&gt;

&lt;p&gt;To visualise this simple imagine placing one or more appliances within the pipeline of our stream. These appliances could have filters in them or could modify the contents of the water (or other transformations) thereby transforming our stream into a new stream.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F6f2qahx90sn2mflt3l2x.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F6f2qahx90sn2mflt3l2x.png" alt="" width="800" height="392"&gt;&lt;/a&gt;Water pipe stream analogy with operators &lt;/p&gt;

&lt;p&gt;In the image above, our initial stream of type 'Unpurified Water' was transformed into a stream of type 'Purified Water' transforming the data that gets observed at the end of the pipeline from its original form.&lt;/p&gt;

&lt;p&gt;To explain operators and their effects on real streams of data we will have to dive into the world of Marble Diagrams.&lt;/p&gt;

&lt;h2&gt;
  
  
  Marble Diagrams
&lt;/h2&gt;

&lt;p&gt;Before explaining marble diagrams we need to improve our terminology a little bit.&lt;/p&gt;

&lt;h3&gt;
  
  
  Redefining Some Terms
&lt;/h3&gt;

&lt;p&gt;Now, because we will be dealing with ReactiveX in the next chapter, it's time to introduce some of the required terminologies. Don't worry, for now, I will only be giving abstracted definitions to a few terms that map to terms I've already covered. Below, the same diagrams as before, but with the new terminology included.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fth62dw2hw9o3p18cc9gr.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fth62dw2hw9o3p18cc9gr.png" alt="" width="800" height="282"&gt;&lt;/a&gt;Water pipe stream analogy (w/terminology) &lt;/p&gt;

&lt;p&gt;and for the operator diagram,&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F1r9fgxt1yfyfp5mpv4v7.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F1r9fgxt1yfyfp5mpv4v7.png" alt="" width="800" height="407"&gt;&lt;/a&gt;Water pipe stream analogy with operators (w/terminology)  &lt;/p&gt;

&lt;p&gt;Simple definitions for these terms are:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Stream -&amp;gt; Observable:&lt;/strong&gt; A structure representing a stream of values over time.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Tap -&amp;gt; Subscriber:&lt;/strong&gt; Sometimes called the consumer, the code that calls the subscription process on an observable structure.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Turning the tap -&amp;gt; Subscription:&lt;/strong&gt; The method that opens the stream for the observer.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Closing the tap -&amp;gt; Completing:&lt;/strong&gt; The action of marking the stream as completed meaning it is terminated.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Bucket -&amp;gt; Observer:&lt;/strong&gt; The structure that captures our pushed values allowing us to act on them.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Appliances -&amp;gt; Operators:&lt;/strong&gt; Functions that transform the stream.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;We will be returning to more precise definitions later since they are pretty much required to read any sort of RX documentation without inducing a headache. So don't worry if you don't quite understand what these mean yet.&lt;/p&gt;

&lt;p&gt;However, we will be using this new terminology from now on so I recommend keeping the term mapping in your head.&lt;/p&gt;

&lt;h3&gt;
  
  
  Marble Diagrams - The Observable
&lt;/h3&gt;

&lt;p&gt;Okay, time for actual marble diagrams! &lt;/p&gt;

&lt;p&gt;Learning Reactive Programming can be a daunting task so the Rx team came up with the concept of marble diagrams to help with visualising observables and their operators. These diagrams are incredibly intuitive and are commonly found in any Rx Operator documentation. They allow for an easy understanding of the operators without having to read much else. A good alternative to a chunky wall of text filled with terminology! I'll try to explain how to read them as best I can:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fdki7ul5wpik316wkssw3.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fdki7ul5wpik316wkssw3.png" alt="" width="800" height="503"&gt;&lt;/a&gt;&lt;a href="https://medium.com/@bencabanes/marble-testing-observable-introduction-1f5ad39231c" title="OMD" rel="noopener noreferrer"&gt;Overview of a Marble Diagram&lt;/a&gt;  &lt;/p&gt;

&lt;p&gt;Okay... my bad haha, sorry! Let's go step by step. &lt;/p&gt;

&lt;p&gt;Marble diagrams describe observables. Observables are streams of values through time. So, we need a time axis!&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fue48ew05m7wpr9sgwqgv.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fue48ew05m7wpr9sgwqgv.png" alt="" width="600" height="200"&gt;&lt;/a&gt;&lt;a href="https://www.zachgollwitzer.com/posts/2020/rxjs-marble-diagram/" title="OMD" rel="noopener noreferrer"&gt;Marble Diagram: time axis&lt;/a&gt;  &lt;/p&gt;

&lt;p&gt;Now that we have a time axis we need to represent our observable outputs. If you recall our earlier definition, an observable can only output a value, a termination signal or an error. &lt;/p&gt;

&lt;p&gt;Let's start with the easy one, the termination signal:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fe9afmw9ld3xyevxd079m.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fe9afmw9ld3xyevxd079m.png" alt="" width="600" height="200"&gt;&lt;/a&gt;&lt;a href="https://www.zachgollwitzer.com/posts/2020/rxjs-marble-diagram/" title="OMD" rel="noopener noreferrer"&gt;Marble Diagram: termination signal&lt;/a&gt;   &lt;/p&gt;

&lt;p&gt;In similar fashion, we have our error output:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fci83oemg1ho6pztolb9p.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fci83oemg1ho6pztolb9p.png" alt="" width="600" height="200"&gt;&lt;/a&gt;&lt;a href="https://www.zachgollwitzer.com/posts/2020/rxjs-marble-diagram/" title="OMD" rel="noopener noreferrer"&gt;Marble Diagram: error&lt;/a&gt;   &lt;/p&gt;

&lt;p&gt;Finally, lets represent our emitted value:  &lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fqzuzc29irqvf2hy8l3w9.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fqzuzc29irqvf2hy8l3w9.png" alt="" width="600" height="200"&gt;&lt;/a&gt;&lt;a href="https://www.zachgollwitzer.com/posts/2020/rxjs-marble-diagram/" title="OMD" rel="noopener noreferrer"&gt;Marble Diagram: value push/emission&lt;/a&gt;   &lt;/p&gt;

&lt;p&gt;There can be multiple values across the time axis as long as there is no termination or error output behind them as those will unsubscribe from the observable.&lt;/p&gt;

&lt;p&gt;Done, simple right? On to the next part: operators in marble diagrams!&lt;/p&gt;

&lt;h3&gt;
  
  
  Marble Diagrams - The Operators
&lt;/h3&gt;

&lt;p&gt;As previously mentioned, operators are functions that transform observables. That means they take as input one or more observables and output a new observable. We can represent them in a marble diagram like so:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fxab3a7gqc9mm0xl4nom7.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fxab3a7gqc9mm0xl4nom7.png" alt="" width="800" height="227"&gt;&lt;/a&gt;Marble diagram of a filter operator   &lt;/p&gt;

&lt;p&gt;The block in between is our operator function, taking in an observable and returning another. So, our function is filtering the input observable by taking the modulus 2 to determine whether a pushed value is even and if it is it allows that push value to pass through, essentially, filtering the stream. &lt;/p&gt;

&lt;p&gt;As mentioned before, operators can have more than one observable as input, such as the case for operators such as &lt;code&gt;switchMap&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F76qz9j0n1ggp30s8mcy9.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F76qz9j0n1ggp30s8mcy9.png" alt="" width="800" height="375"&gt;&lt;/a&gt;Marble diagram of a switch map operator     &lt;/p&gt;

&lt;p&gt;The &lt;code&gt;switchMap&lt;/code&gt; operator is a very popular one that has a handful of practical applications. It is generally used to implement a discard action between the input streams which can save a lot of trouble and computation in practice.&lt;/p&gt;

&lt;p&gt;In summary, every time the &lt;code&gt;Input Observable 1&lt;/code&gt; emits a value, &lt;code&gt;Input Observable 2&lt;/code&gt; emits all of its values unless &lt;code&gt;Input Observable 1&lt;/code&gt; emits a new value before the &lt;code&gt;Input Observable 2&lt;/code&gt; completes. If you look at the output observable you will notice that there are only two 30's. This is because &lt;code&gt;Input Observable 2&lt;/code&gt; could not be complete before &lt;code&gt;Input Observable 1&lt;/code&gt; emitted the value 5. You easily confirm this because the space between 3 and 5 is much less than the size of the axis for &lt;code&gt;Input Observable 2&lt;/code&gt;, suggesting there was only time to emit the first two values. &lt;/p&gt;

&lt;h2&gt;
  
  
  In Practice - RxJS
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Overview of RxJS
&lt;/h3&gt;

&lt;p&gt;RxJS is a library extending &lt;a href="http://reactivex.io/" rel="noopener noreferrer"&gt;ReactiveX&lt;/a&gt; for composing asynchronous and event-based programs by using observable sequences with JavaScript. It provides one core type, the Observable, satellite types (Observer, Schedulers, Subjects) and operators (map, filter, reduce, every, etc) to allow the manipulation of the observable streams with easy and significantly reducing the amount of code needed to solve asynchronous problems. &lt;/p&gt;

&lt;h3&gt;
  
  
  Advantages VS Disadvantages
&lt;/h3&gt;

&lt;h4&gt;
  
  
  Advantages​
&lt;/h4&gt;

&lt;ul&gt;
&lt;li&gt;Growing very rapidly.​

&lt;ul&gt;
&lt;li&gt;RxJs alone has 25mil weekly downloads.​&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;

&lt;li&gt;Provides a very high-quality asynchronous API.​&lt;/li&gt;

&lt;li&gt;Lightweight &amp;amp; memory optimised.​&lt;/li&gt;

&lt;li&gt;Easy error handling.​&lt;/li&gt;

&lt;li&gt;Makes asynchronous programming much faster in most applications.​&lt;/li&gt;

&lt;/ul&gt;

&lt;h5&gt;
  
  
  Disadvantages​
&lt;/h5&gt;

&lt;ul&gt;
&lt;li&gt;Relatively steep learning curve.​&lt;/li&gt;
&lt;li&gt;Implies a functional programming style (data immutability).​&lt;/li&gt;
&lt;li&gt;Testing/debugging can be a learning process.&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  RxJS Glossary
&lt;/h3&gt;

&lt;p&gt;In RxJS some arguably established definitions are:&lt;/p&gt;

&lt;h4&gt;
  
  
  Entities
&lt;/h4&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Observable:&lt;/strong&gt; represents the idea of an invokable collection of future values or events.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Observer:&lt;/strong&gt; is a collection of callbacks that knows how to listen to values delivered by the Observable.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Subscription:&lt;/strong&gt; represents the execution of an Observable, which is primarily useful for cancelling the execution.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Operators:&lt;/strong&gt; are pure functions that enable a functional programming style of dealing with collections with operations like map, filter, concat, reduce, etc.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Subject:&lt;/strong&gt; is equivalent to an EventEmitter, and the only way of multicasting a value or event to multiple Observers.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Schedulers:&lt;/strong&gt; are centralized dispatchers to control concurrency, allowing us to coordinate when computation happens on e.g. setTimeout or requestAnimationFrame or others.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Producer:&lt;/strong&gt; The code that is subscribing to the observable. This is whoever is being notified of nexted values, and errors or completions.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Consumer:&lt;/strong&gt; Any system or thing that is the source of values that are being pushed out of the observable subscription to the consumer. &lt;/li&gt;
&lt;/ul&gt;

&lt;h4&gt;
  
  
  Concepts
&lt;/h4&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Unicast:&lt;/strong&gt; The act of one producer being observed only one consumer. An observable is "unicast" when it only connects one producer to one consumer. Unicast doesn't necessarily mean "cold".&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Multicast&lt;/strong&gt;: The act of one producer being observed by many consumers.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Cold&lt;/strong&gt;: An observable is "cold" when it creates a new producer during subscribe for every new subscription. As a result, a "cold" observables are always unicast, being one producer observed by one consumer. Cold observables can be made hot but not the other way around.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Hot&lt;/strong&gt;: An observable is "hot", when its producer was created outside of the context of the subscribe action. This means that the "hot" observable is almost always multicast. It is possible that a "hot" observable is still technically unicast if it is engineered to only allow one subscription at a time, however, there is no straightforward mechanism for this in RxJS, and the scenario is unlikely. For the purposes of discussion, all "hot" observables can be assumed to be multicast. Hot observables cannot be made cold.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Push&lt;/strong&gt;: Observables are a push-based type. That means rather than having the consumer call a function or perform some other action to get a value, the consumer receives values as soon as the producer has produced them, via a registered next handler.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Pull&lt;/strong&gt;: Pull-based systems are the opposite of push-based. In a pull-based type or system, the consumer must request each value the producer has produced manually, perhaps long after the producer has actually done so. Examples of such systems are Functions and Iterators&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Observables &amp;amp; Subscriptions
&lt;/h3&gt;

&lt;p&gt;By now we should agree that observables are simply structures that lazy push collections of multiple values. Subscriptions are the resulting structure representing a disposable resource, usually the execution of an Observable.&lt;/p&gt;

&lt;p&gt;Heres how we code them in RxJS:&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;Observable&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;rxjs&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="cm"&gt;/* Instantiate an observable */&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;observable&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;Observable&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;subscriber&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nx"&gt;subscriber&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;next&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt; &lt;span class="c1"&gt;// pushes a value&lt;/span&gt;
  &lt;span class="nx"&gt;subscriber&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;next&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt; &lt;span class="c1"&gt;// pushes another value synchronously&lt;/span&gt;
  &lt;span class="nf"&gt;setTimeout&lt;/span&gt;&lt;span class="p"&gt;(()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nx"&gt;subscriber&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;next&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;3&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt; &lt;span class="c1"&gt;// pushes last value after a wait of 1s&lt;/span&gt;
    &lt;span class="nx"&gt;subscriber&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;complete&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt; &lt;span class="c1"&gt;// terminates observable stream&lt;/span&gt;
  &lt;span class="p"&gt;},&lt;/span&gt; &lt;span class="mi"&gt;1000&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="p"&gt;});&lt;/span&gt;

&lt;span class="cm"&gt;/* Subscribing to an observable */&lt;/span&gt;
&lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;just before subscribe&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;subscription&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;observable&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;subscribe&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;
  &lt;span class="c1"&gt;// The three possible output captures:&lt;/span&gt;
  &lt;span class="nf"&gt;next&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;x&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;got value &lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="nx"&gt;x&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt; &lt;span class="p"&gt;},&lt;/span&gt;
  &lt;span class="nf"&gt;error&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;err&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;error&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;something wrong occurred: &lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="nx"&gt;err&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt; &lt;span class="p"&gt;},&lt;/span&gt;
  &lt;span class="nf"&gt;complete&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;done&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="c1"&gt;// creates subscription object&lt;/span&gt;
&lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;just after subscribe&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

&lt;span class="cm"&gt;/* Unsubscribing to an observable using subscription */&lt;/span&gt;
&lt;span class="nf"&gt;setTimeout&lt;/span&gt;&lt;span class="p"&gt;(()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nx"&gt;subscription&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;unsubscribe&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
&lt;span class="p"&gt;},&lt;/span&gt; &lt;span class="mi"&gt;500&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

&lt;span class="c1"&gt;// Logs:&lt;/span&gt;
&lt;span class="c1"&gt;// just before subscribe &lt;/span&gt;
&lt;span class="c1"&gt;// got value 1 &lt;/span&gt;
&lt;span class="c1"&gt;// got value 2 &lt;/span&gt;
&lt;span class="c1"&gt;// just after subscribe &lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Notice how we never see the value 3 logged because we cancel our subscription before it is emitted through the closure function passed to &lt;code&gt;setTimeout&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;However, this does not mean the value was not emitted, it was, we just don't see it because we stopped subscribing. The stream was not terminated via the act of unsubscribing.&lt;/p&gt;

&lt;h3&gt;
  
  
  Hot vs Cold Observables
&lt;/h3&gt;

&lt;p&gt;A &lt;strong&gt;cold observable&lt;/strong&gt; starts producing data when some code invokes a &lt;strong&gt;subscribe()&lt;/strong&gt; function on it.&lt;/p&gt;

&lt;p&gt;A cold observable:&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;Observable&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;rxjs&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="c1"&gt;// Creating a cold observable&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;observable&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;Observable&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;create&lt;/span&gt;&lt;span class="p"&gt;((&lt;/span&gt;&lt;span class="nx"&gt;observer&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nx"&gt;observer&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;next&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nb"&gt;Math&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;random&lt;/span&gt;&lt;span class="p"&gt;());&lt;/span&gt; &lt;span class="c1"&gt;// We explicitly push the value to the stream&lt;/span&gt;
&lt;span class="p"&gt;});&lt;/span&gt;

&lt;span class="c1"&gt;// Subscription 1&lt;/span&gt;
&lt;span class="nx"&gt;observable&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;subscribe&lt;/span&gt;&lt;span class="p"&gt;((&lt;/span&gt;&lt;span class="nx"&gt;data&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;data&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt; &lt;span class="c1"&gt;// 0.24957144215097515 (random number)&lt;/span&gt;
&lt;span class="p"&gt;});&lt;/span&gt;

&lt;span class="c1"&gt;// Subscription 2&lt;/span&gt;
&lt;span class="nx"&gt;observable&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;subscribe&lt;/span&gt;&lt;span class="p"&gt;((&lt;/span&gt;&lt;span class="nx"&gt;data&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
   &lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;data&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt; &lt;span class="c1"&gt;// 0.004617340049055896 (random number)&lt;/span&gt;
&lt;span class="p"&gt;});&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;A &lt;strong&gt;hot observable&lt;/strong&gt; produces data even if &lt;strong&gt;no subscribers are interested&lt;/strong&gt; in the data.&lt;/p&gt;

&lt;p&gt;A hot observable:&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;Observable&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;rxjs&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="c1"&gt;// Coming from an event which is constantly emmit values&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;observable&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;Observable&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;fromEvent&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="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;click&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

&lt;span class="c1"&gt;// Subscription 1&lt;/span&gt;
&lt;span class="nx"&gt;observable&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;subscribe&lt;/span&gt;&lt;span class="p"&gt;((&lt;/span&gt;&lt;span class="nx"&gt;event&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;event&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;clientX&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt; &lt;span class="c1"&gt;// x position of click&lt;/span&gt;
&lt;span class="p"&gt;});&lt;/span&gt;

&lt;span class="c1"&gt;// Subscription 2&lt;/span&gt;
&lt;span class="nx"&gt;observable&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;subscribe&lt;/span&gt;&lt;span class="p"&gt;((&lt;/span&gt;&lt;span class="nx"&gt;event&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
   &lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;event&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;clientY&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt; &lt;span class="c1"&gt;// y position of click&lt;/span&gt;
&lt;span class="p"&gt;});&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Promises vs Observables
&lt;/h3&gt;

&lt;p&gt;The main differences are:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Promises are eager. Observables are lazy.​&lt;/li&gt;
&lt;li&gt;Promises are single-value emissions. Observables are multi-value streams.​&lt;/li&gt;
&lt;li&gt;Promises have no cancelling or operator APIs. Observables do.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fgbg528g59fb2w50vclj0.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fgbg528g59fb2w50vclj0.png" alt="" width="800" height="370"&gt;&lt;/a&gt;Promise vs Observable   &lt;/p&gt;

&lt;p&gt;A stackblitz example of RxJS vs Promises: &lt;a href="https://stackblitz.com/edit/classicjs-vs-rxjs" rel="noopener noreferrer"&gt;https://stackblitz.com/edit/classicjs-vs-rxjs&lt;/a&gt;&lt;/p&gt;

&lt;h4&gt;
  
  
  Observables can be Promises
&lt;/h4&gt;

&lt;p&gt;Although observables are not an extension of the &lt;a href="https://promisesaplus.com/" rel="noopener noreferrer"&gt;Promise/A+&lt;/a&gt; specification, RxJS still provides means to transform an observable into a true Promise. An example follows:&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;Observable&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;rxjs&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="c1"&gt;// Return a basic observable&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;simpleObservable&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;val&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nx"&gt;Observable&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="k"&gt;of&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;val&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nf"&gt;delay&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;5000&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

&lt;span class="c1"&gt;// Convert basic observable to promise&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;example&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;sample&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;First Example&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;toPromise&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="c1"&gt;// Now its a promise&lt;/span&gt;
  &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;then&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;result&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;From Promise:&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;result&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt; &lt;span class="c1"&gt;// After 500ms, output 'First Example'&lt;/span&gt;
  &lt;span class="p"&gt;});&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;With the use of RxJS's &lt;code&gt;toPromise&lt;/code&gt; method, any observable can be converted to a promise. Note that because it returns a true JS Promise, &lt;code&gt;toPromise&lt;/code&gt; is not a pipable operator, as it does not return an observable.&lt;/p&gt;

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

&lt;p&gt;In practice, an Observer is a consumer of values delivered by an Observable. Observers are simply a set of callbacks, one for each type of notification delivered by the Observable: &lt;code&gt;next&lt;/code&gt;, &lt;code&gt;error&lt;/code&gt;, and &lt;code&gt;complete&lt;/code&gt;. The following is an example of a typical Observer object:&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="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;observer&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="na"&gt;next&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;x&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Observer got a next value: &lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="nx"&gt;x&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
  &lt;span class="na"&gt;error&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;err&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;error&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Observer got an error: &lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="nx"&gt;err&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
  &lt;span class="na"&gt;complete&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Observer got a complete notification&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
&lt;span class="p"&gt;};&lt;/span&gt;

&lt;span class="c1"&gt;// To use it, pass it to a subscribe&lt;/span&gt;
&lt;span class="nx"&gt;observable&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;subscribe&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;observer&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;That's it for observers, really!&lt;/p&gt;

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

&lt;p&gt;RxJS is mostly useful for its operators, even though the Observable is the foundation. Previously we studied operators as functions that transformed streams. Nothing changes here, just terminology!&lt;/p&gt;

&lt;p&gt;RxJS has a (very) vast library of operators. We will only be touching on a few simple ones to cover what we've talked about already:&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="k"&gt;from&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;rxjs&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;filter&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;rxjs/operators&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="k"&gt;from&lt;/span&gt;&lt;span class="p"&gt;([&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;3&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;4&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;5&lt;/span&gt;&lt;span class="p"&gt;]).&lt;/span&gt;&lt;span class="nf"&gt;pipe&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
  &lt;span class="nf"&gt;filter&lt;/span&gt;&lt;span class="p"&gt;((&lt;/span&gt;&lt;span class="nx"&gt;x&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;x&lt;/span&gt; &lt;span class="o"&gt;%&lt;/span&gt; &lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;)&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="nf"&gt;subscribe&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;log&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt; &lt;span class="c1"&gt;// [2, 4]&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



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

&lt;p&gt;If you remember our filter example from before this should be fairly simple to understand!&lt;/p&gt;

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

&lt;p&gt;A pipeline is simply a series of operators that get executed in order. Something obvious but that people forget, every pipeline operator &lt;strong&gt;must&lt;/strong&gt; return an observable.&lt;/p&gt;

&lt;p&gt;The same exmaple as before but with chaining operators:&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="k"&gt;from&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;rxjs&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;filter&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;take&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;map&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;rxjs/operators&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="k"&gt;from&lt;/span&gt;&lt;span class="p"&gt;([&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;3&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;4&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;5&lt;/span&gt;&lt;span class="p"&gt;]).&lt;/span&gt;&lt;span class="nf"&gt;pipe&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
  &lt;span class="nf"&gt;filter&lt;/span&gt;&lt;span class="p"&gt;((&lt;/span&gt;&lt;span class="nx"&gt;x&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;x&lt;/span&gt; &lt;span class="o"&gt;%&lt;/span&gt; &lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;)&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="nf"&gt;take&lt;/span&gt;&lt;span class="p"&gt;(&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;map&lt;/span&gt;&lt;span class="p"&gt;((&lt;/span&gt;&lt;span class="nx"&gt;firstValue&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;The first even number was &lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="nx"&gt;firstValue&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nf"&gt;subscribe&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;log&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;There are a ton more operators that do vastly different things in categories such as: Creation, Filtering, Combination, Error Handling, Transformation, Multicasting, etc. I encourage you to try a few from each of the categories out. This is the power of RxJS, there's a lot already done for you!&lt;/p&gt;

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

&lt;p&gt;A Subject is like an Observable, but can multicast to many Observers. Subjects are like EventEmitters: they maintain a registry of many listeners. In fact, part of a subject is literally an observable and you can get a reference to that observable. &lt;/p&gt;

&lt;p&gt;The easiest way to think of a subject is quite literally:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Subject = Observer + Observable&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Example:&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;Subject&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="k"&gt;from&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;rxjs&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;subject&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nx"&gt;Subject&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;number&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;

&lt;span class="nx"&gt;subject&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;subscribe&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;
  &lt;span class="na"&gt;next&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;v&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;`observerA: &lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;v&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;`&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="p"&gt;});&lt;/span&gt;
&lt;span class="nx"&gt;subject&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;subscribe&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;
  &lt;span class="na"&gt;next&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;v&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;`observerB: &lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;v&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;`&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="p"&gt;});&lt;/span&gt;

&lt;span class="nx"&gt;subject&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;next&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="nx"&gt;subject&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;next&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

&lt;span class="c1"&gt;// Logs:&lt;/span&gt;
&lt;span class="c1"&gt;// observerA: 1&lt;/span&gt;
&lt;span class="c1"&gt;// observerB: 1&lt;/span&gt;
&lt;span class="c1"&gt;// observerA: 2&lt;/span&gt;
&lt;span class="c1"&gt;// observerB: 2&lt;/span&gt;

&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;observable&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt;&lt;span class="p"&gt;([&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;3&lt;/span&gt;&lt;span class="p"&gt;]);&lt;/span&gt;

&lt;span class="nx"&gt;observable&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;subscribe&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;subject&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt; &lt;span class="c1"&gt;// You can subscribe providing a Subject&lt;/span&gt;

&lt;span class="c1"&gt;// Logs:&lt;/span&gt;
&lt;span class="c1"&gt;// observerA: 1&lt;/span&gt;
&lt;span class="c1"&gt;// observerB: 1&lt;/span&gt;
&lt;span class="c1"&gt;// observerA: 2&lt;/span&gt;
&lt;span class="c1"&gt;// observerB: 2&lt;/span&gt;
&lt;span class="c1"&gt;// observerA: 3&lt;/span&gt;
&lt;span class="c1"&gt;// observerB: 3&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;IMO, the best use case for Subjects is when the code it is referenced in is the one that is producing the observable data. You can easily let your consumers subscribe to the Subject and then call the &lt;code&gt;.next()&lt;/code&gt; function to push data into the pipeline. Be wary of overusing them since most problems are solvable with only data transformation and Observables.&lt;/p&gt;

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

&lt;p&gt;Finally, schedulers! They might seem hard to understand but are quite simple at a surface level which is more than enough for us to know about. In essence, schedulers control the order of tasks for Observables. There are only a few of them and they won't be changing anytime soon, here they are:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F0iuxaq13i0seumfqvsv0.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F0iuxaq13i0seumfqvsv0.png" alt="" width="789" height="282"&gt;&lt;/a&gt;Table of the types of schedulers   &lt;/p&gt;

&lt;p&gt;You can use schedulers by passing them to observables through a handful of operators (usually of the creation category) as arguments. The most basic example, forcing a synchronous observable to behave asynchronously:&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;Observable&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;asyncScheduler&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;rxjs&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;observeOn&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;rxjs/operators&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;observable&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;Observable&lt;/span&gt;&lt;span class="p"&gt;((&lt;/span&gt;&lt;span class="nx"&gt;observer&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nx"&gt;observer&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;next&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="nx"&gt;observer&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;next&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="nx"&gt;observer&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;next&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;3&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="nx"&gt;observer&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;complete&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
&lt;span class="p"&gt;}).&lt;/span&gt;&lt;span class="nf"&gt;pipe&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
  &lt;span class="nf"&gt;observeOn&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;asyncScheduler&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="p"&gt;);&lt;/span&gt;

&lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;just before subscribe&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="nx"&gt;observable&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;subscribe&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;
  &lt;span class="nf"&gt;next&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;x&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;got value &lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="nx"&gt;x&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
  &lt;span class="p"&gt;},&lt;/span&gt;
  &lt;span class="nf"&gt;error&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;err&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;error&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;something wrong occurred: &lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="nx"&gt;err&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="p"&gt;},&lt;/span&gt;
  &lt;span class="nf"&gt;complete&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
     &lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;done&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="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;just after subscribe&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

&lt;span class="c1"&gt;// Logs&lt;/span&gt;
&lt;span class="c1"&gt;// just before subscribe&lt;/span&gt;
&lt;span class="c1"&gt;// just after subscribe&lt;/span&gt;
&lt;span class="c1"&gt;// got value 1&lt;/span&gt;
&lt;span class="c1"&gt;// got value 2&lt;/span&gt;
&lt;span class="c1"&gt;// got value 3&lt;/span&gt;
&lt;span class="c1"&gt;// done&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Notice how the notifications got &lt;code&gt;value...&lt;/code&gt; were delivered after just after subscription. This is because &lt;code&gt;observeOn(asyncScheduler)&lt;/code&gt; introduces a proxy Observer between the new Observable and the final Observer. &lt;/p&gt;

&lt;p&gt;Other schedulers can be used for different timings. We are done!&lt;/p&gt;

&lt;h3&gt;
  
  
  Amazing RxJS Resources
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;RxJS visualizer:&lt;/strong&gt; &lt;a href="https://rxviz.com/" rel="noopener noreferrer"&gt;https://rxviz.com/&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Instant marble diagrams:&lt;/strong&gt; &lt;a href="https://thinkrx.io/" rel="noopener noreferrer"&gt;https://thinkrx.io/&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Docs with marble diagrams:&lt;/strong&gt; &lt;a href="https://rxmarbles.com/" rel="noopener noreferrer"&gt;https://rxmarbles.com/&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Operator decision tree:&lt;/strong&gt; &lt;a href="https://rxjs.dev/operator-decision-tree" rel="noopener noreferrer"&gt;https://rxjs.dev/operator-decision-tree&lt;/a&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Reference
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://gist.github.com/staltz/868e7e9bc2a7b8c1f754" rel="noopener noreferrer"&gt;https://gist.github.com/staltz/868e7e9bc2a7b8c1f754&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://www.reactivemanifesto.org/" rel="noopener noreferrer"&gt;https://www.reactivemanifesto.org/&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://en.wikipedia.org/wiki/Reactive_programming" rel="noopener noreferrer"&gt;https://en.wikipedia.org/wiki/Reactive_programming&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://www.zachgollwitzer.com/posts/2020/rxjs-marble-diagram/" rel="noopener noreferrer"&gt;https://www.zachgollwitzer.com/posts/2020/rxjs-marble-diagram/&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://medium.com/@bencabanes/marble-testing-observable-introduction-1f5ad39231c" rel="noopener noreferrer"&gt;https://medium.com/@bencabanes/marble-testing-observable-introduction-1f5ad39231c&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://www.lightbend.com/white-papers-and-reports/reactive-programming-versus-reactive-systems" rel="noopener noreferrer"&gt;https://www.lightbend.com/white-papers-and-reports/reactive-programming-versus-reactive-systems&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

</description>
      <category>javascript</category>
      <category>webdev</category>
      <category>reactive</category>
      <category>rxjs</category>
    </item>
    <item>
      <title>Journey of a web page 🛣️ - How browsers work</title>
      <dc:creator>Paulo Santos</dc:creator>
      <pubDate>Mon, 19 Jul 2021 09:04:55 +0000</pubDate>
      <link>https://dev.to/gitpaulo/journey-of-a-web-page-how-browsers-work-10co</link>
      <guid>https://dev.to/gitpaulo/journey-of-a-web-page-how-browsers-work-10co</guid>
      <description>&lt;p&gt;This article covers the processes that happen in-between a user entering a web address in a browser and a web page showing up as a result.&lt;/p&gt;

&lt;h2&gt;
  
  
  Overview
&lt;/h2&gt;

&lt;p&gt;There are a handful of steps that occur betiwx the time a user requests a web page and the time it displays in their browser. To better cover each of them, I've divided those steps into the following sections:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Navigation&lt;/strong&gt;

&lt;ul&gt;
&lt;li&gt;Resolving the web address (DNS Lookup)&lt;/li&gt;
&lt;li&gt;Establishing a connection to the server (TCP 3-way handshake)&lt;/li&gt;
&lt;li&gt;Establishing a security protocol (TLS negotiation)&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Fetching&lt;/strong&gt;

&lt;ul&gt;
&lt;li&gt;HTTP request&lt;/li&gt;
&lt;li&gt;HTTP response&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Parsing&lt;/strong&gt;

&lt;ul&gt;
&lt;li&gt;Building the DOM tree&lt;/li&gt;
&lt;li&gt;Building the CSSOM tree&lt;/li&gt;
&lt;li&gt;Combining the trees into the render tree&lt;/li&gt;
&lt;li&gt;Preload Scanner&lt;/li&gt;
&lt;li&gt;JavaScript Compilation&lt;/li&gt;
&lt;li&gt;Building the Accessibility Tree&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Rendering&lt;/strong&gt;

&lt;ul&gt;
&lt;li&gt;Critical Rendering Path&lt;/li&gt;
&lt;li&gt;Layout&lt;/li&gt;
&lt;li&gt;Paint&lt;/li&gt;
&lt;li&gt;Compositing&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Finalising&lt;/strong&gt;

&lt;ul&gt;
&lt;li&gt;JavaScript Occupied.&lt;/li&gt;
&lt;li&gt;User can now browse the page!&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Use this index to jump to any particular section of interest. If you're new to some of these concepts, I suggest a linear read. It is time for a quick background lesson!&lt;/p&gt;

&lt;h2&gt;
  
  
  Background
&lt;/h2&gt;

&lt;p&gt;This section contains a very &lt;em&gt;quick&lt;/em&gt; and &lt;em&gt;general&lt;/em&gt; overview of the some of the core background concepts that are required to understand the later parts of the article.&lt;/p&gt;

&lt;h3&gt;
  
  
  Networking models
&lt;/h3&gt;

&lt;p&gt;Models exist to explain how data is transmitted through a network. In particular, there exists a network model so widely known that even those that do not partake in &lt;em&gt;hackerman&lt;/em&gt; things might've heard of! We call it the Open Systems Interconnected (OSI) model.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fsx08iepkwc18o55nwx9s.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fsx08iepkwc18o55nwx9s.png" alt="The OSI Model" width="710" height="722"&gt;&lt;/a&gt;&lt;a href="https://community.fs.com/blog/tcpip-vs-osi-whats-the-difference-between-the-two-models.html" title="foo" rel="noopener noreferrer"&gt;The OSI Model&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://www.iso.org/ics/35.100/x/" rel="noopener noreferrer"&gt;The Open Systems Interconnection (OSI) model&lt;/a&gt; describes seven layers that computer systems use to communicate over a network. Each upper layer is one level of abstraction higher than the previous, all the way up to the application (browser) layer which we will be talking about.&lt;/p&gt;

&lt;p&gt;It’s important to understand that the OSI model is a “conceptual model” for how applications communicate over a network. It is &lt;strong&gt;not&lt;/strong&gt; a protocol. Do not get the two confused. Protocols are strict sets of rules that may live within these layers.&lt;/p&gt;

&lt;p&gt;An older and very similar model, possibly more relevant towards the article, is the &lt;a href="https://en.wikipedia.org/wiki/Internet_protocol_suite" rel="noopener noreferrer"&gt;TCP/IP model&lt;/a&gt;. This network model is used for both modelling current Internet architecture and providing a set of rules (concrete protocols) that are followed by all forms of transmission over that network.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fd4qicoy7basi6gd4joxr.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fd4qicoy7basi6gd4joxr.png" alt="" width="710" height="450"&gt;&lt;/a&gt;&lt;a href="https://community.fs.com/blog/tcpip-vs-osi-whats-the-difference-between-the-two-models.html" title="OSI vs TCP/IP" rel="noopener noreferrer"&gt;OSI vs TCP/IP&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;I will be using and referring to this model with its associated protocols throughout the article.&lt;/p&gt;

&lt;p&gt;Any data sent from an application to another will have to travel up and down through these layers a few numbers of times (depending on how many middlemen there are). Of course, this happens incredibly fast nowadays, however, it still does happen and understanding the overview of the process is something that every developer should know. The following is an image representation of network process between a server and a client application:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F24o98vnamwefnr850216.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F24o98vnamwefnr850216.png" alt="" width="710" height="440"&gt;&lt;/a&gt;&lt;a href="https://community.fs.com/blog/tcpip-vs-osi-whats-the-difference-between-the-two-models.html" title="TCP/IP data travel" rel="noopener noreferrer"&gt;TCP/IP model data path between applications&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Take this example - a user requesting to browse a page using their browser: &lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;The request is first sent to the application layer, where it is processed from layer to layer down with each layer performing its designated functions. &lt;/li&gt;
&lt;li&gt;The data is then transmitted over the physical layer of the network until the destination server or another device receives it. &lt;/li&gt;
&lt;li&gt;At this point the data is passed up through the layers again, each layer performing its assigned operations until the data is used by the web server software. &lt;/li&gt;
&lt;li&gt;This process is repeated again for the response of the server. &lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;In general, this is how machines communicate over the network!&lt;/p&gt;

&lt;h3&gt;
  
  
  High-level abstraction of a browser
&lt;/h3&gt;

&lt;p&gt;The later sections of the article will be covering how a typical browser displays the content of a page on screen. A high-level understanding of the browser is important when reading those sections. I will be referencing some of the following browser components:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;The user interface:&lt;/strong&gt; this includes the address bar, back/forward button, bookmarking menu, etc. Every part of the browser display except the window where you see the requested page.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;The browser engine:&lt;/strong&gt; marshals actions between the UI and the rendering engine.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;The rendering engine:&lt;/strong&gt; responsible for displaying requested content. For example, if the requested content is HTML, the rendering engine parses HTML and CSS and displays the parsed content on the screen.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Networking:&lt;/strong&gt; for network calls such as HTTP requests, using different implementations for different platforms behind a platform-independent interface.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;UI backend:&lt;/strong&gt; used for drawing basic widgets like combo boxes and windows. This backend exposes a generic interface that is not platform-specific. Underneath it uses operating system user interface methods.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;JavaScript interpreter:&lt;/strong&gt; Used to parse and execute JavaScript code.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Data storage:&lt;/strong&gt; This is a persistence layer. The browser may need to save all sorts of data locally, such as cookies. Browsers also support storage mechanisms such as localStorage, IndexedDB, WebSQL and FileSystem.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fivei7zfohim9n6l83bbk.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fivei7zfohim9n6l83bbk.png" alt="" width="500" height="339"&gt;&lt;/a&gt;&lt;a href="https://www.html5rocks.com/en/tutorials/internals/howbrowserswork/" title="Browser Components" rel="noopener noreferrer"&gt;Browser Components&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;It is important to note that browsers such as Chrome have a multi-process approach for performance and security reasons. This means that they run instances of some of these components, such as the rendering engine, for each tab (each tab is a separate process). You can find proof of this by checking chrome's processes in a task manager.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fwv6sub7wk7fxyi25j1yh.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fwv6sub7wk7fxyi25j1yh.png" alt="" width="650" height="385"&gt;&lt;/a&gt;Screenshot of Chrome's Task Manager&lt;/p&gt;

&lt;p&gt;As you can observe from the screenshot above, each tab has a process priority and CPU/Network/GPU statistics implying that they work like normal processes. That is because they do! You can further confirm this by listing your OS's processes and you will surely find them there.&lt;/p&gt;

&lt;p&gt;To conclude this background section, it is important to note that what you just read so far is a &lt;strong&gt;very&lt;/strong&gt; high-level generalisation and abstraction of how networks and browsers actually work. Not all networks strictly abide by the OSI/TCP IP models and the main browsers in use today are all different in their own ways but share a common base of concepts that allows us to abstract them to what you've just read. &lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;For browsers, as an example, they all follow (to some degree) the specifications maintained by the &lt;a href="https://www.w3.org/" rel="noopener noreferrer"&gt;W3C (World Wide Web Consortium) organization&lt;/a&gt;, which is the standards organization for the web. However, the actual implementation of each component varies quite significantly. e.g. rendering engines are different, Internet Explorer uses Trident, Firefox uses Gecko, Safari uses WebKit. Chrome, Edge and Opera use Blink, a fork of WebKit etc. And the same goes for javascript engine pipelines!&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Journey of a page
&lt;/h2&gt;

&lt;p&gt;You open up a browser and type in &lt;a href="http://www.google.com" rel="noopener noreferrer"&gt;www.google.com&lt;/a&gt;. This is what happens.&lt;/p&gt;

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

&lt;p&gt;The first step is navigating to the correct place. Navigating to a web page is finding where the assets for that page are located. To us, web pages are simply domain names, but to computers, they resolve into IP addresses.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F3l0quvd7dcsg97hbfmfu.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F3l0quvd7dcsg97hbfmfu.png" alt="" width="630" height="172"&gt;&lt;/a&gt; &amp;lt;-&amp;gt; IP&lt;/p&gt;

&lt;p&gt;If you navigate to &lt;a href="http://www.google.com" rel="noopener noreferrer"&gt;www.google.com&lt;/a&gt;, the page resources will be located on a server with an IP address such as 93.184.216.34 (of sorts). If you’ve never visited this site, a Domain Name System (DNS) lookup must happen.&lt;/p&gt;

&lt;h5&gt;
  
  
  Round Trip Time
&lt;/h5&gt;

&lt;p&gt;&lt;a href="https://en.wikipedia.org/wiki/Round-trip_delay" rel="noopener noreferrer"&gt;Round-trip time (RTT)&lt;/a&gt; is the duration, measured in milliseconds, from when a browser sends a request to when it receives a response from a server. It's a key performance metric for web applications and one of the main factors, along with &lt;a href="https://developer.mozilla.org/en-US/docs/Glossary/time_to_first_byte" rel="noopener noreferrer"&gt;Time to First Byte (TTFB)&lt;/a&gt;, when measuring page load time and network latency.&lt;/p&gt;

&lt;p&gt;I will be annotating each network process with their corresponding RTT.&lt;/p&gt;

&lt;h4&gt;
  
  
  Resolving a web address - The DNS Process (O RTT)
&lt;/h4&gt;

&lt;p&gt;An overview of the DNS process for &lt;code&gt;www.google.com&lt;/code&gt; is as follows:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Check browser &amp;amp; OS cache, return if IP found.&lt;/li&gt;
&lt;li&gt;Browser sends out a request asking for a DNS resolver. 

&lt;ol&gt;
&lt;li&gt;DNS resolver checks its cache, return if IP is found.&lt;/li&gt;
&lt;/ol&gt;


&lt;/li&gt;

&lt;li&gt;DNS resolver sends out a request asking root nameservers.&lt;/li&gt;

&lt;li&gt;A root nameserver responds to the DNS resolver with an IP address to a TLD nameserver (in this case the TLD for extensions of &lt;code&gt;.com&lt;/code&gt;).&lt;/li&gt;

&lt;li&gt;DNS resolver sends out another request, now to the TLD nameserver, asking if they know what the IP is.&lt;/li&gt;

&lt;li&gt;TLD nameserver responds back to the DNS resolver with an IP of the authoritative nameserver.&lt;/li&gt;

&lt;li&gt;DNS resolver sends out the final request to the authoritative nameserver asking for the IP.&lt;/li&gt;

&lt;li&gt;The authoritative nameserver will scan zones files to find the domain name:ipaddress mapping and will return whether it exists or not to the DNS resolver.&lt;/li&gt;

&lt;li&gt;Finally, the DNS resolver will now respond back to the browser with the IP of the server the browser is trying to communicate.&lt;/li&gt;

&lt;/ol&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fhglrqe8nj9us42fuxs8d.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fhglrqe8nj9us42fuxs8d.png" alt="" width="800" height="450"&gt;&lt;/a&gt;&lt;a href="https://youtu.be/vrxwXXytEuI" title="TITLE" rel="noopener noreferrer"&gt;Visualisation of the DNS process&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Note that this process is usually incredibly fast and rarely follows through in its entirety because of all the layers of caching. It was designed to be fast!&lt;/p&gt;

&lt;h4&gt;
  
  
  Establishing a connection to the server - TCP Handshake (1 RTT)
&lt;/h4&gt;

&lt;p&gt;Now that the IP address is known, the browser sets up a connection to the server via a &lt;a href="https://www.sciencedirect.com/topics/computer-science/three-way-handshake" rel="noopener noreferrer"&gt;TCP three-way handshake&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://en.wikipedia.org/wiki/Transmission_Control_Protocol" rel="noopener noreferrer"&gt;TCP&lt;/a&gt; uses a three-way handshake to establish a reliable connection. The connection is full-duplex, and both sides synchronize (SYN) and acknowledge (ACK) each other. The exchange of these four flags is performed in three steps—SYN, SYN-ACK, and ACK—as shown in&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fdn8y466ruwdfllwwtaig.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fdn8y466ruwdfllwwtaig.png" alt="" width="355" height="167"&gt;&lt;/a&gt;&lt;a href="https://www.sciencedirect.com/topics/computer-science/three-way-handshake" title="TCP Handskae" rel="noopener noreferrer"&gt;TCP 3-way handshake&lt;/a&gt;&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;The client chooses an initial sequence number, set in the first SYN packet. &lt;/li&gt;
&lt;li&gt;The server also chooses its own initial sequence number. &lt;/li&gt;
&lt;li&gt;Each side acknowledges the other's sequence number by incrementing it; this is the acknowledgement number.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Once a connection is established, ACKs typically follow for each segment. The connection will eventually end with an RST (reset or tear down the connection) or FIN (gracefully end the connection).&lt;/p&gt;

&lt;p&gt;This mechanism is designed so that two entities attempting to communicate, in this case, the browser and web server, can negotiate the parameters of the network TCP socket connection before transmitting data, in our case, it will be over HTTPS—the secure version of &lt;a href="https://developer.mozilla.org/en-US/docs/Web/HTTP" rel="noopener noreferrer"&gt;HTTP&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;HTTPS is HTTP with encryption. The only difference between the two protocols is that HTTPS uses &lt;a href="https://en.wikipedia.org/wiki/Transport_Layer_Security" rel="noopener noreferrer"&gt;TLS (SSL)&lt;/a&gt; to encrypt normal HTTP requests and responses. As a result, HTTPS provides a solid layer of security over HTTP. A website that uses HTTP has &lt;code&gt;HTTP://&lt;/code&gt; in its URL, while a website that uses HTTPS has &lt;code&gt;HTTPS://&lt;/code&gt;.&lt;/p&gt;

&lt;h4&gt;
  
  
  Establishing a security protocol - TLS Negotiation (~2 RTT)
&lt;/h4&gt;

&lt;p&gt;For secure connections established over HTTPS, another "handshake" is required. This handshake, or rather the TLS negotiation, determines which cypher will be used to encrypt the communication, verifies the server, and establishes that a secure connection is in place before beginning the actual transfer of data.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fmuxmc254vu339latlf61.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fmuxmc254vu339latlf61.png" alt="" width="758" height="340"&gt;&lt;/a&gt;&lt;a href="https://blog.cloudflare.com/keyless-ssl-the-nitty-gritty-technical-details/" title="TSL Hanshake" rel="noopener noreferrer"&gt;Modern day TLS establishing&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;While making the connection secure adds time to the page load, a secure connection is worth the latency expense, as the data transmitted between the browser and the web server cannot normally be decrypted by a third party. TLS has come a long way and version 1.3 upwards has reduced the Round Trip Time (RTT) from 4 all the way to 2 or even 1 depending on the situation.&lt;/p&gt;

&lt;p&gt;Assuming DNS is instantaneous and adding in the HTTP fetch RTT (next section), this leaves 4 round trips before the browser can start showing the page. If you’re visiting a site you’ve recently connected to, the TLS handshake phase can be shortened from 2 round trips to 1 with &lt;a href="https://blog.cloudflare.com/tls-session-resumption-full-speed-and-secure/" rel="noopener noreferrer"&gt;TLS session resumption&lt;/a&gt;.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;New Connection: 4 RTT + DNS&lt;/li&gt;
&lt;li&gt;Resumed Connection: 3 RTT + DNS&lt;/li&gt;
&lt;/ul&gt;

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

&lt;p&gt;Now that we have a TCP connection setup and the TLS exchange has been completed, the browser can now begin to fetch the page's resources. It starts by fetching the markup document for the page. It does this by using the &lt;a href="https://developer.mozilla.org/en-US/docs/Web/HTTP" rel="noopener noreferrer"&gt;HTTP protocol&lt;/a&gt;. HTTP requests are sent via TCP/IP and in our case encrypted with Transport Layer Security (TLS)—since google uses HTTPS.&lt;/p&gt;

&lt;h4&gt;
  
  
  HTTP Request
&lt;/h4&gt;

&lt;p&gt;To fetch a page an &lt;a href="https://www.restapitutorial.com/lessons/idempotency.html" rel="noopener noreferrer"&gt;idempotent&lt;/a&gt; (not changing the server state) request is made. We use the HTTP GET request.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;GET&lt;/code&gt;—Requests information from a given server using a &lt;a href="https://en.wikipedia.org/wiki/Uniform_Resource_Identifier" rel="noopener noreferrer"&gt;Uniform Resource Identifier (URI)&lt;/a&gt;. Specification &lt;a href="https://datatracker.ietf.org/doc/html/rfc7231#section-4.3.1" rel="noopener noreferrer"&gt;correct implementations&lt;/a&gt; of  the GET method only retrieve data and do not cause changes in the source state. No matter how many times you request the same resource, you will never cause a change in state.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;There are many other types of HTTP methods:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fegy39l7tc3e4pm965lnq.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fegy39l7tc3e4pm965lnq.png" alt="" width="364" height="196"&gt;&lt;/a&gt;&lt;a href="https://datatracker.ietf.org/doc/html/rfc7231#section-8.1.3" title="HTTP method types" rel="noopener noreferrer"&gt;HTTP Methods as per sepecification&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;For fetching our page we are only interested in &lt;code&gt;GET&lt;/code&gt;.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;GET / HTTP/2
Host: www.google.com
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:89.0) Gecko/20100101 Firefox/89.0
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8
Accept-Language: en-GB,en;q=0.5
Accept-Encoding: gzip, deflate, br
Connection: keep-alive
Upgrade-Insecure-Requests: 1
Cache-Control: max-age=0
TE: Trailers
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h4&gt;
  
  
  HTTP Response
&lt;/h4&gt;

&lt;p&gt;Once the webserver receives the request. It will parse the request and try to fulfil it. We assume the request is valid and the files are available. It will reply with an HTTP response, attaching the relevant headers and the contents of the requested HTML document to the body of that response structure.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;HTTP/2 200 OK
date: Sun, 18 Jul 2021 00:26:11 GMT
expires: -1
cache-control: private, max-age=0
content-type: text/html; charset=UTF-8
strict-transport-security: max-age=31536000
content-encoding: br
server: gws
content-length: 37418
x-xss-protection: 0
x-frame-options: SAMEORIGIN
domain=www.google.com
priority=high
X-Firefox-Spdy: h2
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;*the source code of the HTML document will be in the body of the response.&lt;/p&gt;

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

&lt;p&gt;Once the browser receives the response, it can begin parsing the information received. Parsing is the step the browser takes to turn the data it receives over the network into the DOM and CSSOM, which is used by the renderer to paint a page to the screen.&lt;/p&gt;

&lt;p&gt;The &lt;a href="https://en.wikipedia.org/wiki/Document_Object_Model" rel="noopener noreferrer"&gt;Document Object Model (DOM)&lt;/a&gt; is an internal representation of the objects that comprise the structure and content of the markup (HTML in this case) document the browser just received. It represents the page so that programs can change the document structure, style, and content. &lt;/p&gt;

&lt;p&gt;The DOM represents the document as nodes and objects. That way, programming languages can connect to the page. There are many different types of nodes in a DOM tree. An example part of the specification for the &lt;a href="https://developer.mozilla.org/en-US/docs/Web/API/Node" rel="noopener noreferrer"&gt;DOM Node Interface&lt;/a&gt; looks as follows:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;code&gt;Node.ELEMENT_NODE&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;Node.ATTRIBUTE_NODE&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;Node.TEXT_NODE&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;Node.CDATA_SECTION_NODE&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;Node.PROCESSING_INSTRUCTION_NODE&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;Node.COMMENT_NODE&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;Node.DOCUMENT_NODE&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;Node.DOCUMENT_TYPE_NODE&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;Node.DOCUMENT_FRAGMENT_NODE&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;Node.NOTATION_NODE&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;These node types cover all possible nodes in the document. Such representations help programming languages connect to the page so that they can manipulate it.&lt;/p&gt;

&lt;p&gt;To conclude our parsing preface, we need to talk about the CSSOM. &lt;/p&gt;

&lt;p&gt;The &lt;a href="https://developer.mozilla.org/en-US/docs/Web/API/CSS_Object_Model" rel="noopener noreferrer"&gt;CSS Object Model (CSSOM)&lt;/a&gt; is a set of APIs allowing the manipulation of CSS from JavaScript. It is much like the DOM, but for the CSS rather than the HTML. It allows users to read and modify CSS style dynamically. It is represented very similarly to the DOM, as a tree, and it will be used along with the DOM to form a render tree so that the browser can begin its rendering process. Let's find out how by going through the entire process.&lt;/p&gt;

&lt;h4&gt;
  
  
  Building the DOM tree
&lt;/h4&gt;

&lt;p&gt;The first step is processing the HTML markup and building the DOM tree. HTML parsing involves tokenization and tree construction. &lt;/p&gt;

&lt;p&gt;HTML may come as a surprise in the world of parsing as it cannot be parsed through conventional means as it cannot be defined by a &lt;a href="https://en.wikipedia.org/wiki/Context-free_grammar" rel="noopener noreferrer"&gt;Context Free Grammar (CFG)&lt;/a&gt;. Instead, there is a formal format for defining HTML which is called the &lt;a href="https://en.wikipedia.org/wiki/Document_type_definition" rel="noopener noreferrer"&gt;Document Type Definition (DTD)&lt;/a&gt;. I will not be going too much into detail about how this is done but the main reasons for this are:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;The forgiving nature of the language.&lt;/li&gt;
&lt;li&gt;The fact that browsers have traditional error tolerance to support well-known cases of invalid HTML.&lt;/li&gt;
&lt;li&gt;The parsing process is reentrant. For other languages, the source doesn't change during parsing, but in HTML, dynamic code (such as script elements containing &lt;code&gt;document.write()&lt;/code&gt; calls) can add extra tokens, so the parsing process actually modifies the input.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Unable to use the regular parsing techniques, browsers create custom parsers for parsing HTML.&lt;/p&gt;

&lt;p&gt;The parsing algorithm is described in detail by the &lt;a href="https://html.spec.whatwg.org/multipage/parsing.html" rel="noopener noreferrer"&gt;HTML5 specification&lt;/a&gt;. As previously mentioned, the algorithm consists of two stages: tokenization and tree construction.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Tokenization&lt;/strong&gt; is the lexical analysis, parsing the input into tokens. Among HTML tokens are start tags, end tags, attribute names and attribute values.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Tree construction&lt;/strong&gt; is essentially creating a tree-based of the parsed tokens and what we will be focusing on—The DOM tree.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The DOM tree describes the content of the document. The &lt;code&gt;&amp;lt;html&amp;gt;&lt;/code&gt; element is the first tag and root node of the document tree. The tree reflects the relationships and hierarchies between different tags. Tags nested within other tags are child nodes. The greater the number of DOM nodes, the longer it takes to construct the DOM tree. Below you can find a visual representation of the DOM tree—The output of the parser:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fk2ovvtmkybu182f1ak2b.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fk2ovvtmkybu182f1ak2b.png" alt="" width="754" height="689"&gt;&lt;/a&gt;Part of the DOM Tree&lt;/p&gt;

&lt;p&gt;When the parser finds non-blocking resources, such as an image, the browser will request those resources and continue parsing. Parsing can continue when a CSS file is encountered, but &lt;code&gt;&amp;lt;script&amp;gt;&lt;/code&gt; tags—particularly those without an async or defer attribute—block rendering, and pause the parsing of HTML. Though the browser's preload scanner hastens this process, excessive scripts can still be a significant bottleneck.&lt;/p&gt;

&lt;h4&gt;
  
  
  Building the CSSOM tree
&lt;/h4&gt;

&lt;p&gt;The second step is processing CSS and building the CSSOM tree. In a similar fashion to the DOM parsing phase, the browser goes through each rule set in the CSS, creating a tree of nodes with parent, child, and sibling relationships based on the CSS selectors.&lt;/p&gt;

&lt;p&gt;In regards to parsing, well, unlike HTML, CSS is a context-free grammar and can be parsed using regular CFG parsing techniques. In fact the &lt;a href="https://www.w3.org/TR/CSS21/grammar.html" rel="noopener noreferrer"&gt;CSS specification defines CSS lexical and syntax grammar&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;As with HTML, the browser needs to convert the received CSS rules into something it can work with. From there, it repeats the HTML-to-object process, but for the CSS.&lt;/p&gt;

&lt;h4&gt;
  
  
  Combining the trees into the render tree
&lt;/h4&gt;

&lt;p&gt;The CSSOM and DOM trees are combined into a render tree, which is then used to compute the layout of each visible element and serves as an input to the paint process that renders the pixels to the screen.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fz6lpm4e05fws0naziz4p.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fz6lpm4e05fws0naziz4p.png" alt="" width="800" height="373"&gt;&lt;/a&gt;&lt;a href="HERE%20LINK" title="DOM + CSSOM"&gt;Combining the CSSOM + DOM trees to make the render tree&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;To construct the render tree, the browser roughly does the following:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Starting at the root of the DOM tree, traverse each visible node.

&lt;ul&gt;
&lt;li&gt;Some nodes are not visible (for example, script tags, meta tags, and so on), and are omitted since they are not reflected in the rendered output.&lt;/li&gt;
&lt;li&gt;Some nodes are hidden via CSS and are also omitted from the render tree; for example, the span node—in the example above—is missing from the render tree because we have an explicit rule that sets the "display: none" property on it.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;For each visible node, find the appropriate matching CSSOM rules and apply them.&lt;/li&gt;
&lt;li&gt;Emit visible nodes with content and their computed styles. &lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;The final output is a render that contains both the content and style information of all the visible content on the screen. With the render tree in place, we can proceed to the "layout" stage.&lt;/p&gt;

&lt;h4&gt;
  
  
  Preload Scanner
&lt;/h4&gt;

&lt;p&gt;While the browser's main thread is busing building the DOM tree it has a helper worker scan through the content available. This helper is the &lt;a href="https://ariya.io/2013/04/css-preload-scanner-in-webkit" rel="noopener noreferrer"&gt;preload scanner&lt;/a&gt; and will prepare high priority fetch request for resources like CSS, JavaScript, and web fonts. This is an optimization added over the parsing stage as it would take far too long to make these requests as the parser finds references to them.&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;link&lt;/span&gt; &lt;span class="na"&gt;rel=&lt;/span&gt;&lt;span class="s"&gt;"stylesheet"&lt;/span&gt; &lt;span class="na"&gt;src=&lt;/span&gt;&lt;span class="s"&gt;"styles.css"&lt;/span&gt;&lt;span class="nt"&gt;/&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;script &lt;/span&gt;&lt;span class="na"&gt;src=&lt;/span&gt;&lt;span class="s"&gt;"myscript.js"&lt;/span&gt; &lt;span class="na"&gt;async&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;img&lt;/span&gt; &lt;span class="na"&gt;src=&lt;/span&gt;&lt;span class="s"&gt;"myimage.jpg"&lt;/span&gt; &lt;span class="na"&gt;alt=&lt;/span&gt;&lt;span class="s"&gt;"image description"&lt;/span&gt;&lt;span class="nt"&gt;/&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;script &lt;/span&gt;&lt;span class="na"&gt;src=&lt;/span&gt;&lt;span class="s"&gt;"anotherscript.js"&lt;/span&gt; &lt;span class="na"&gt;async&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&amp;lt;/script&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Taking the example above, the preload scanner will try to find the scripts and images, and start downloading them. There are ways to communicate to the preload scanner via the HTML—the attributes: &lt;code&gt;async&lt;/code&gt; and &lt;code&gt;defer&lt;/code&gt;.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;async&lt;/code&gt;: When present, it specifies that the script will be executed asynchronously as soon as it is available.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;defer&lt;/code&gt;: When present, it specifies that the script is executed when the page has finished parsing.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Waiting to obtain CSS doesn't block HTML parsing or downloading, but it does block JavaScript because JavaScript is often used to query CSS properties’ impact on elements.&lt;/p&gt;

&lt;h4&gt;
  
  
  JavaScript Compilation
&lt;/h4&gt;

&lt;p&gt;While the CSS is being parsed and the CSSOM created, other assets, including JavaScript files, are downloading (thanks to the preload scanner). JavaScript is interpreted, compiled, parsed and executed. &lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F0pdfl3y8t9d7vm2qaxlg.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F0pdfl3y8t9d7vm2qaxlg.png" alt="" width="800" height="355"&gt;&lt;/a&gt;&lt;a href="https://v8.dev/blog/background-compilation" title="TITLE" rel="noopener noreferrer"&gt;Overview of the JS compilation process&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The scripts are parsed into &lt;a href="https://en.wikipedia.org/wiki/Abstract_syntax_tree" rel="noopener noreferrer"&gt;abstract syntax trees&lt;/a&gt;. Like in the above diagram (from V8's engine blog), some browser engines take the Abstract Syntax Tree and pass it into an interpreter, outputting bytecode which is executed on the main thread. This is known as JavaScript compilation.&lt;/p&gt;

&lt;h4&gt;
  
  
  Building the Accessibility Tree
&lt;/h4&gt;

&lt;p&gt;The browser also builds an accessibility tree that assistive devices use to parse and interpret content. The &lt;a href="https://wicg.github.io/aom/explainer.html" rel="noopener noreferrer"&gt;accessibility object model (AOM)&lt;/a&gt; is like a semantic version of the DOM. The browser updates the accessibility tree when the DOM is updated. The accessibility tree is not modifiable by assistive technologies themselves.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fa4e181v8hq7vmuvdegh5.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fa4e181v8hq7vmuvdegh5.png" alt="" width="735" height="401"&gt;&lt;/a&gt;Build and use process of the AOM&lt;/p&gt;

&lt;p&gt;Until the AOM is built, the content is not accessible to screen readers.&lt;/p&gt;

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

&lt;p&gt;Now that the information has been parsed the browser can begin to display it. To achieve this the browser will now use the render tree to produce a visual representation of the document. Rendering steps include layout, paint and, in some cases, compositing.&lt;/p&gt;

&lt;h4&gt;
  
  
  Critical Rendering Path
&lt;/h4&gt;

&lt;p&gt;Now is a good time to introduce the notion of the &lt;a href="https://developer.mozilla.org/en-US/docs/Web/Performance/Critical_rendering_path" rel="noopener noreferrer"&gt;Critical Rendering Path&lt;/a&gt;. The best way to visualise it is with a diagram:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F081c6qn9jf63g3038yt5.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F081c6qn9jf63g3038yt5.png" alt="" width="800" height="230"&gt;&lt;/a&gt;&lt;a href="https://guillermo.at/browser-critical-render-path" title="CRP" rel="noopener noreferrer"&gt;The Critical Rendering Path&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Optimizing the critical rendering path improves the time to first render. It is important to ensure reflows and repaints can happen at the &lt;a href="https://developer.mozilla.org/en-US/docs/Web/API/Frame_Timing_API" rel="noopener noreferrer"&gt;goal of 60 frames per second&lt;/a&gt; (for performant user interactions).&lt;/p&gt;

&lt;p&gt;We won't be going into detail on how to optimise the CRP but the general gist relies on improving page load speed by prioritizing which resources get loaded, controlling the order in which they are loaded, and reducing the file sizes of those resources.&lt;/p&gt;

&lt;p&gt;Now let's move on to the rendering stages.&lt;/p&gt;

&lt;h4&gt;
  
  
  Layout
&lt;/h4&gt;

&lt;p&gt;Layout is the first rendering stage, where the geometry and positioning of the render tree nodes are determined. Once the render tree is built, the layout commences. &lt;/p&gt;

&lt;p&gt;Layout is a recursive process. It begins at the root renderer, which corresponds to the &lt;code&gt;&amp;lt;html&amp;gt;&lt;/code&gt; element of the HTML document. Layout continues recursively through some or all of the frame hierarchy, computing geometric information for each renderer that requires it. &lt;/p&gt;

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

&lt;p&gt;At the end of the layout stage, a tree similar to the one above is generated with what we call blocks/Coxes as nodes. Blocks/Boxes hold the geometric information of DOM objects and nodes.&lt;/p&gt;

&lt;h5&gt;
  
  
  Dirty bit system
&lt;/h5&gt;

&lt;p&gt;In order not to do a full layout for every small change, browsers use a "dirty bit" system. A renderer that is changed or added marks itself and its children as "dirty": needing layout.&lt;/p&gt;

&lt;p&gt;There are two flags: &lt;br&gt;
    - &lt;strong&gt;dirty:&lt;/strong&gt; node needs a layout.&lt;br&gt;
    - &lt;strong&gt;children are dirty:&lt;/strong&gt; node has at least one child that needs a layout.&lt;/p&gt;

&lt;h5&gt;
  
  
  Layout Algorithm
&lt;/h5&gt;

&lt;p&gt;Using the dirty bit system browsers can now perform an algorithm to generate the layout. A high-level abstraction of that algorithm is as folows:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Parent node determines its own width.&lt;/li&gt;
&lt;li&gt;Parent goes over children and:

&lt;ol&gt;
&lt;li&gt;Calculate child render's size&lt;/li&gt;
&lt;li&gt;Calls child layout if they have a dirty descendant&lt;/li&gt;
&lt;/ol&gt;


&lt;/li&gt;

&lt;li&gt;Parent uses children's accumulative heights and the heights of margins and padding to set its own height–this will be used by the parent renderer's parent.&lt;/li&gt;

&lt;li&gt;Sets its dirty bit to false.&lt;/li&gt;

&lt;/ol&gt;

&lt;p&gt;An added important concept is that of &lt;strong&gt;reflow&lt;/strong&gt;. As previously mentioned, the first time the size and position of nodes are determined is called &lt;strong&gt;layout&lt;/strong&gt;. Subsequent recalculations of node size and locations are called &lt;strong&gt;reflows&lt;/strong&gt;. As an example, suppose the initial layout occurs before the image is returned. Since we didn't declare the size of our image, there will be a reflow once the image size is known!&lt;/p&gt;

&lt;h4&gt;
  
  
  Paint
&lt;/h4&gt;

&lt;p&gt;The third and last stage of rendering. In this painting phase, the browser converts each box calculated in the layout phase to actual pixels on the screen. Painting involves drawing every visual part of an element to the screen, including text, colours, borders, shadows, and replaced elements like buttons and images. The browser needs to do this super quickly.&lt;/p&gt;

&lt;h5&gt;
  
  
  Painting order
&lt;/h5&gt;

&lt;p&gt;&lt;a href="https://www.w3.org/TR/CSS21/zindex.html" rel="noopener noreferrer"&gt;CSS2 defines the order of the painting process&lt;/a&gt;. This is actually the order in which the elements are stacked in the stacking contexts. This order affects painting since the stacks are painted from back to front. The stacking order of a block renderer is:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;background colour&lt;/li&gt;
&lt;li&gt;background image&lt;/li&gt;
&lt;li&gt;border&lt;/li&gt;
&lt;li&gt;children&lt;/li&gt;
&lt;li&gt;outline&lt;/li&gt;
&lt;/ol&gt;

&lt;h5&gt;
  
  
  Paint Layers
&lt;/h5&gt;

&lt;p&gt;Painting can break the elements in the layout tree into layers. Promoting content into layers on the GPU (instead of the main thread on the CPU) improves paint and repaint performance. There are specific properties and elements that instantiate a layer, including &lt;code&gt;&amp;lt;video&amp;gt;&lt;/code&gt; and &lt;code&gt;&amp;lt;canvas&amp;gt;&lt;/code&gt;, and any element which has the CSS properties of opacity, a 3D transform, will-change, and a few others. These nodes will be painted onto their own layer, along with their descendants, unless a descendant necessitates its own layer for one (or more) of the above reasons.&lt;/p&gt;

&lt;p&gt;Layers do improve performance but are expensive when it comes to memory management, so should not be overused as part of web performance optimization strategies.&lt;/p&gt;

&lt;h4&gt;
  
  
  Compositing
&lt;/h4&gt;

&lt;p&gt;When sections of the document are drawn in different layers, overlapping each other, compositing is necessary to ensure they are drawn to the screen in the right order and the content is rendered correctly.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fr33bwf2r09f27t73az2n.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fr33bwf2r09f27t73az2n.png" alt="" width="598" height="278"&gt;&lt;/a&gt;Compositing stage&lt;/p&gt;

&lt;p&gt;As the page continues to load assets, reflows can happen (recall our example image that arrived late).  A reflow sparks a repaint and a re-composite. Had we defined the size of our image, no-reflow would have been necessary, and only the layer that needed to be repainted would be repainted, and composited if necessary. But we didn't include the image size! When the image is obtained from the server, the rendering process goes back to the layout steps and restarts from there.&lt;/p&gt;

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

&lt;p&gt;Once the main thread is done painting the page, you would think we would be "all set." That isn't necessarily the case. If the load includes JavaScript, which was correctly deferred, and only executed after the onload event fires, the main thread might be busy, and not available for scrolling, touch, and other interactions.&lt;/p&gt;

&lt;h4&gt;
  
  
  JavaScript Occupied
&lt;/h4&gt;

&lt;p&gt;&lt;a href="https://web.dev/interactive/" rel="noopener noreferrer"&gt;Time to Interactive (TTI)&lt;/a&gt; is the measurement of how long it took from that first request which led to the DNS lookup and SSL connection to when the page is interactive—interactive being the point in time after the &lt;a href="https://developer.mozilla.org/en-US/docs/Glossary/First_contentful_paint" rel="noopener noreferrer"&gt;First Contentful Paint&lt;/a&gt; when the page responds to user interactions within 50ms. If the main thread is occupied parsing, compiling, and executing JavaScript, it is not available and therefore not able to respond to user interactions in a timely (&lt;a href="https://developer.mozilla.org/en-US/docs/Web/Performance/How_long_is_too_long" rel="noopener noreferrer"&gt;less than 50ms&lt;/a&gt;) fashion.&lt;/p&gt;

&lt;p&gt;In our example, maybe the image loaded quickly, but perhaps the anotherscript.js file was 2MB and our user's network connection was slow.  In this case, the user would see the page super quickly, but wouldn't be able to scroll without jank until the script was downloaded, parsed and executed. That is not a good user experience. Avoid occupying the main thread, as demonstrated in this WebPageTest example:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fxbkoby5bedm789lskzyb.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fxbkoby5bedm789lskzyb.png" alt="" width="800" height="466"&gt;&lt;/a&gt;Example - JavaScript hogging main thread&lt;/p&gt;

&lt;p&gt;In this example, the DOM content load process took over 1.5 seconds, and the main thread was fully occupied that entire time, unresponsive to click events or screen taps.&lt;/p&gt;

&lt;h4&gt;
  
  
  The user can now browse the page! 🎉
&lt;/h4&gt;

&lt;p&gt;Yes, after all these stages the user can now both see and interact with the page!&lt;/p&gt;

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

&lt;p&gt;For a simple page to be displayed in our browser window it may need to go through:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;DNS Lookup: To find out the IP of the web address.&lt;/li&gt;
&lt;li&gt;TCP Handshake: To set up TCP/IP communication between the client and server for the subsequent steps.&lt;/li&gt;
&lt;li&gt;TLS Handshake: To safeguard the information that will be sent via encryption.&lt;/li&gt;
&lt;li&gt;HTTP communication: To establish a method of communication that browsers can understand.&lt;/li&gt;
&lt;li&gt;Browser Parsing: To parse the HTTP's response—the document of the page to be displayed.&lt;/li&gt;
&lt;li&gt;Browser Rendering: To render the document on the browsers window.&lt;/li&gt;
&lt;li&gt;Javascript Occupied: To wait for JS to compile and execute as it may hog the main thread.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;It is incredible the number of things that happen for this seemingly simple task to be accomplished. Truly an impressive journey for our little page :)&lt;/p&gt;

&lt;h4&gt;
  
  
  There is more...
&lt;/h4&gt;

&lt;p&gt;In a real-world scenario, our little page may have to tackle even more obstacles before reaching its destination things such as: &lt;a href="https://www.nginx.com/resources/glossary/load-balancing/" rel="noopener noreferrer"&gt;load balancers, proxies&lt;/a&gt;, &lt;a href="https://www.nginx.com/resources/glossary/what-is-a-waf/" rel="noopener noreferrer"&gt;multiple layers of firewalls&lt;/a&gt;, etc... &lt;/p&gt;

&lt;p&gt;These topics are beasts of their own and if you're curious about how they work I recommend looking them up! Perhaps I'll write something for them in the future.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Thank you for reading,&lt;br&gt;
Paulo 😎&lt;/strong&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Reference
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://developer.mozilla.org/en-US/docs/Web/Performance/How_browsers_work#overview" rel="noopener noreferrer"&gt;https://developer.mozilla.org/en-US/docs/Web/Performance/How_browsers_work#overview&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://www.html5rocks.com/en/tutorials/internals/howbrowserswork" rel="noopener noreferrer"&gt;https://www.html5rocks.com/en/tutorials/internals/howbrowserswork&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://developers.google.com/web/fundamentals/" rel="noopener noreferrer"&gt;https://developers.google.com/web/fundamentals/&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://blog.cloudflare.com/introducing-0-rtt/" rel="noopener noreferrer"&gt;https://blog.cloudflare.com/introducing-0-rtt/&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://blog.cloudflare.com/keyless-ssl-the-nitty-gritty-technical-details/" rel="noopener noreferrer"&gt;https://blog.cloudflare.com/keyless-ssl-the-nitty-gritty-technical-details/&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://community.fs.com/blog/tcpip-vs-osi-whats-the-difference-between-the-two-models.html" rel="noopener noreferrer"&gt;https://community.fs.com/blog/tcpip-vs-osi-whats-the-difference-between-the-two-models.html&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://www.sciencedirect.com/topics/computer-science/three-way-handshake" rel="noopener noreferrer"&gt;https://www.sciencedirect.com/topics/computer-science/three-way-handshake&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://v8.dev/blog/background-compilation" rel="noopener noreferrer"&gt;https://v8.dev/blog/background-compilation&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://www.smashingmagazine.com/2016/12/gpu-animation-doing-it-right/" rel="noopener noreferrer"&gt;https://www.smashingmagazine.com/2016/12/gpu-animation-doing-it-right/&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

</description>
      <category>architecture</category>
      <category>html</category>
      <category>css</category>
      <category>javascript</category>
    </item>
  </channel>
</rss>
