<?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>Forem: Abhishek Mishra</title>
    <description>The latest articles on Forem by Abhishek Mishra (@abhishek_mishra_2002).</description>
    <link>https://forem.com/abhishek_mishra_2002</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%2F3000498%2Fe33930d8-cf8a-488b-a73f-e51162c9179c.png</url>
      <title>Forem: Abhishek Mishra</title>
      <link>https://forem.com/abhishek_mishra_2002</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://forem.com/feed/abhishek_mishra_2002"/>
    <language>en</language>
    <item>
      <title>Event Loop Deep Dive: What Every Frontend Dev Should Know — Timers, Microtasks, and Real Examples</title>
      <dc:creator>Abhishek Mishra</dc:creator>
      <pubDate>Sat, 18 Oct 2025 19:38:32 +0000</pubDate>
      <link>https://forem.com/abhishek_mishra_2002/event-loop-deep-dive-what-every-frontend-dev-should-know-timers-microtasks-and-real-examples-dma</link>
      <guid>https://forem.com/abhishek_mishra_2002/event-loop-deep-dive-what-every-frontend-dev-should-know-timers-microtasks-and-real-examples-dma</guid>
      <description>&lt;p&gt;If you’ve ever wondered why &lt;code&gt;Promise.resolve().then(...)&lt;/code&gt; runs before &lt;code&gt;setTimeout(..., 0)&lt;/code&gt;, or why your UI freezes while a loop “just counts to a million,” this post is for you.&lt;br&gt;
Let’s break down the &lt;strong&gt;JavaScript event loop&lt;/strong&gt; — in simple terms — with real examples you can run right in your browser console.&lt;/p&gt;


&lt;h2&gt;
  
  
  Table of contents
&lt;/h2&gt;

&lt;ol&gt;
&lt;li&gt;The big picture — what the event loop actually is&lt;/li&gt;
&lt;li&gt;Tasks (macrotasks) vs microtasks — the crucial difference&lt;/li&gt;
&lt;li&gt;Where timers, rAF and promises fit&lt;/li&gt;
&lt;li&gt;Concrete examples — paste these into your browser console&lt;/li&gt;
&lt;li&gt;Real world gotchas &amp;amp; best practices&lt;/li&gt;
&lt;li&gt;Debugging tips &amp;amp; tools&lt;/li&gt;
&lt;li&gt;Wrap-up / TL;DR&lt;/li&gt;
&lt;/ol&gt;



&lt;p&gt;&lt;a&gt;&lt;/a&gt;&lt;/p&gt;
&lt;h2&gt;
  
  
  1. The big picture — what the event loop actually is
&lt;/h2&gt;

&lt;p&gt;Think of JavaScript as a &lt;strong&gt;single worker&lt;/strong&gt; in your system — one person doing one task at a time.&lt;br&gt;
No extra threads, no multitasking magic.&lt;/p&gt;

&lt;p&gt;Here’s how it works:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;The &lt;strong&gt;call stack&lt;/strong&gt; is what the worker is doing &lt;em&gt;right now&lt;/em&gt;.&lt;/li&gt;
&lt;li&gt;The &lt;strong&gt;event loop&lt;/strong&gt; is like the manager who keeps checking, “Is the worker done? What’s next on the list?”&lt;/li&gt;
&lt;li&gt;The &lt;strong&gt;task queues&lt;/strong&gt; are the list of pending jobs waiting for their turn.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;There are two main kinds of tasks waiting to be picked:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Macrotasks&lt;/strong&gt; — bigger jobs like &lt;code&gt;setTimeout&lt;/code&gt;, I/O, user events.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Microtasks&lt;/strong&gt; — smaller, “finish this right after the current thing” jobs, like &lt;code&gt;Promise.then&lt;/code&gt;.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;👉 After one macrotask finishes, the event loop runs &lt;em&gt;all&lt;/em&gt; the microtasks before starting the next macrotask.&lt;/p&gt;

&lt;p&gt;That’s the golden rule. If you understand that, 80% of event loop mysteries disappear.&lt;/p&gt;



&lt;p&gt;&lt;a&gt;&lt;/a&gt;&lt;/p&gt;
&lt;h2&gt;
  
  
  2. Tasks (macrotasks) vs microtasks — the crucial difference
&lt;/h2&gt;
&lt;h3&gt;
  
  
  Macrotasks:
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;Examples: &lt;code&gt;setTimeout&lt;/code&gt;, &lt;code&gt;setInterval&lt;/code&gt;, DOM events, I/O.&lt;/li&gt;
&lt;li&gt;These are scheduled to run later, after microtasks are done.&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;
  
  
  Microtasks:
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;Examples: &lt;code&gt;Promise.then&lt;/code&gt;, &lt;code&gt;queueMicrotask&lt;/code&gt;, &lt;code&gt;async/await&lt;/code&gt; after &lt;code&gt;await&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;These run &lt;strong&gt;right after&lt;/strong&gt; the current code finishes, before rendering or the next macrotask.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Think of it like this:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Macrotask = “Do it later.”&lt;/li&gt;
&lt;li&gt;Microtask = “Do it immediately after this.”&lt;/li&gt;
&lt;/ul&gt;



&lt;p&gt;&lt;a&gt;&lt;/a&gt;&lt;/p&gt;
&lt;h2&gt;
  
  
  3. Where timers, rAF and promises fit
&lt;/h2&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Function&lt;/th&gt;
&lt;th&gt;Type&lt;/th&gt;
&lt;th&gt;When it runs&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;setTimeout(fn, 0)&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Macrotask&lt;/td&gt;
&lt;td&gt;After all microtasks finish&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;Promise.then(fn)&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Microtask&lt;/td&gt;
&lt;td&gt;Right after current code finishes&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;queueMicrotask(fn)&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Microtask&lt;/td&gt;
&lt;td&gt;Same as Promise.then timing&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;requestAnimationFrame(fn)&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Special&lt;/td&gt;
&lt;td&gt;Before the next screen paint&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;



&lt;p&gt;&lt;a&gt;&lt;/a&gt;&lt;/p&gt;
&lt;h2&gt;
  
  
  4. Concrete examples — paste these into your browser console
&lt;/h2&gt;
&lt;h3&gt;
  
  
  Example 1 — Basic ordering
&lt;/h3&gt;


&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&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;script start&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;);&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="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;setTimeout (macrotask)&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

&lt;span class="nb"&gt;Promise&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;resolve&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
  &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;then&lt;/span&gt;&lt;span class="p"&gt;(()&lt;/span&gt; &lt;span class="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;promise.then (microtask)&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;
  &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;then&lt;/span&gt;&lt;span class="p"&gt;(()&lt;/span&gt; &lt;span class="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;promise.then 2 (microtask)&lt;/span&gt;&lt;span class="dl"&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;script end&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;&lt;strong&gt;Expected output:&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;script start
script end
promise.then (microtask)
promise.then 2 (microtask)
setTimeout (macrotask)
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;✅ Microtasks run before macrotasks. Always.&lt;/p&gt;




&lt;h3&gt;
  
  
  Example 2 — async/await under the hood
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&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;start&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

&lt;span class="k"&gt;async&lt;/span&gt; &lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;foo&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;inside async&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="kc"&gt;null&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="nx"&gt;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;after await (microtask)&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;foo&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;end&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Expected output:&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;start
inside async
end
after await (microtask)
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;code&gt;await&lt;/code&gt; always pauses the function and resumes it as a microtask later.&lt;/p&gt;




&lt;h3&gt;
  
  
  Example 3 — requestAnimationFrame vs others
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&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;begin&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

&lt;span class="nf"&gt;requestAnimationFrame&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;rAF (animation frame)&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;));&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="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;timeout (macrotask)&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

&lt;span class="nb"&gt;Promise&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;resolve&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="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;promise (microtask)&lt;/span&gt;&lt;span class="dl"&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;finish&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Typical output:&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;begin
finish
promise (microtask)
rAF (animation frame)
timeout (macrotask)
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;p&gt;&lt;a&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  5. Real world gotchas &amp;amp; best practices
&lt;/h2&gt;

&lt;h3&gt;
  
  
  🧠 Long loops freeze your UI
&lt;/h3&gt;

&lt;p&gt;If you run:&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;for &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kd"&gt;let&lt;/span&gt; &lt;span class="nx"&gt;i&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="nx"&gt;i&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="nx"&gt;e9&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="nx"&gt;i&lt;/span&gt;&lt;span class="o"&gt;++&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;your browser tab becomes unresponsive — the event loop can’t do anything else.&lt;/p&gt;

&lt;p&gt;✅ Split heavy tasks:&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;function&lt;/span&gt; &lt;span class="nf"&gt;doWorkInChunks&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="k"&gt;for &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kd"&gt;let&lt;/span&gt; &lt;span class="nx"&gt;i&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="nx"&gt;i&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt; &lt;span class="mi"&gt;100000&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="nx"&gt;i&lt;/span&gt;&lt;span class="o"&gt;++&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="cm"&gt;/* work */&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;
  &lt;span class="k"&gt;if &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;stillWorkLeft&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="nf"&gt;setTimeout&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;doWorkInChunks&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h3&gt;
  
  
  ⚡ &lt;code&gt;setTimeout(..., 0)&lt;/code&gt; is &lt;em&gt;not&lt;/em&gt; instant
&lt;/h3&gt;

&lt;p&gt;Even with &lt;code&gt;0&lt;/code&gt;, the browser decides when to actually run it — it might be delayed.&lt;br&gt;
For “run this right after current code,” use &lt;code&gt;queueMicrotask()&lt;/code&gt; or &lt;code&gt;Promise.resolve().then()&lt;/code&gt;.&lt;/p&gt;




&lt;h3&gt;
  
  
  🔁 Microtask loops can block rendering
&lt;/h3&gt;

&lt;p&gt;If you keep queueing microtasks inside microtasks, you can stop the browser from ever updating the screen.&lt;br&gt;
Don’t overdo it — use a timer or &lt;code&gt;rAF&lt;/code&gt; to give the UI a break.&lt;/p&gt;




&lt;p&gt;&lt;a&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  6. Debugging tips &amp;amp; tools
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Chrome DevTools → Performance tab&lt;/strong&gt;: record and check long tasks.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Performance Monitor&lt;/strong&gt;: view FPS, JS memory, and CPU usage.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Lighthouse audits&lt;/strong&gt;: detect scripts that block main thread.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Try the console experiments above&lt;/strong&gt; — it’s the fastest way to really “get it”.&lt;/li&gt;
&lt;/ul&gt;




&lt;p&gt;&lt;a&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  7. Wrap-up / TL;DR
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Microtasks&lt;/strong&gt; (Promises, &lt;code&gt;queueMicrotask&lt;/code&gt;) run before macrotasks (&lt;code&gt;setTimeout&lt;/code&gt;).&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;requestAnimationFrame&lt;/strong&gt; runs before the browser’s next repaint.&lt;/li&gt;
&lt;li&gt;Don’t block the event loop — chunk your heavy work or move it to a web worker.&lt;/li&gt;
&lt;li&gt;When debugging “weird async timing,” think:
&lt;strong&gt;current code → microtasks → render → next macrotask.&lt;/strong&gt;
&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%2Fy8uoeahhr3a9zlbhnlzc.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%2Fy8uoeahhr3a9zlbhnlzc.png" alt=" " width="582" height="382"&gt;&lt;/a&gt;&lt;/p&gt;

</description>
      <category>frontend</category>
      <category>tutorial</category>
      <category>performance</category>
      <category>javascript</category>
    </item>
    <item>
      <title>Managing Multiple GitHub Accounts &amp; Branches on Windows</title>
      <dc:creator>Abhishek Mishra</dc:creator>
      <pubDate>Sat, 14 Jun 2025 18:31:47 +0000</pubDate>
      <link>https://forem.com/abhishek_mishra_2002/managing-multiple-github-accounts-branches-on-windows-27pl</link>
      <guid>https://forem.com/abhishek_mishra_2002/managing-multiple-github-accounts-branches-on-windows-27pl</guid>
      <description>&lt;p&gt;Ever feel like your Windows machine is hosting a GitHub account meetup—your personal projects in one corner, work repos in another—and you’re stuck with the wrong name tag? Fear not. In this post, I’ll show you how to juggle multiple GitHub accounts and keep your branches as organized as your desktop icons (well, almost). Expect a few laughs, zero hair-pulling, and a workflow that actually scales on Windows.&lt;/p&gt;




&lt;h3&gt;
  
  
  Table of Contents
&lt;/h3&gt;

&lt;ol&gt;
&lt;li&gt;The Windows SSH Setup: Keys &amp;amp; Pageant or OpenSSH&lt;/li&gt;
&lt;li&gt;Git Config: Who Am I Today?&lt;/li&gt;
&lt;li&gt;Branching Like a Boss&lt;/li&gt;
&lt;li&gt;Switching Contexts Without Facepalms&lt;/li&gt;
&lt;li&gt;Windows‑Specific Pro Tips &amp;amp; Pitfalls&lt;/li&gt;
&lt;li&gt;Wrap-Up: Your Workflow, Upgraded&lt;/li&gt;
&lt;/ol&gt;




&lt;p&gt;&lt;a&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  1. The Windows SSH Setup: Keys &amp;amp; Pageant or OpenSSH
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;Goal:&lt;/strong&gt; One Windows PC, two (or more) GitHub personae, zero confusion.&lt;/p&gt;

&lt;h4&gt;
  
  
  A. Generating Separate SSH Keys in Git Bash
&lt;/h4&gt;

&lt;p&gt;Open &lt;strong&gt;Git Bash&lt;/strong&gt; (or your preferred shell):&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;# Personal key&lt;/span&gt;
ssh-keygen &lt;span class="nt"&gt;-t&lt;/span&gt; ed25519 &lt;span class="nt"&gt;-C&lt;/span&gt; &lt;span class="s2"&gt;"you.personal@example.com"&lt;/span&gt; &lt;span class="nt"&gt;-f&lt;/span&gt; ~/.ssh/id_ed25519_personal

&lt;span class="c"&gt;# Work key&lt;/span&gt;
ssh-keygen &lt;span class="nt"&gt;-t&lt;/span&gt; ed25519 &lt;span class="nt"&gt;-C&lt;/span&gt; &lt;span class="s2"&gt;"you.work@company.com"&lt;/span&gt; &lt;span class="nt"&gt;-f&lt;/span&gt; ~/.ssh/id_ed25519_work
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Tip: When prompted for a passphrase, choose something strong—but memorable (so you’re not retyping it every hour).&lt;/p&gt;

&lt;h4&gt;
  
  
  B. Using Windows OpenSSH Agent
&lt;/h4&gt;

&lt;p&gt;Windows 10/11 includes an OpenSSH agent you can enable:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Search &lt;strong&gt;Services&lt;/strong&gt; in the Start menu, find &lt;strong&gt;OpenSSH Authentication Agent&lt;/strong&gt;, and set it to &lt;strong&gt;Automatic&lt;/strong&gt; then &lt;strong&gt;Start&lt;/strong&gt; it.&lt;/li&gt;
&lt;li&gt;In PowerShell or Git Bash:
&lt;/li&gt;
&lt;/ol&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;   &lt;span class="c"&gt;# Add your keys&lt;/span&gt;
   ssh-add ~/.ssh/id_ed25519_personal
   ssh-add ~/.ssh/id_ed25519_work
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h4&gt;
  
  
  C. (Alternative) Using PuTTY &amp;amp; Pageant
&lt;/h4&gt;

&lt;p&gt;If you prefer PuTTY:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Use &lt;strong&gt;PuTTYgen&lt;/strong&gt; to load &lt;code&gt;id_ed25519_personal&lt;/code&gt; and &lt;code&gt;id_ed25519_work&lt;/code&gt;, saving them as &lt;code&gt;.ppk&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;Launch &lt;strong&gt;Pageant&lt;/strong&gt;, add both &lt;code&gt;.ppk&lt;/code&gt; files.&lt;/li&gt;
&lt;li&gt;In your PuTTY/SuperPuTTY config, point to the correct key for each host.&lt;/li&gt;
&lt;/ol&gt;

&lt;h4&gt;
  
  
  D. Configure SSH Hosts
&lt;/h4&gt;

&lt;p&gt;Edit (or create) &lt;code&gt;C:\Users\&amp;lt;YourUser&amp;gt;\.ssh\config&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;# Personal GitHub
Host github-personal
  HostName github.com
  User git
  IdentityFile ~/.ssh/id_ed25519_personal

# Work GitHub
Host github-work
  HostName github.com
  User git
  IdentityFile ~/.ssh/id_ed25519_work
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;When cloning or setting remotes, use:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;git clone git@github-personal:you/my-blog.git
git clone git@github-work:company/project.git
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;p&gt;&lt;a&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  2. Git Config: Who Am I Today?
&lt;/h2&gt;

&lt;p&gt;Git needs your name &amp;amp; email per repo. Don’t let it guess.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Global Defaults&lt;/strong&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;  git config &lt;span class="nt"&gt;--global&lt;/span&gt; user.name &lt;span class="s2"&gt;"Your Name"&lt;/span&gt;
  git config &lt;span class="nt"&gt;--global&lt;/span&gt; user.email &lt;span class="s2"&gt;"you.personal@example.com"&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Per‑Repo Overrides&lt;/strong&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;  &lt;span class="nb"&gt;cd &lt;/span&gt;C:/path/to/work/project
  git config user.name &lt;span class="s2"&gt;"Your Work Alias"&lt;/span&gt;
  git config user.email &lt;span class="s2"&gt;"you.work@company.com"&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Now commits in that folder will use your work identity.&lt;/p&gt;




&lt;h2&gt;
  
  
  3. Branching Like a Boss
&lt;/h2&gt;

&lt;p&gt;Keep branches clear. Adopt a naming template:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;&amp;lt;type&amp;gt;/&amp;lt;ticket#&amp;gt;-&amp;lt;short-desc&amp;gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Types&lt;/strong&gt;: &lt;code&gt;feat&lt;/code&gt;, &lt;code&gt;fix&lt;/code&gt;, &lt;code&gt;chore&lt;/code&gt;, &lt;code&gt;docs&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Example&lt;/strong&gt;: &lt;code&gt;feat/42-add-search-box&lt;/code&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;git checkout &lt;span class="nt"&gt;-b&lt;/span&gt; feat/42-add-search-box
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Benefits:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Readability&lt;/strong&gt;: Know at a glance what each branch does.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Isolation&lt;/strong&gt;: One feature, one branch—no accidental cross-contamination.&lt;/li&gt;
&lt;/ul&gt;




&lt;p&gt;&lt;a&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  4. Switching Contexts Without Facepalms
&lt;/h2&gt;

&lt;p&gt;On Windows, context switching can be a breeze:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;PowerShell Aliases&lt;/strong&gt; (add to your &lt;code&gt;Microsoft.PowerShell_profile.ps1&lt;/code&gt;):
&lt;/li&gt;
&lt;/ol&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight powershell"&gt;&lt;code&gt;&lt;span class="w"&gt;   &lt;/span&gt;&lt;span class="n"&gt;Set-Alias&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;gpsh&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s1"&gt;'git push git@github-personal'&lt;/span&gt;&lt;span class="w"&gt;
   &lt;/span&gt;&lt;span class="n"&gt;Set-Alias&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;gwsh&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s1"&gt;'git push git@github-work'&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Windows Terminal Profiles&lt;/strong&gt;: Create separate profiles for personal vs. work, each initializing SSH agent with the correct keys.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Verify Before You Push&lt;/strong&gt;
&lt;/li&gt;
&lt;/ol&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;   git remote &lt;span class="nt"&gt;-v&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Always check your remote URL to avoid pushing to the wrong account.&lt;/p&gt;




&lt;p&gt;&lt;a&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  5. Windows‑Specific Pro Tips &amp;amp; Pitfalls
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Long Path Issues&lt;/strong&gt;: Enable long paths in Windows 10+ via Group Policy or registry—avoids “Filename too long” errors.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;CRLF vs. LF&lt;/strong&gt;: Keep &lt;code&gt;.gitattributes&lt;/code&gt; in your repos to normalize line endings.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Credential Manager&lt;/strong&gt;: If you ever switch to HTTPS, use Windows Credential Manager so you’re not typing tokens every time.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;WSL Integration&lt;/strong&gt;: If you use WSL, symlink your SSH keys (&lt;code&gt;ln -s /mnt/c/Users/You/.ssh ~/.ssh&lt;/code&gt;) so Git Bash and WSL share the same credentials.&lt;/li&gt;
&lt;/ul&gt;




&lt;p&gt;&lt;a&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  6. Wrap-Up: Your Workflow, Upgraded
&lt;/h2&gt;

&lt;p&gt;Your Windows PC can now host multiple GitHub accounts without breaking a sweat, and your branch strategy has crystal‑clear organization. No more “Which email did I set here?” panics, no more stray pushes, and no more chaotic branch names.&lt;/p&gt;

&lt;p&gt;Go forth and code with confidence—on Windows. When Git asks “Who am I?”, you’ll have the right answer every time. Happy hacking! 🎉&lt;/p&gt;

&lt;p&gt;Please Like, Comment and Share&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%2Fxcf4jw7l09u66575ikcy.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%2Fxcf4jw7l09u66575ikcy.png" alt="Image description" width="800" height="527"&gt;&lt;/a&gt;&lt;/p&gt;

</description>
      <category>webdev</category>
      <category>programming</category>
      <category>git</category>
      <category>github</category>
    </item>
    <item>
      <title>Understanding Stack vs. Heap in JavaScript: Primitives and Non-Primitives</title>
      <dc:creator>Abhishek Mishra</dc:creator>
      <pubDate>Sat, 24 May 2025 18:25:56 +0000</pubDate>
      <link>https://forem.com/abhishek_mishra_2002/understanding-stack-vs-heap-in-javascript-primitives-and-non-primitives-jh</link>
      <guid>https://forem.com/abhishek_mishra_2002/understanding-stack-vs-heap-in-javascript-primitives-and-non-primitives-jh</guid>
      <description>&lt;p&gt;JavaScript manages memory in two main areas—the &lt;strong&gt;stack&lt;/strong&gt; and the &lt;strong&gt;heap&lt;/strong&gt;—and knowing how data fits into each can help you avoid confusing bugs. In this post, we’ll cover the difference between primitive and non-primitive types, explain where they live in memory, and show practical examples you can use right away.&lt;/p&gt;




&lt;h3&gt;
  
  
  Table of Contents
&lt;/h3&gt;

&lt;ol&gt;
&lt;li&gt;Primitives on the Stack&lt;/li&gt;
&lt;li&gt;Objects and Arrays on the Heap&lt;/li&gt;
&lt;li&gt;Stack vs. Heap: Key Differences&lt;/li&gt;
&lt;li&gt;Why It Matters: Copying and Mutation&lt;/li&gt;
&lt;li&gt;Code Examples&lt;/li&gt;
&lt;li&gt;Conclusion&lt;/li&gt;
&lt;/ol&gt;




&lt;p&gt;&lt;a&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  1. Primitives on the Stack
&lt;/h2&gt;

&lt;p&gt;JavaScript’s primitive types include:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;String&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Number&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Boolean&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Null&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Undefined&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Symbol&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;BigInt&lt;/strong&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;When you declare a primitive, its value is stored directly on the &lt;strong&gt;call stack&lt;/strong&gt;, a region of memory designed for fast, fixed-size allocations. Assigning one primitive variable to another creates a &lt;strong&gt;copy&lt;/strong&gt; of the value:&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;let&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;42&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="kd"&gt;let&lt;/span&gt; &lt;span class="nx"&gt;y&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="c1"&gt;// y receives its own copy of 42&lt;/span&gt;
&lt;span class="nx"&gt;y&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;100&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="nx"&gt;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;x&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt; &lt;span class="c1"&gt;// 42&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Because each primitive has its own stack slot, changing &lt;code&gt;y&lt;/code&gt; does not affect &lt;code&gt;x&lt;/code&gt;.&lt;/p&gt;




&lt;p&gt;&lt;a&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  2. Objects and Arrays on the Heap
&lt;/h2&gt;

&lt;p&gt;Non-primitive types (objects, arrays, functions, and other complex structures) are allocated in the &lt;strong&gt;heap&lt;/strong&gt;, a larger, dynamic region of memory suited for variable-sized data. Variables that hold non-primitives store a &lt;strong&gt;reference&lt;/strong&gt; (pointer) to the heap location:&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;let&lt;/span&gt; &lt;span class="nx"&gt;objA&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Alice&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt; &lt;span class="p"&gt;};&lt;/span&gt;
&lt;span class="kd"&gt;let&lt;/span&gt; &lt;span class="nx"&gt;objB&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;objA&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;   &lt;span class="c1"&gt;// both variables reference the same object&lt;/span&gt;
&lt;span class="nx"&gt;objB&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;name&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Bob&lt;/span&gt;&lt;span class="dl"&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;objA&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;name&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt; &lt;span class="c1"&gt;// 'Bob'&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Here, &lt;code&gt;objA&lt;/code&gt; and &lt;code&gt;objB&lt;/code&gt; point to the same heap object, so mutations via one reference are visible through the other.&lt;/p&gt;




&lt;p&gt;&lt;a&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  3. Stack vs. Heap: Key Differences
&lt;/h2&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Aspect&lt;/th&gt;
&lt;th&gt;Stack&lt;/th&gt;
&lt;th&gt;Heap&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Storage for&lt;/td&gt;
&lt;td&gt;Primitives &amp;amp; references&lt;/td&gt;
&lt;td&gt;Actual object and array data&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Access speed&lt;/td&gt;
&lt;td&gt;Very fast&lt;/td&gt;
&lt;td&gt;Slower (managed by the JS engine)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Size&lt;/td&gt;
&lt;td&gt;Limited, fixed&lt;/td&gt;
&lt;td&gt;Larger, dynamic&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Allocation order&lt;/td&gt;
&lt;td&gt;Last-in, first-out (LIFO)&lt;/td&gt;
&lt;td&gt;Managed by garbage collector&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Copy behavior&lt;/td&gt;
&lt;td&gt;By value&lt;/td&gt;
&lt;td&gt;By reference&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;




&lt;p&gt;&lt;a&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  4. Why It Matters: Copying and Mutation
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Primitives&lt;/strong&gt; are passed by &lt;strong&gt;value&lt;/strong&gt;. You get independent copies, so you can’t accidentally overwrite another variable’s data.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Non-primitives&lt;/strong&gt; are passed by &lt;strong&gt;reference&lt;/strong&gt;. Multiple variables can point to the same data, so changing one will affect all references.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Understanding these rules helps you decide when to clone data to avoid unintended side effects:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="c1"&gt;// Cloning an object to avoid shared references&lt;/span&gt;
&lt;span class="kd"&gt;let&lt;/span&gt; &lt;span class="nx"&gt;original&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="na"&gt;count&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt; &lt;span class="p"&gt;};&lt;/span&gt;
&lt;span class="kd"&gt;let&lt;/span&gt; &lt;span class="nx"&gt;clone&lt;/span&gt;    &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="p"&gt;...&lt;/span&gt;&lt;span class="nx"&gt;original&lt;/span&gt; &lt;span class="p"&gt;};&lt;/span&gt; &lt;span class="c1"&gt;// shallow copy&lt;/span&gt;
&lt;span class="nx"&gt;clone&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;count&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;2&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;original&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;count&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;clone&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;count&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt; &lt;span class="c1"&gt;// 1, 2&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;p&gt;&lt;a&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  5. Code Examples
&lt;/h2&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="c1"&gt;// Primitive example: separate copies&lt;/span&gt;
&lt;span class="kd"&gt;let&lt;/span&gt; &lt;span class="nx"&gt;a&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;hello&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="kd"&gt;let&lt;/span&gt; &lt;span class="nx"&gt;b&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;a&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="nx"&gt;b&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;world&lt;/span&gt;&lt;span class="dl"&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;a&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;b&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt; &lt;span class="c1"&gt;// "hello", "world"&lt;/span&gt;

&lt;span class="c1"&gt;// Reference example: shared object&lt;/span&gt;
&lt;span class="kd"&gt;let&lt;/span&gt; &lt;span class="nx"&gt;arr1&lt;/span&gt; &lt;span class="o"&gt;=&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="kd"&gt;let&lt;/span&gt; &lt;span class="nx"&gt;arr2&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;arr1&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="nx"&gt;arr2&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;push&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;4&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;arr1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;arr2&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt; &lt;span class="c1"&gt;// [1,2,3,4], [1,2,3,4]&lt;/span&gt;

&lt;span class="c1"&gt;// Creating a true copy of an array&lt;/span&gt;
&lt;span class="kd"&gt;let&lt;/span&gt; &lt;span class="nx"&gt;arr3&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;arr1&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;slice&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt; &lt;span class="c1"&gt;// or [...arr1]&lt;/span&gt;
&lt;span class="nx"&gt;arr3&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;push&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;5&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;arr1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;arr3&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt; &lt;span class="c1"&gt;// [1,2,3,4], [1,2,3,4,5]&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;p&gt;&lt;a&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  6. Conclusion
&lt;/h2&gt;

&lt;p&gt;Knowing &lt;strong&gt;where&lt;/strong&gt; JavaScript stores your data—the &lt;strong&gt;stack&lt;/strong&gt; for primitives and references, and the &lt;strong&gt;heap&lt;/strong&gt; for objects and arrays—gives you clarity on assignment, copying, and mutation behavior. Keeping these distinctions in mind will help you write more predictable, bug-free code. Happy coding!&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%2Ftd34dzjqo4l7kin4i78p.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%2Ftd34dzjqo4l7kin4i78p.png" alt="Image description" width="800" height="533"&gt;&lt;/a&gt;&lt;/p&gt;

</description>
    </item>
    <item>
      <title>How to Stream RTSP in the Browser with Minimal Latency (Without Losing Your Mind)</title>
      <dc:creator>Abhishek Mishra</dc:creator>
      <pubDate>Sat, 26 Apr 2025 20:13:02 +0000</pubDate>
      <link>https://forem.com/abhishek_mishra_2002/how-to-stream-rtsp-in-the-browser-with-minimal-latency-without-losing-your-mind-4d5o</link>
      <guid>https://forem.com/abhishek_mishra_2002/how-to-stream-rtsp-in-the-browser-with-minimal-latency-without-losing-your-mind-4d5o</guid>
      <description>&lt;p&gt;Let’s be real: streaming RTSP in the browser is like trying to fit a square peg into a round hole. RTSP streams are like the cool kids at the party that browsers just don’t invite. You can either use HLS, which works but adds a bit of a delay (15–60 seconds, anyone?), or you can get fancy and use WebRTC, which, spoiler alert, is &lt;strong&gt;way&lt;/strong&gt; better for real-time performance. &lt;/p&gt;

&lt;p&gt;In this post, I’m going to walk you through how we went from sub‑1ms latency in our local prototype to 60-second delays in production and back again (with WebRTC, of course). Plus, how you can avoid the pain I went through, so you don’t end up pulling your hair out in frustration.&lt;/p&gt;




&lt;h3&gt;
  
  
  Table of Contents
&lt;/h3&gt;

&lt;ol&gt;
&lt;li&gt;Why RTSP Doesn't Just Work in the Browser&lt;/li&gt;
&lt;li&gt;My First Attempt: RTSP → HLS with FFmpeg &amp;amp; hls.js&lt;/li&gt;
&lt;li&gt;The Latency Nightmare: AI + HLS = Bad News&lt;/li&gt;
&lt;li&gt;Why HLS Will Never Be Your Real-Time Friend&lt;/li&gt;
&lt;li&gt;Enter WebRTC &amp;amp; Janus Gateway: Our Savior&lt;/li&gt;
&lt;li&gt;How I Made It Work (and Stayed Sane)&lt;/li&gt;
&lt;li&gt;What I Learned (aka My Cautionary Tale)&lt;/li&gt;
&lt;li&gt;Conclusion: Don't Be Like Me, Do It Right From the Start&lt;/li&gt;
&lt;/ol&gt;




&lt;p&gt;&lt;a&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  1. Why RTSP Doesn’t Just Work in the Browser
&lt;/h3&gt;

&lt;p&gt;Okay, so &lt;strong&gt;RTSP (Real-Time Streaming Protocol)&lt;/strong&gt; is the king of live video streaming. It’s what most cameras use, and it works great… until you try to get it into the browser. Browsers are all like, "Nah, I don't do RTSP." They prefer &lt;strong&gt;HLS (HTTP Live Streaming)&lt;/strong&gt; because it’s super chill and easy to play. &lt;/p&gt;

&lt;p&gt;But here’s the catch: HLS has latency—lots of it. Like, sometimes more than &lt;strong&gt;30 seconds&lt;/strong&gt;, and that’s not ideal when you're trying to build something that’s, you know, &lt;em&gt;real-time&lt;/em&gt;. Think surveillance, AI detection, or anything where delays mean missed action (or worse—awkward silences in a live event stream).&lt;/p&gt;




&lt;p&gt;&lt;a&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  2. My First Attempt: RTSP → HLS with FFmpeg &amp;amp; hls.js
&lt;/h3&gt;

&lt;p&gt;So, I decided to hack together a quick prototype. I was like, "How hard can it be to just convert RTSP to HLS and get it working in Angular?" Spoiler: It was easier than I thought, but it still felt like I was solving a puzzle while blindfolded.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Step 1: Convert RTSP to HLS with FFmpeg&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;First, I needed to take the RTSP stream and convert it to HLS, because that’s what browsers like. Here’s the FFmpeg command I used:&lt;/p&gt;

&lt;p&gt;&lt;code&gt;bash&lt;br&gt;
ffmpeg -i rtsp://camera/stream \&lt;br&gt;
  -c:v copy -c:a aac \&lt;br&gt;
  -f hls \&lt;br&gt;
  -hls_time 1 \&lt;br&gt;
  -hls_list_size 3 \&lt;br&gt;
  -hls_flags delete_segments \&lt;br&gt;
  public/stream.m3u8&lt;br&gt;
&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;What does it do? It takes the RTSP stream and breaks it down into smaller HLS chunks—1 second each. It’s like taking a pizza and slicing it into tiny, snackable pieces. The browser loves that.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Step 2: Play HLS with hls.js in Angular&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Then, I used &lt;strong&gt;hls.js&lt;/strong&gt; to play the stream in Angular. A bit of code, and boom—it worked. Here’s the magic:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&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;Component&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;AfterViewInit&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;ViewChild&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;ElementRef&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;@angular/core&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="nx"&gt;Hls&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;hls.js&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="p"&gt;@&lt;/span&gt;&lt;span class="nd"&gt;Component&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;
  &lt;span class="na"&gt;selector&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;app-video-player&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="na"&gt;template&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;`&amp;lt;video #video controls autoplay&amp;gt;&amp;lt;/video&amp;gt;`&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;span class="p"&gt;})&lt;/span&gt;
&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;VideoPlayerComponent&lt;/span&gt; &lt;span class="k"&gt;implements&lt;/span&gt; &lt;span class="nx"&gt;AfterViewInit&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="p"&gt;@&lt;/span&gt;&lt;span class="nd"&gt;ViewChild&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;video&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="nx"&gt;videoRef&lt;/span&gt;&lt;span class="o"&gt;!&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;ElementRef&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;HTMLVideoElement&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="k"&gt;private&lt;/span&gt; &lt;span class="nx"&gt;hls&lt;/span&gt;&lt;span class="o"&gt;!&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;Hls&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

  &lt;span class="nf"&gt;ngAfterViewInit&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;video&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;videoRef&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;nativeElement&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;src&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;/assets/stream.m3u8&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

    &lt;span class="k"&gt;if &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;Hls&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;isSupported&lt;/span&gt;&lt;span class="p"&gt;())&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;hls&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;Hls&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
      &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;hls&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;loadSource&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;src&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
      &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;hls&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;attachMedia&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;video&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
      &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;hls&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;on&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;Hls&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;Events&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;MANIFEST_PARSED&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;video&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;play&lt;/span&gt;&lt;span class="p"&gt;());&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;else&lt;/span&gt; &lt;span class="k"&gt;if &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;video&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;canPlayType&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;application/vnd.apple.mpegurl&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="nx"&gt;video&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;src&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;src&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
      &lt;span class="nx"&gt;video&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;addEventListener&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;loadedmetadata&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nx"&gt;video&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;play&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="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Local Results:&lt;/strong&gt; I was feeling pretty proud of myself. The latency was like &lt;strong&gt;1 ms&lt;/strong&gt;. Real-time! I could almost hear the camera’s lens spinning. Everything was smooth.&lt;/p&gt;




&lt;p&gt;&lt;a&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  3. The Latency Nightmare: AI + HLS = Bad News
&lt;/h3&gt;

&lt;p&gt;Then, we decided to integrate it into the actual application. You know, the one where we run &lt;strong&gt;AI inference&lt;/strong&gt; on the frames coming from the RTSP stream. This is where the fun begins—or should I say, the &lt;strong&gt;nightmare&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;Everything worked fine locally. The stream was fast, I was happy, life was good. But once I threw it into production, the latency went through the roof:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;15–25 seconds of delay&lt;/strong&gt;—seriously.
&lt;/li&gt;
&lt;li&gt;On slower connections, it even &lt;strong&gt;spiked to 1 minute&lt;/strong&gt;. &lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Imagine trying to run real-time object detection with that kind of delay. It was like trying to stream a live event while watching it through a broken telescope.&lt;/p&gt;




&lt;p&gt;&lt;a&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  4. Why HLS Will Never Be Your Real-Time Friend
&lt;/h3&gt;

&lt;p&gt;HLS was great for a prototype, but &lt;strong&gt;it wasn’t real-time&lt;/strong&gt;. Why? Let me break it down:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Segmented by Design&lt;/strong&gt;: HLS takes your video, chops it into small segments, and sends them one at a time. That’s like waiting for a new episode of your favorite series, but only getting one minute at a time. &lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Client-Pull&lt;/strong&gt;: The browser has to keep checking for new segments. It’s like sending someone to the store for milk and hoping they come back before you die of thirst.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Buffering&lt;/strong&gt;: To avoid choppy video, browsers buffer multiple segments. Which means &lt;strong&gt;more latency&lt;/strong&gt;. Fun, right?&lt;/li&gt;
&lt;/ul&gt;




&lt;p&gt;&lt;a&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  5. Enter WebRTC &amp;amp; Janus Gateway: Our Savior
&lt;/h3&gt;

&lt;p&gt;I was done. I needed a solution that could handle &lt;strong&gt;real-time streaming&lt;/strong&gt;. Enter &lt;strong&gt;WebRTC&lt;/strong&gt; and &lt;strong&gt;Janus Gateway&lt;/strong&gt;—the dynamic duo that saved the day.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;WebRTC&lt;/strong&gt; is built for low-latency, real-time communication, and &lt;strong&gt;Janus Gateway&lt;/strong&gt; is a powerful media server that supports WebRTC. It’s like the Batman and Robin of streaming—able to handle &lt;strong&gt;RTSP to WebRTC conversion&lt;/strong&gt; with minimal delay. And the best part? It’s all &lt;strong&gt;peer-to-peer&lt;/strong&gt;, which means no buffering, no waiting.&lt;/p&gt;




&lt;p&gt;&lt;a&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  6. How I Made It Work (and Stayed Sane)
&lt;/h3&gt;

&lt;p&gt;Here’s how I switched from HLS to WebRTC with Janus:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Install Janus Gateway&lt;/strong&gt;&lt;br&gt;&lt;br&gt;
Janus is like the Swiss Army knife of WebRTC servers, so I installed it and configured the &lt;strong&gt;streaming plugin&lt;/strong&gt; for RTSP.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Configure RTSP Streaming&lt;/strong&gt;&lt;br&gt;&lt;br&gt;
Janus can take an RTSP stream and serve it directly as a WebRTC stream. I added the camera’s RTSP URL in the config file and boom, ready to go.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;WebRTC Player in Angular&lt;/strong&gt;&lt;br&gt;&lt;br&gt;
I used the Janus JS API to connect to the Janus server and get the stream playing. It was as simple as:&lt;br&gt;
&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="c1"&gt;// WebRTC video player component&lt;/span&gt;
&lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;janus&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;attach&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;
  &lt;span class="na"&gt;plugin&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;janus.plugin.streaming&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="na"&gt;success&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;pluginHandle&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;streamPlugin&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;pluginHandle&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;streamPlugin&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;send&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt; &lt;span class="na"&gt;message&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="na"&gt;request&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;watch&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="na"&gt;id&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="p"&gt;});&lt;/span&gt;
  &lt;span class="p"&gt;},&lt;/span&gt;
  &lt;span class="na"&gt;onremotestream&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;remoteStream&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;videoRef&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;nativeElement&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;srcObject&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;remoteStream&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="p"&gt;},&lt;/span&gt;
&lt;span class="p"&gt;});&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Now the latency was under &lt;strong&gt;500 ms&lt;/strong&gt;, and my AI model could process frames &lt;strong&gt;in real-time&lt;/strong&gt;.&lt;/p&gt;




&lt;p&gt;&lt;a&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  7. What I Learned (aka My Cautionary Tale)
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Latency is real&lt;/strong&gt;: HLS is fine for static streaming, but if you're doing AI inference, it’s &lt;strong&gt;too slow&lt;/strong&gt;.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;WebRTC is your friend&lt;/strong&gt;: If you need true real-time performance, &lt;strong&gt;WebRTC&lt;/strong&gt; + &lt;strong&gt;Janus&lt;/strong&gt; is the way to go.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;WebRTC ≠ Easy&lt;/strong&gt;: It’s way more complex than HLS, but &lt;strong&gt;so worth it&lt;/strong&gt; for real-time apps.&lt;/li&gt;
&lt;/ul&gt;




&lt;p&gt;&lt;a&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  8. Conclusion: Don’t Be Like Me, Do It Right From the Start
&lt;/h3&gt;

&lt;p&gt;If you’re trying to stream RTSP with &lt;strong&gt;minimal latency&lt;/strong&gt; for real-time processing, &lt;strong&gt;HLS&lt;/strong&gt; just won’t cut it. Skip the frustration, and go straight to &lt;strong&gt;WebRTC&lt;/strong&gt;. It’ll save you from tearing your hair out (and trust me, I’ve been there).&lt;/p&gt;

&lt;p&gt;So, save yourself the headache, grab a Janus server, and start streaming like a pro. You’ll thank me later. 😉&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%2Fejjkqviyg6oqi8fu33t2.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%2Fejjkqviyg6oqi8fu33t2.png" alt="Image description" width="800" height="518"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Happy streaming, and may your latencies always be low and your frame rates high!&lt;/em&gt;&lt;/p&gt;

</description>
    </item>
    <item>
      <title>The Dev Revolution: How AI and Automation Are Changing the Game</title>
      <dc:creator>Abhishek Mishra</dc:creator>
      <pubDate>Fri, 04 Apr 2025 19:14:55 +0000</pubDate>
      <link>https://forem.com/abhishek_mishra_2002/the-dev-revolution-how-ai-and-automation-are-changing-the-game-5955</link>
      <guid>https://forem.com/abhishek_mishra_2002/the-dev-revolution-how-ai-and-automation-are-changing-the-game-5955</guid>
      <description>&lt;p&gt;In the ever-evolving world of development, one thing is certain—change is constant. But hey, if you’re like me, you might have secretly wished for a magic wand (or a really clever script) to fix bugs and automate the mundane. &lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Spoiler alert&lt;br&gt;
: AI and automation are pretty close to that magic wand, and they’re here to shake things up in the best possible way.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;&lt;strong&gt;A New Era for Developers&lt;/strong&gt;&lt;br&gt;
Remember the days when you’d spend hours wrestling with a bug that felt like it was hiding under your code like a teenager avoiding chores? Well, those days are slowly fading away. With AI-powered tools like code assistants, automated testing frameworks, and smart IDE plugins, we're stepping into an era where our keyboards might as well be magic wands—minus the cape (though a cape might not be a bad idea for Monday mornings).&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Why This Matters&lt;/strong&gt;&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;&lt;p&gt;Boosting Productivity:&lt;br&gt;
AI tools are not just about making our lives easier—they’re about turning our “oh no” moments into “aha!” breakthroughs. Imagine having a sidekick that points out your mistakes before you even realize you made them. It’s like having a friend who always texts you “I told you so,” but in the most supportive way possible.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Fostering Innovation:&lt;br&gt;
When routine tasks are automated, we’re free to explore, experiment, and yes, even fail spectacularly. Let’s be honest: our most memorable “aha!” moments often come after a few epic fails. Now, thanks to AI, we can focus on the creative side of coding, while our digital buddies handle the grunt work.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Learning and Growth:&lt;br&gt;
Embracing these new technologies means we’re on a never-ending learning curve—like trying to assemble IKEA furniture without instructions, but with a lot less swearing (hopefully). Every new tool opens up opportunities to level up, and yes, sometimes you might even laugh at how much you once struggled.&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;&lt;strong&gt;Embracing the Change&lt;/strong&gt;&lt;br&gt;
Adapting to a rapidly shifting landscape isn’t always smooth sailing. There are moments when your code just won’t cooperate—kind of like that stubborn jar of pickles you can never open. But the trick is to stay curious, experiment boldly, and remember that a little humor can go a long way in diffusing frustration.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;Stay Updated:&lt;br&gt;
Follow tech blogs, join developer communities, and attend webinars. Consider it the “developer news feed” that keeps you from becoming the human equivalent of outdated floppy disks.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Experiment Boldly:&lt;br&gt;
Dedicate time each week to try out new AI tools or emerging frameworks. The more you experiment, the more you might laugh at your past mistakes—and the better you’ll understand how to leverage these tools to your advantage.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Network and Collaborate:&lt;br&gt;
Share your experiences with peers. Whether it’s a coding triumph or a hilarious debugging disaster, collaboration turns individual struggles into collective victories (and funny stories).&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Looking Ahead&lt;/strong&gt;&lt;br&gt;
The fusion of AI and development isn’t just another trend—it’s a revolution. As we navigate this brave new world, one thing remains clear: the future of coding is dynamic, interconnected, and occasionally absurdly funny. Whether you’re a seasoned developer or a newbie still learning which end of the keyboard is which, there’s never been a more exciting (or entertaining) time to be in the game.&lt;/p&gt;

&lt;p&gt;So, let’s embrace the challenge, harness the power of AI, and laugh a little along the way. After all, in the world of code, even our errors can be a source of great comedy. What’s your funniest coding moment? Share your stories and let’s start a conversation that’s as engaging as it is enlightening!&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%2F17xo31xwh76ybv5v4c90.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%2F17xo31xwh76ybv5v4c90.png" alt="Image description" width="800" height="533"&gt;&lt;/a&gt;&lt;/p&gt;

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