Loading...
Loading...
Browser superpowers that JavaScript can access. Timers, network, DOM, and more.
Module 10 · Browser Internals & Best Practices
Production JavaScript requires more than syntax. The event loop, rendering pipeline, bundlers, debugging techniques, performance optimization, design patterns, testing, and security practices separate hobby scripts from professional software.
Learn Web APIs in JavaScript — covering What Are Web APIs, Timer APIs, Observer APIs, Communication APIs with interactive visual examples and step-by-step explanations.
Writing JavaScript that works in a tutorial is different from writing JavaScript that ships to production. The event loop explains why setTimeout(0) does not run immediately. Performance profiling finds bottlenecks before users do.
This module covers the internals and best practices that separate hobby scripts from professional software: debugging, bundlers, design patterns, testing strategies, and security fundamentals every developer should know.
Understanding web apis is essential for every JavaScript developer. It shows up in frontend UI code, backend APIs, and framework internals — and getting it wrong leads to bugs that are hard to trace. This chapter builds intuition with visuals so the behavior sticks.
APIs provided by the browser, not the JavaScript language.
// JavaScript (the language) has: // - Variables, functions, objects, arrays // - Promises, async/await // - Math, Date, JSON, RegExp // Web APIs (provided by the browser) have: // - DOM manipulation (document.querySelector) // - Timers (setTimeout, setInterval) // - Network (fetch, XMLHttpRequest) // - Storage (localStorage, sessionStorage) // - Geolocation, Canvas, Audio, WebSocket... // These are NOT part of JavaScript itself! // They're C++ code in the browser, exposed to JS. // That's why they work differently in different environments: // - Browser: has DOM, window, document // - Node.js: has fs, http, process (no DOM!) // - Deno: has Deno.readFile (different APIs) typeof window; // "object" in browser, "undefined" in Node typeof document; // "object" in browser, "undefined" in Node
How they work with the event loop:
1. JS calls a Web API (e.g., setTimeout)
2. Browser handles it on a separate thread
3. When done, browser puts callback in the task queue
4. Event loop picks it up when the stack is empty
Schedule code to run later.
// setTimeout — run once after delay: const id = setTimeout(() => { console.log("After 1 second"); }, 1000); clearTimeout(id); // cancel before it fires // setInterval — run repeatedly: let count = 0; const intervalId = setInterval(() => { count++; console.log(`Tick ${count}`); if (count >= 5) clearInterval(intervalId); }, 1000); // requestAnimationFrame — sync with display refresh: function animate(timestamp) { // Update animation state element.style.transform = `translateX(${x}px)`; // Schedule next frame (~60fps) requestAnimationFrame(animate); } requestAnimationFrame(animate); // requestIdleCallback — run when browser is idle: requestIdleCallback((deadline) => { while (deadline.timeRemaining() > 0) { doLowPriorityWork(); } });
Watch for changes without polling.
// IntersectionObserver — watch element visibility: const observer = new IntersectionObserver((entries) => { entries.forEach(entry => { if (entry.isIntersecting) { entry.target.classList.add("visible"); // Lazy load images, trigger animations, etc. } }); }, { threshold: 0.5 }); // 50% visible observer.observe(document.querySelector(".card")); // MutationObserver — watch DOM changes: const mutation = new MutationObserver((mutations) => { mutations.forEach(m => { console.log("DOM changed:", m.type); }); }); mutation.observe(element, { childList: true, // watch child additions/removals attributes: true, // watch attribute changes subtree: true // watch all descendants });
Observers are event-driven — much more efficient than polling with setInterval. The browser notifies you when something changes.
Send and receive data.
// fetch — HTTP requests: const response = await fetch("/api/users"); const data = await response.json(); // WebSocket — real-time bidirectional: const ws = new WebSocket("wss://chat.example.com"); ws.onopen = () => ws.send("Hello!"); ws.onmessage = (event) => console.log(event.data); ws.onclose = () => console.log("Disconnected"); // Server-Sent Events — one-way streaming: const source = new EventSource("/api/stream"); source.onmessage = (event) => { console.log("New data:", event.data); }; // BroadcastChannel — communicate between tabs: const channel = new BroadcastChannel("app"); channel.postMessage({ type: "logout" }); // send to all tabs channel.onmessage = (event) => { if (event.data.type === "logout") redirectToLogin(); }; // postMessage — communicate with iframes/workers: iframe.contentWindow.postMessage(data, "https://trusted.com"); window.addEventListener("message", (event) => { if (event.origin !== "https://trusted.com") return; // security! handleMessage(event.data); });
Other commonly used browser APIs.
// Clipboard API: await navigator.clipboard.writeText("Copied!"); const text = await navigator.clipboard.readText(); // Geolocation: navigator.geolocation.getCurrentPosition( (pos) => console.log(pos.coords.latitude, pos.coords.longitude), (err) => console.error(err.message) ); // URL API: const url = new URL("https://example.com/path?q=hello&page=2"); url.searchParams.get("q"); // "hello" url.searchParams.set("page", "3"); url.pathname; // "/path" // AbortController — cancel async operations: const controller = new AbortController(); fetch("/api", { signal: controller.signal }); controller.abort(); // cancel the fetch! // structuredClone — deep copy: const deep = structuredClone({ nested: { data: [1, 2, 3] } }); // crypto — random values and hashing: const uuid = crypto.randomUUID(); const array = crypto.getRandomValues(new Uint8Array(16));
Common questions about web apis.