Browser Developer Tools: The Swiss Army Knife of Frontend Debugging â
Overview of Developer Tools â
Browser Developer Tools (DevTools) are a set of web development and debugging tools built into modern browsers. They provide frontend developers with powerful page analysis, debugging, and optimization capabilities. Mastering developer tools is an essential skill for every frontend developer.
Importance of Developer Tools â
Real-time Debugging: View and modify page effects in real-time without recompiling or deploying.
Problem Diagnosis: Quickly locate CSS style issues, JavaScript errors, network request failures, etc.
Performance Optimization: Analyze page load time, rendering performance, memory usage, etc., to find performance bottlenecks.
Compatibility Testing: Test page performance in different browser environments to ensure cross-browser compatibility.
Learning Tool: Analyze the implementation of excellent websites and learn best practices.
Mainstream Browser Developer Tools â
Chrome DevTools: The most comprehensive and widely used developer tool with rich debugging and analysis features.
Firefox Developer Tools: A powerful development tool developed by Mozilla, which has unique features in some aspects compared to Chrome.
Safari Web Inspector: Development tool for macOS and iOS devices, suitable for Apple ecosystem development.
Edge Developer Tools: Based on the Chromium kernel, with functions basically consistent with Chrome.
Mobile Debugging Tools: Such as Chrome remote debugging, Firefox mobile debugging, etc.
Opening and Basic Operations â
Opening Developer Tools â
Multiple Ways to Open:
- Shortcut:
F12orCtrl+Shift+I(Windows/Linux),Cmd+Opt+I(macOS) - Right-click Menu: Right-click anywhere on the page -> "Inspect" or "Inspect Element"
- Menu Bar: Browser Menu -> More Tools -> Developer Tools
Developer Tools Panel Layout:
- Top: Tab Bar (Elements, Console, Sources, etc.)
- Left: DOM Tree or File Explorer
- Middle: Main Work Area
- Right: Property Panel or Debugging Information
- Bottom: Console or Drawer Panel
Basic Operation Tips â
Panel Adjustment:
- Drag to adjust panel size and position
- Click panel tabs to switch different functions
- Use shortcuts to quickly switch:
Ctrl+1/2/3/4, etc.
Theme Settings:
// Set theme in console
// 1 for light theme, 2 for dark theme
DevTools.setTheme(1); // Light theme
DevTools.setTheme(2); // Dark themeCommon Shortcuts:
Ctrl+Shift+C: Element selection modeCtrl+Shift+J: Open Console directlyCtrl+R: Refresh pageCtrl+F5: Force refresh (ignore cache)Esc: Open/Close Drawer Panel
Elements Panel Detailed â
The Elements panel is used to inspect and debug the HTML structure and CSS styles of the page, and is one of the most commonly used panels.
DOM Tree Inspection â
Element Selection:
<!-- Example HTML Structure -->
<div class="container">
<header class="header">
<h1>Page Title</h1>
<nav class="navigation">
<ul>
<li><a href="#home">Home</a></li>
<li><a href="#about">About</a></li>
<li><a href="#contact">Contact</a></li>
</ul>
</nav>
</header>
<main class="main-content">
<article class="post">
<h2>Article Title</h2>
<p class="content">Article content...</p>
</article>
</main>
</div>In the Elements panel, you can:
- Click an element to view the corresponding DOM node
- Use arrow keys to navigate the DOM tree
- Use search function (
Ctrl+F) to quickly locate elements - View the complete HTML structure of the element
Real-time HTML Editing:
// Double-click element in Elements panel to edit
// Add new attribute
<div class="container" data-role="main">...</div>
// Modify element content
<h1>New Page Title</h1>CSS Style Inspection and Editing â
Style Panel Functions:
- View all CSS rules of the element
- Edit existing styles
- Add new CSS rules
- Toggle CSS class application state
- View computed final styles
Style Editing Example:
/* Real-time editing in Style panel */
.container {
/* Background color can be modified in real-time after clicking */
background-color: #f0f0f0;
padding: 20px;
margin: 0 auto;
max-width: 1200px;
}
/* Can add new style rules */
.main-content {
line-height: 1.6;
color: #333;
}View Computed CSS Values: The Computed tab displays the final style values applied to the element, including inherited styles and browser default styles.
Box Model Visualization:
/* Box model shows dimensions of each part */
.box {
width: 200px; /* Content width */
padding: 20px; /* Padding */
border: 2px solid #ccc; /* Border */
margin: 10px; /* Margin */
}Event Listener Inspection â
In the Event Listeners tab, you can view the event listeners bound to the element:
// View these bound events
document.querySelector(".button").addEventListener("click", function () {
console.log("Button clicked");
});
// jQuery event
$(".button").on("click", function () {
console.log("jQuery click event");
});DOM Breakpoint Debugging â
Set Breakpoints:
- Subtree Modifications: Triggered when child nodes are modified
- Attribute Modifications: Triggered when attributes are modified
- Node Removal: Triggered when node is removed
Usage Scenarios:
// When DOM changes, code will pause at breakpoint
document.querySelector(".container").innerHTML = "<p>New Content</p>";
// Triggers Subtree Modifications breakpointConsole Panel Detailed â
The Console panel is the core tool for JavaScript debugging, providing code execution, error viewing, log output, and other functions.
Basic Log Output â
console Object Methods:
// Basic output
console.log("Normal log info");
console.info("Info prompt");
console.warn("Warning info");
console.error("Error info");
// Formatted output
const user = { name: "Alice", age: 30 };
console.log("User info: %o", user);
console.log("User name: %s, Age: %d", user.name, user.age);
// CSS styled output
console.log(
"%cImportant Notice",
"color: red; font-size: 16px; font-weight: bold;"
);Grouped Output:
console.group("User Data");
console.log("ID:", 12345);
console.log("Name:", "John Doe");
console.log("Email:", "[email protected]");
console.groupEnd();
console.groupCollapsed("Detailed Info (Collapsed)");
console.log("Registration Time:", "2023-01-01");
console.log("Last Login:", "2023-11-27");
console.groupEnd();Object and Array Viewing â
Table View:
const users = [
{ id: 1, name: "Alice", age: 25, city: "Beijing" },
{ id: 2, name: "Bob", age: 30, city: "Shanghai" },
{ id: 3, name: "Charlie", age: 35, city: "Guangzhou" },
];
// Display array in table format
console.table(users);
// Display specific columns
console.table(users, ["name", "city"]);Object Expansion View:
const userProfile = {
name: "John Doe",
age: 28,
address: {
province: "Guangdong",
city: "Shenzhen",
district: "Nanshan",
},
hobbies: ["Reading", "Programming", "Sports"],
greet: function () {
return `Hello, I am ${this.name}`;
},
};
// Expand view object
console.dir(userProfile, { depth: 2 });Performance Measurement â
Time Measurement:
// Start timing
console.time("Algorithm Execution Time");
// Perform some calculations
const result = fibonacci(30);
// End timing
console.timeEnd("Algorithm Execution Time");
// Output: Algorithm Execution Time: 123.456ms
function fibonacci(n) {
if (n <= 1) return n;
return fibonacci(n - 1) + fibonacci(n - 2);
}Performance Markers:
// Add performance marker
performance.mark("start-operation");
// Perform operation
for (let i = 0; i < 1000000; i++) {
Math.sqrt(i);
}
performance.mark("end-operation");
performance.measure("operation-duration", "start-operation", "end-operation");Error Debugging and Breakpoints â
Breakpoint Debugging:
// Use debugger statement in code
function calculateSum(a, b) {
debugger; // Code execution pauses here
const sum = a + b;
console.log("Calculation Result:", sum);
return sum;
}
calculateSum(5, 3);Conditional Breakpoints:
// Set conditional breakpoint in Sources panel
// Condition: user.age > 18
function checkUserAge(user) {
if (user.age > 18) {
console.log("User is adult");
} else {
console.log("User is minor");
}
}Sources Panel Detailed â
The Sources panel is the core panel for JavaScript code debugging, providing code viewing, breakpoint setting, variable monitoring, and other functions.
File Resource Management â
Resource Viewing:
- Page: All resource files of the current page
- FileSystem: Local file system mapping
- Content scripts: Browser extension scripts
- Snippets: Code snippet management
Local File Mapping:
// Add local workspace in Sources panel
{
"name": "my-project",
"localPath": "/path/to/your/project",
"writable": true
}Breakpoint Debugging Functions â
Breakpoint Types:
// 1. Normal Breakpoint: Pause at specific line
function processOrder(order) {
validateOrder(order); // Set breakpoint here
calculateTotal(order);
sendNotification(order);
}
// 2. Conditional Breakpoint: Pause when condition is met
function processUsers(users) {
users.forEach((user) => {
if (user.isActive) {
// Set condition: user.id === 123
processActiveUser(user);
}
});
}
// 3. DOM Breakpoint: Pause when DOM changes
document.getElementById("container").appendChild(newElement);
// Set DOM breakpoint for #container in Element panelCall Stack:
// View function call chain
function main() {
const result = processData(getData());
console.log(result);
}
function getData() {
return fetch("/api/data").then((res) => res.json());
}
function processData(data) {
return data.map((item) => ({ ...item, processed: true }));
}
// Set breakpoint in processData, view call stack
// Call stack shows: processData -> main -> (anonymous)Code Snippet Management â
Create and Save Code Snippets:
// Create common code snippets in Snippets
// 1. Page Performance Test Snippet
function measurePerformance() {
const timing = performance.timing;
const loadTime = timing.loadEventEnd - timing.navigationStart;
console.log("Page Load Time:", loadTime + "ms");
const paintEntries = performance.getEntriesByType("paint");
paintEntries.forEach((entry) => {
console.log(`${entry.name}: ${entry.startTime}ms`);
});
}
// 2. Element Selection Snippet
function getSelectedElement() {
const selection = window.getSelection();
if (selection.rangeCount > 0) {
const selectedElement = selection.getRangeAt(0).commonAncestorContainer;
console.log("Selected Element:", selectedElement);
return selectedElement;
}
}
// 3. Network Request Snippet
function testAPI(url) {
fetch(url)
.then((response) => response.json())
.then((data) => console.log("API Response:", data))
.catch((error) => console.error("API Error:", error));
}Async Debugging â
Async Call Stack:
// Async function debugging
async function fetchUserData(userId) {
try {
// Set breakpoint here, view async call stack
const response = await fetch(`/api/users/${userId}`);
const userData = await response.json();
return processUserData(userData);
} catch (error) {
console.error("Failed to fetch user data:", error);
}
}
function processUserData(userData) {
return {
...userData,
lastUpdated: new Date().toISOString(),
};
}
// Call async function
fetchUserData(123);Network Panel Detailed â
The Network panel is used to analyze network requests of the page, including HTTP requests, WebSocket connections, resource loading, etc.
Request Monitoring and Analysis â
Request Classification Display:
- All: All requests
- Fetch/XHR: AJAX requests
- Doc: HTML documents
- CSS: Stylesheets
- JS: JavaScript files
- Img: Image resources
- Media: Media files
- Font: Font files
- Other: Other resources
Request Details:
// Example: View AJAX request details
fetch("/api/users", {
method: "GET",
headers: {
"Content-Type": "application/json",
Authorization: "Bearer token123",
},
})
.then((response) => response.json())
.then((data) => console.log(data));
// In Network panel you can view:
// - Request URL and Method
// - Request Headers and Response Headers
// - Request Parameters and Response Data
// - Status Code and Response Time
// - Resource Size and Load TimePerformance Analysis â
Timeline View:
- Queueing: Request queueing time
- Stalled: Waiting time
- DNS Lookup: DNS resolution time
- Initial connection: Initial connection time
- SSL/TLS: Secure connection time
- Request sent: Request sending time
- Waiting (TTFB): Waiting for server response time
- Content Download: Content download time
Network Optimization Suggestions:
// Analyze page load performance
function analyzePageLoad() {
const resources = performance.getEntriesByType("resource");
const totalSize = resources.reduce(
(sum, resource) => sum + resource.transferSize,
0
);
const totalTime = Math.max(...resources.map((r) => r.responseEnd));
console.log(`Total Resource Size: ${(totalSize / 1024).toFixed(2)} KB`);
console.log(`Total Load Time: ${totalTime.toFixed(2)} ms`);
// Analyze slow resources
const slowResources = resources.filter((r) => r.duration > 1000);
if (slowResources.length > 0) {
console.warn(
"Slow loading resources:",
slowResources.map((r) => r.name)
);
}
}Request Filtering and Search â
Filter Rules:
// Common filter expressions
// 1. Filter by status code
status:200 // Show only successful requests
status:404 // Show only 404 errors
status:500 // Show only server errors
// 2. Filter by request type
method:GET // Show only GET requests
method:POST // Show only POST requests
method:XHR // Show only AJAX requests
// 3. Filter by domain
domain:api.example.com // Show only requests from specified domain
domain:cdn.example.com // Show only CDN requests
// 4. Filter by resource type
mime-type:image/png // Show only PNG images
mime-type:text/css // Show only CSS files
mime-type:application/json // Show only JSON responses
// 5. Filter by response size
larger-than:100KB // Show resources larger than 100KB
smaller-than:1MB // Show resources smaller than 1MBWebSocket Debugging â
WebSocket Connection Monitoring:
// WebSocket connection example
const ws = new WebSocket("wss://echo.websocket.org");
ws.onopen = function (event) {
console.log("WebSocket connection established");
ws.send("Hello WebSocket!");
};
ws.onmessage = function (event) {
console.log("Message received:", event.data);
};
ws.onclose = function (event) {
console.log("WebSocket connection closed");
};
ws.onerror = function (error) {
console.error("WebSocket error:", error);
};
// In Network panel you can view:
// - Connection status and protocol
// - Sent and received messages
// - Connection time and latencyPerformance Panel Detailed â
The Performance panel is used to analyze the runtime performance of the page, including rendering performance, JavaScript execution, memory usage, etc.
Performance Recording and Analysis â
Recording Performance Data:
// Performance test code
function createPerformanceTest() {
const container = document.getElementById("container");
const startTime = performance.now();
// Create large number of DOM elements (performance test)
for (let i = 0; i < 10000; i++) {
const div = document.createElement("div");
div.textContent = `Element ${i}`;
div.className = "test-element";
container.appendChild(div);
}
const endTime = performance.now();
console.log(`Creating 10000 elements took: ${endTime - startTime} ms`);
}
// Record in Performance panel:
// 1. Click record button
// 2. Execute performance test code
// 3. Stop recording
// 4. Analyze performance dataFrame Rate and Rendering Performance â
FPS (Frames Per Second) Monitoring:
// FPS calculation code
let lastTime = performance.now();
let frameCount = 0;
function calculateFPS() {
frameCount++;
const currentTime = performance.now();
if (currentTime >= lastTime + 1000) {
const fps = Math.round((frameCount * 1000) / (currentTime - lastTime));
console.log(`Current FPS: ${fps}`);
frameCount = 0;
lastTime = currentTime;
}
requestAnimationFrame(calculateFPS);
}
// Start FPS monitoring
calculateFPS();Main Thread Analysis:
// Long task detection
function detectLongTasks() {
if ("PerformanceObserver" in window) {
const observer = new PerformanceObserver((list) => {
for (const entry of list.getEntries()) {
console.log(`Long task detected: ${entry.duration}ms`, entry);
}
});
observer.observe({ entryTypes: ["longtask"] });
}
}
detectLongTasks();Memory Analysis â
Memory Usage Monitoring:
// Memory usage analysis
function analyzeMemoryUsage() {
if (performance.memory) {
const memory = performance.memory;
console.log("Memory usage:");
console.log(`Used: ${(memory.usedJSHeapSize / 1024 / 1024).toFixed(2)} MB`);
console.log(
`Total: ${(memory.totalJSHeapSize / 1024 / 1024).toFixed(2)} MB`
);
console.log(
`Limit: ${(memory.jsHeapSizeLimit / 1024 / 1024).toFixed(2)} MB`
);
}
}
// Monitor memory periodically
setInterval(analyzeMemoryUsage, 5000);Memory Leak Detection:
// Create code that might cause memory leak
function createMemoryLeakExample() {
const elements = [];
function createLeakingElements() {
// Create elements but don't clean up
for (let i = 0; i < 1000; i++) {
const element = document.createElement("div");
element.onclick = function () {
console.log("Clicked element", i);
};
elements.push(element);
}
}
return createLeakingElements;
}
// Use Memory panel to detect memory leaks
// 1. Take snapshot
// 2. Execute code that might leak
// 3. Take snapshot again
// 4. Compare two snapshots to find objects that cannot be garbage collectedApplication Panel Detailed â
The Application panel is used to manage the storage, service workers, cache, etc., of web applications.
Storage Management â
Local Storage:
// Local Storage operation example
localStorage.setItem(
"userPreferences",
JSON.stringify({
theme: "dark",
language: "en-US",
fontSize: 16,
})
);
const preferences = JSON.parse(localStorage.getItem("userPreferences"));
console.log(preferences);
// Remove specific item
localStorage.removeItem("userPreferences");Session Storage:
// Session Storage operation example
sessionStorage.setItem("currentPage", window.location.href);
sessionStorage.setItem("visitTime", new Date().toISOString());
const lastPage = sessionStorage.getItem("currentPage");
console.log("Last visited page:", lastPage);IndexedDB:
// IndexedDB example
function initIndexedDB() {
return new Promise((resolve, reject) => {
const request = indexedDB.open("MyDatabase", 1);
request.onerror = () => reject(request.error);
request.onsuccess = () => resolve(request.result);
request.onupgradeneeded = (event) => {
const db = event.target.result;
if (!db.objectStoreNames.contains("users")) {
const store = db.createObjectStore("users", { keyPath: "id" });
store.createIndex("name", "name", { unique: false });
}
};
});
}Service Workers Management â
Service Worker Registration:
// Service Worker registration code
if ("serviceWorker" in navigator) {
navigator.serviceWorker
.register("/sw.js")
.then((registration) => {
console.log("Service Worker registration successful:", registration);
})
.catch((error) => {
console.error("Service Worker registration failed:", error);
});
}
// sw.js file content
self.addEventListener("install", (event) => {
console.log("Service Worker installed");
event.waitUntil(
caches.open("v1").then((cache) => {
return cache.addAll([
"/",
"/index.html",
"/styles/main.css",
"/scripts/main.js",
]);
})
);
});
self.addEventListener("fetch", (event) => {
event.respondWith(
caches.match(event.request).then((response) => {
return response || fetch(event.request);
})
);
});Practical Debugging Tips â
Mobile Debugging â
Chrome Remote Debugging:
<!-- Mobile debugging page -->
<!DOCTYPE html>
<html>
<head>
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>Mobile Debugging Test</title>
</head>
<body>
<div class="container">
<h1>Mobile Debugging Test</h1>
<button id="testBtn">Test Button</button>
<div id="result"></div>
</div>
<script>
// Mobile specific code
document.getElementById("testBtn").addEventListener("click", function () {
const touch =
"ontouchstart" in window ? "Touch Supported" : "Touch Not Supported";
document.getElementById("result").textContent = touch;
console.log("Device Info:", {
userAgent: navigator.userAgent,
width: window.innerWidth,
height: window.innerHeight,
});
});
</script>
</body>
</html>Advanced Breakpoint Debugging â
Conditional Breakpoint Settings:
// Set conditional breakpoint in Sources panel
// Condition: user.id === currentUserId
function processUsers(users, currentUserId) {
users.forEach((user) => {
if (user.id === currentUserId) {
// Set conditional breakpoint, pause only when matching current user
console.log("Processing current user:", user);
processCurrentUser(user);
}
});
}DOM Breakpoints:
// DOM change monitoring
function monitorDOMChanges() {
const container = document.getElementById("container");
// Set breakpoint for container in Elements panel:
// - Subtree Modifications: Triggered when child nodes are modified
// - Attribute Modifications: Triggered when attributes are modified
// - Node Removal: Triggered when node is removed
container.innerHTML = "<p>New Content</p>"; // Triggers DOM breakpoint
container.setAttribute("data-updated", "true"); // Triggers attribute breakpoint
container.remove(); // Triggers removal breakpoint
}Performance Monitoring Tips â
Network Performance Monitoring:
// Network performance analysis
function analyzeNetworkPerformance() {
const resources = performance.getEntriesByType("resource");
resources.forEach((resource) => {
console.log(`${resource.name}:`, {
size: `${(resource.transferSize / 1024).toFixed(2)} KB`,
time: `${resource.duration.toFixed(2)} ms`,
type: resource.initiatorType,
});
});
// Find the slowest resource
const slowestResource = resources.reduce((slowest, current) =>
current.duration > slowest.duration ? current : slowest
);
console.log("Slowest Resource:", slowestResource);
}
// Execute after page load
window.addEventListener("load", analyzeNetworkPerformance);Summary â
Browser developer tools are one of the most important tools for frontend developers. Mastering them can significantly improve debugging efficiency and development quality.
Key Points Review:
- Developer tools provide core functions such as HTML/CSS inspection, JavaScript debugging, and performance analysis.
- Elements panel is used to inspect DOM structure and CSS styles, supporting real-time editing.
- Console panel provides powerful JavaScript debugging and logging functions.
- Sources panel is the core tool for code breakpoint debugging.
- Network panel is used to analyze network requests and optimize performance.
- Performance panel helps analyze runtime performance and memory usage.
- Application panel manages storage and service workers for web applications.
- Mastering mobile debugging and advanced debugging tips can solve complex problems.
Learning developer tools is a gradual process. It is recommended to start with basic element inspection and console usage, and gradually master more advanced functions. As you gain experience, you will find that developer tools are not just debugging tools, but also important assistants for learning Web technologies, optimizing page performance, and improving development efficiency.