DEV Community

mosabnazli
mosabnazli

Posted on Edited on AI-assisted

I went beyond the usual JavaScript Event Loop diagrams and inspected a real Chrome Renderer process on my Mac.

I had read about the JavaScript Event Loop many times, but I wanted to see what was actually happening underneath the diagrams.

So I opened a simple HTML page in Chrome on my Mac and started inspecting the Renderer process responsible for running it.

Finding the Renderer Process

I started by looking at Chrome's process tree.

At the time of inspection, Chrome had a Browser process, four Renderer processes, a GPU process, and several Utility processes.

Chrome Browser process tree showing Renderer, GPU, and Utility processes

Chrome's process architecture on macOS, showing multiple Renderer, GPU, and Utility processes.

What looks like a single browser window is actually supported by multiple operating-system processes.

Looking Inside a Renderer

I then inspected one Renderer process using macOS tools.

The native sample showed 16 threads, including:

  • Main thread
  • Compositor
  • Chrome I/O thread
  • HangWatcher
  • Background workers

Native sample showing 16 threads inside a Chrome Renderer process

A native sample showing the threads inside a Chrome Renderer process.

One distinction became clearer: the JavaScript Event Loop isn't a separate operating-system process or an independently named thread.

Ordinary page JavaScript runs on the Renderer's main thread, alongside the event-loop-driven processing of tasks.

Blocking JavaScript for 10 Seconds

Next, I used a button that triggered a simple CPU-intensive loop:

function startWork() {
  const end = Date.now() + 10000;

  while (Date.now() < end) {}

  console.log("CPU work finished");
}
Enter fullscreen mode Exit fullscreen mode

I recorded the interaction using Chrome DevTools Performance.

Chrome DevTools Performance call tree showing a 10-second JavaScript click task

Chrome DevTools showing a click task lasting approximately 10,000 ms, with most of the execution time inside startWork().

The trace showed:

  • A click task lasting approximately 10,000 ms.
  • Around 9,810 ms attributed to startWork() in total time.
  • The page becoming unresponsive during execution.

The Renderer process was still alive, but its main thread was busy executing JavaScript instead of returning to handle other work.

What I Took Away

A running process doesn't necessarily mean a responsive application.

Looking at the same behavior from different layers helped me connect the pieces:

  • The operating system showed the Renderer process and its threads.
  • Native sampling exposed the thread structure.
  • Chrome DevTools showed the long-running JavaScript task.

This also matters in browser automation.

When a browser appears stuck during a test, the problem isn't necessarily a selector or an insufficient timeout. The application's main thread may be busy, and investigating that can be more useful than simply increasing the wait.

The JavaScript Event Loop made more sense to me once I started inspecting a real browser process instead of looking only at diagrams.

Top comments (0)