jargon

Frontend & browser·topic 3 of 13

JavaScript in the browser

One thread does the layout, the paint and your code, and it can only do one of them at a time. These are the words for what that thread is doing, in what order, and why the interface stopped responding while it did it.

Read in order · tick what you already know

  1. 01

    your loop over ten thousand rows froze the whole tab, including the scroll and the spinner.

    Main thread

  2. 02

    the error trace reads bottom to top and shows you every function that was still waiting when it threw.

    Call stack

  3. 03

    your `setTimeout(fn, 0)` did not run immediately, it ran after the browser got a chance to paint.

    Task

  4. 04

    the promise callback ran before the timeout you scheduled first, and before the browser painted anything.

    Microtask

  5. 05

    you moved the animation out of `setInterval` and it finally stopped stuttering at odd moments.

    requestAnimationFrame

  6. 06

    you deferred the analytics work until the browser said it had nothing better to do.

    requestIdleCallback

  7. 07

    you moved the parsing off to another thread and the interface kept responding while it ran.

    Web worker

  8. 08

    you clicked the button and the click handler on its container ran too, without you binding anything there.

    Event bubbling

  9. 09

    you passed `{ capture: true }` and your handler ran before the one on the element that was actually clicked.

    Event capturing

  10. 10

    you put one click handler on the list and read `event.target` to work out which row was clicked.

    Event delegation

  11. 11

    you stopped the form from navigating away but the parent's handler still ran.

    preventDefault

  12. 12

    you stopped the click from reaching the document and three unrelated features quietly broke.

    stopPropagation

  13. 13

    the console warned that your scroll handler blocked scrolling, so you marked it passive.

    Passive event listener

  14. 14

    you wait until the user stops typing for three hundred milliseconds and only then send the request.

    Debounce

  15. 15

    you let the scroll handler run at most once every hundred milliseconds no matter how fast the events arrive.

    Throttle

  16. 16

    the callback still had the variable from the function that created it, long after that function returned.

    Closure

  17. 17

    the interval you set up on mount kept logging the count as zero no matter how many times you clicked.

    Stale closure

  18. 18

    you passed the method as a callback and it lost the object it belonged to.

    this binding

  19. 19

    you called the function on line three and it worked, even though it is declared on line forty.

    Hoisting

  20. 20

    you got 'cannot access before initialization' on a `const` that is clearly declared right there in the file.

    Temporal dead zone

  21. 21

    the object did not have the method but calling it worked anyway, because something further up did.

    Prototype chain

  22. 22

    the object had exactly the same contents as last render and the component re-rendered anyway.

    Referential equality

  23. 23

    the comparison checked each top-level property and still said unchanged, because the nested object was mutated in place.

    Shallow equality

  24. 24

    you compared the two API responses field by field, all the way down, to decide whether to update.

    Deep equality

  25. 25

    you posted the object to a worker and got a real deep copy on the other side, but the functions were gone.

    Structured clone

  26. 26

    memory in the tab keeps climbing across navigations and never comes back down.

    Garbage collection

  27. 27

    you removed the element from the page but a variable still points at it, so it never gets collected.

    Detached DOM node

  28. 28

    the component unmounted mid-request, so you cancelled the fetch instead of letting it resolve into nothing.

    AbortController

  29. 29

    the request failed and nothing happened at all — no error boundary, no message, just a line in the console.

    Unhandled rejection