Chrome DevTools Protocol (CDP)
Get tab WebSocket URL first: Never connect to
ws://localhost:9222/devtools/browser
directly. Fetch
http://localhost:9222/json/list
and use
webSocketDebuggerUrl
from the active tab.
Enable domains before use:
Runtime.enable
and
Page.enable
must be called before any
Runtime.evaluate
or
Page.navigate
commands.
CDP is async: Wait for response before sending next command. Use Promise-based wrapper with response ID tracking.
Screenshot on high-DPI: Include
fromSurface: true
and
scale: 2
in
Page.captureScreenshot
params for Retina displays.
Get response body separately:
Network.responseReceived
doesn't include body. Call
Network.getResponseBody
with requestId after response completes.
Chrome Extension Manifest V3
Permissions split: Use
permissions
for APIs,
host_permissions
for URLs. Never use
http://*/*
in permissions.
Service workers terminate: No persistent state. Use
chrome.storage.local
instead of global variables. Use
chrome.alarms
instead of
setInterval
.
Content script isolation: Can't access page globals. Use
chrome.scripting.executeScript
with
func
for page context. Use
window.postMessage
for content↔page communication.
Storage is async:
chrome.storage.local.get()
returns Promise, not data. Always await. Handle
QUOTA_EXCEEDED
errors.
Context Detection
Detect actual Chrome (not Edge/Brave): Check
window.chrome && navigator.vendor === "Google Inc."
and exclude Opera/Edge.
Extension context types:
chrome.runtime.id
exists → content script
chrome.runtime.getManifest
exists → popup/background/options
chrome.loadTimes
exists but no runtime → regular Chrome web page
Manifest version check: Wrap
chrome.runtime.getManifest()
in try-catch. Use
chrome.action
for V3,
chrome.browserAction
for V2.
Performance Debugging
Memory API conditional: Check
'memory' in performance
before accessing
performance.memory.usedJSHeapSize
.
Use performance marks:
performance.mark()
and
performance.measure()
for sub-frame timing. Clear marks to prevent memory leaks.
Layout thrash detection: PerformanceObserver with
entryTypes: ['measure', 'paint', 'largest-contentful-paint']
. Flag entries >16.67ms.
Network Debugging
Block before navigate: Call
Network.setBlockedURLs
before
Page.navigate
, not after.
Request interception: Use
Network.setRequestInterception
with
requestStage: 'Request'
for granular control. Return
errorReason: 'BlockedByClient'
to block.
Security Contexts
Mixed content: HTTPS pages can't load HTTP resources. Check
location.protocol
vs resource URL.
CORS errors:
TypeError
on cross-origin fetch usually means CORS. Check DevTools Network tab for specific error.
Secure context required: File System Access API, Clipboard API require
window.isSecureContext === true
and user gesture.