Loading...
Loading...
Find and fix bugs faster. DevTools, breakpoints, and systematic strategies.
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 Debugging Techniques in JavaScript — covering Console Methods, Breakpoints, DevTools, Strategies 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 debugging techniques 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.
Beyond console.log — powerful inspection tools.
// Basics: console.log("value:", x); // general output console.error("Failed!"); // red, shows stack trace console.warn("Deprecated"); // yellow warning console.info("FYI"); // informational // Structured data: console.table([ { name: "Alice", age: 25 }, { name: "Bob", age: 30 }, ]); // beautiful table view! console.dir(document.body, { depth: 2 }); // object tree console.group("Network"); console.log("Request sent"); console.log("Response received"); console.groupEnd(); // Timing: console.time("fetch"); await fetch("/api/data"); console.timeEnd("fetch"); // "fetch: 142ms" // Counting: function process(item) { console.count("processed"); // "processed: 1", "processed: 2"... } // Conditional: console.assert(x > 0, "x must be positive!", { x }); // Only logs if assertion FAILS // Stack trace: console.trace("How did we get here?"); // prints call stack
Pause execution and inspect state at any point.
// The 'debugger' statement — programmatic breakpoint: function processData(data) { debugger; // execution pauses here when DevTools is open const result = transform(data); return result; } // Types of breakpoints in DevTools: // 1. Line breakpoints — click the line number // 2. Conditional — right-click line → "Add conditional" // Only pause when: items.length > 100 // 3. DOM breakpoints — pause when DOM changes // Right-click element → "Break on" → subtree/attribute/removal // 4. XHR/Fetch breakpoints — pause on network requests // Sources → XHR Breakpoints → add URL pattern // 5. Event listener breakpoints // Sources → Event Listener Breakpoints → check "click" // 6. Exception breakpoints // Sources → ⏸ icon → "Pause on caught exceptions"
// When paused at a breakpoint, you can: // • Hover variables to see their value // • Use the Scope panel to see all variables // • Use the Watch panel for expressions // • Use the Console to evaluate code in current scope // Stepping controls: // F8 — Resume (continue to next breakpoint) // F10 — Step Over (execute line, don't enter functions) // F11 — Step Into (enter the function call) // Shift+F11 — Step Out (finish current function) // Pro tip: Logpoints (no code changes needed): // Right-click line → "Add logpoint" // Enter: "x is:", x, "items:", items.length // It logs without pausing — like console.log but no code change!
Chrome DevTools panels for debugging JavaScript.
// Sources Panel — the main debugger: // • See all loaded files // • Set breakpoints // • Step through code // • Edit files (Workspaces) // • Snippets for quick scripts // Network Panel — inspect requests: // • See all HTTP requests/responses // • Check timing (DNS, connect, TTFB) // • Filter by type (XHR, JS, CSS) // • Throttle speed (Slow 3G, Offline) // • Block requests to test failures // Performance Panel — find bottlenecks: // • Record page activity // • See flame chart (what took time) // • Identify long tasks (>50ms) // • Find layout thrashing // • Measure FPS and jank
Sources for code debugging, Network for HTTP inspection, Performance for bottleneck analysis.
Systematic approaches to finding bugs.
// 1. Reproduce Reliably: // Can you make the bug happen consistently? // What are the exact steps? // Does it happen in all browsers? All screen sizes? // 2. Isolate the Problem (Binary Search): // Comment out half the code — does bug persist? // If yes → bug is in the remaining half // If no → bug was in the commented half // Repeat until you find the exact line // 3. Check Assumptions: console.log(typeof value); // is it the type you expect? console.log(JSON.stringify(obj)); // is the shape correct? console.log(arr.length); // is it populated? // 4. Rubber Duck Debugging: // Explain the code LINE BY LINE to someone (or a rubber duck) // "This line should give me an array of users..." // "Wait — it's returning a Promise, not the actual array!" // 5. Git Bisect (find which commit broke it): // git bisect start // git bisect bad (current is broken) // git bisect good abc123 (this commit was fine) // Git binary-searches commits for you
Frequent JavaScript mistakes and how to spot them.
// 1. Off-by-one errors: for (let i = 0; i <= arr.length; i++) // ❌ <= should be < arr.slice(0, 3); // returns indices 0,1,2 (not 3!) // 2. Async timing: let data; fetch("/api").then(res => { data = res.json(); }); console.log(data); // undefined! (fetch hasn't resolved) // 3. Reference vs value: const original = [1, 2, 3]; const copy = original; // same reference! copy.push(4); original.length; // 4 (oops!) // 4. this context: const obj = { name: "Alice", greet: () => this.name, // ❌ arrow function has no 'this' }; // 5. Equality gotchas: 0 == ""; // true (type coercion) null == undefined; // true NaN === NaN; // false! // 6. Closure in loops: for (var i = 0; i < 3; i++) { setTimeout(() => console.log(i)); // 3, 3, 3 (use let!) } // 7. Missing await: async function load() { const data = fetch("/api"); // ❌ missing await → Promise object! return data.json(); // ❌ data.json is not a function }
Common questions about debugging techniques.