bug frontend ส่วนใหญ่ตายใน DevTools ไม่ใช่ใน editor ไม่ใช่ใน Stack Overflow — แต่ใน panel ที่คุณเปิดด้วย F12 แล้วปิดไปอีกห้าวินาทีถัดมา ช่องว่างระหว่างวิศวกรที่ไล่ bug เป็นชั่วโมงกับคนที่แก้เสร็จในห้านาที มักจะเป็นเรื่องของนิสัยการใช้ DevTools ไม่กี่อย่าง ไม่ใช่เรื่องพรสวรรค์
บทความนี้คือชุดปฏิบัติ ไม่ใช่ทุก panel — แต่เป็นสิ่งที่คุณเอื้อมไปใช้จริงเวลาเว็บมีปัญหา และ shortcut ที่ทำให้มันเร็วขึ้น
TL;DR
Ctrl+Shift+C→ คลิกเลือก element ตรง ๆ- ใช้ conditional breakpoint แทน
console.logใน loop- ใน Network panel ตั้ง “Disable cache” + “Preserve log” เป็น default ไว้
- Performance → record สำหรับ jank; Rendering → Paint flashing สำหรับ layout thrash
debugger;ใน source code มักเร็วกว่าการคลิก line number
เปิด DevTools ให้ถูกวิธี
F12 ใช้ได้, Ctrl+Shift+I (Cmd+Option+I บน macOS) ก็ได้, right-click → Inspect ก็ได้ แต่ที่สำคัญที่สุดคือ Ctrl+Shift+C — มันจะเข้าสู่ element picker mode ทันที คลิกถัดไปจะไปโดนสิ่งที่คุณอยากดู สามปุ่ม ไม่ต้องไล่หา panel
ตำแหน่ง dock สำคัญกว่าที่คนคิด ผม dock ไว้ ขวามือ บนจอกว้างเพื่อให้ viewport ยังกว้างสมจริง และ undock ออกเป็น window แยกเมื่อต้องใช้ Elements + Console + Network พร้อมกัน เมนูมุมขวาบน (⋮) มีตัวเลือกให้เลือก
Elements panel: DOM, styles, layout
ที่นี่คือที่ที่ bug CSS 70% ถูกแก้ สิ่งที่ควรรู้นอกเหนือจาก “คลิก node แล้วดู style”:
Computed vs Styles. แท็บ Styles แสดงทุก rule ที่ browser match ได้ ตามลำดับ cascade พร้อมขีดฆ่าตัวที่ถูก override ส่วน Computed แสดงค่าสุดท้ายที่ browser ใช้จริง เวลา style “ไม่ติด” ให้ดู Computed ก่อน — มันบอกสิ่งที่ชนะ ไม่ใช่สิ่งที่คุณเขียน
:hov และ :cls. ปุ่ม :hov ให้คุณ pin state (:hover, :focus, :active, :focus-within) เพื่อดู hover style โดยที่ cursor ไม่ต้องอยู่ที่เดิม ส่วน :cls ใช้ toggle class บน node โดยไม่ต้องแก้ markup
Box model diagram. อยู่ด้านล่างของแท็บ Styles คลิกตัวเลขไหนก็ได้ — margin, border, padding, width, height — แก้ inline ได้เลย เร็วกว่าเขียน rule แล้ว reload
Layout debugging. hover ไปที่ sub-tab “Layout” → เปิด grid area line numbers หรือ flexbox badges เวลา container flex/grid ทำอะไรแปลก ๆ การเปิด overlay badge เร็วกว่าอ่านโค้ด
Copy selector / XPath. right-click node → Copy → Copy selector เอาไว้ใช้ตอนเขียน test หรือส่ง locator ให้คนอื่น
Console: ไม่ใช่แค่ console.log
ทุกคนรู้จัก console.log ตัวที่คุ้มค่า:
console.table(arr)— render array ของ object เป็นตารางที่ sort ได้ อ่านห้าวินาที แทนที่จะต้องไล่ดูสามสิบวินาทีconsole.dir(el)— แสดง DOM element เป็น JS object (property ทั้งหมด) ไม่ใช่เป็น markup ใช้เวลาอยากเห็น event listener, dataset หรือ internal fieldconsole.trace()— print stack trace ณ จุดที่เรียก เหมาะกับคำถาม “ใครเรียก function นี้?”console.time('label')/console.timeEnd('label')— จับเวลา block อย่างเร็ว$0,$1,$2… — ห้า element สุดท้ายที่คุณ select ใน Elements panel ใช้ได้เป็นตัวแปรใน Console รวมกับ$0.getBoundingClientRect()แทน log ได้เยอะ$$('selector')— shorthand ของArray.from(document.querySelectorAll(selector))monitor(fn)/monitorEvents(node, 'click')— log ทุก call หรือทุก event โดยไม่ต้องเขียน wrapper
อีกอัน: live expressions (ไอคอนรูปตาด้านบน Console) pin expression ที่จะ re-evaluate ทุก tick pin document.activeElement ตอน debug focus bug คุณจะไม่ต้องคลิก “evaluate” มืออีกเลย
Sources panel: breakpoint ดีกว่า print
ถ้ายัง debug ด้วยการโปรย console.log ไปทั่ว loop คุณกำลังเสียเวลาฟรี
Line-of-code breakpoint. คลิก line number ใน Sources พอรันมาถึงบรรทัดนั้นหน้าจะหยุด hover ดูค่าตัวแปรได้ step ด้วย F10/F11 และประเมิน expression ใน console โดย scope อยู่ที่ frame ปัจจุบัน
Conditional breakpoint. right-click line number → “Add conditional breakpoint” พิมพ์ expression มันจะหยุดก็ต่อเมื่อ expression เป็น true อันนี้แหละที่แทนการนั่ง log ทีละ iteration เวลาเจอ “ทำไมมันพังแค่รอบที่ 47”
Logpoint. right-click → “Add logpoint” เหมือน console.log แต่เพิ่มจาก DevTools โดยไม่ต้องแก้ source, รอด reload, ไม่หลุดไป production, ไม่ต้อง rebuild
DOM breakpoint. ใน Elements right-click node → Break on → subtree modifications / attribute modifications / node removal เหมาะตอน “มีอะไรคอยล้าง element นี้” แล้วไม่รู้ว่าคืออะไร
XHR / fetch breakpoint. Sources panel → sidebar Breakpoints → XHR/fetch พิมพ์ URL substring execution จะหยุดทันทีที่ request ตรงถูกยิง ของดีตอนตาม “request นี้มาจากไหน?”
Event Listener breakpoint. sidebar เดียวกัน หัวข้อ “Event Listener Breakpoints” ขยาย Mouse → click ติ๊กช่อง click ครั้งถัดไปจะหยุดใน handler ที่รันจริง เหมาะที่สุดสำหรับการหา library ที่กลืน event ของคุณ
debugger; ใน source. บางทีทางที่เร็วที่สุดคือใส่ debugger; ลงใน code จริง DevTools จะหยุดที่นั่นตราบที่มันเปิดอยู่ ผมใช้ระหว่าง dev และลบก่อน commit
Network panel: เกิดอะไรขึ้นบน wire จริง
เปิด Network, reload มีสองสามอย่างที่ควรเปิดไว้ตลอด:
- Disable cache (checkbox ด้านบน ใช้ได้เมื่อ DevTools เปิด) response ที่ถูก cache ซ่อน bug ไว้
- Preserve log — request อยู่รอดแม้ navigate สำคัญตอน debug redirect หรือ SPA route change
- Filter ตาม type (XHR/Fetch, Doc, CSS, JS, Img) ด้วยปุ่ม pill, ตาม URL substring ด้วยช่อง filter, ตาม status ด้วย
status-code:404, ตาม header ด้วยhas-response-header:
right-click request → Copy → Copy as fetch / Copy as cURL reproduce bug API ใน terminal ภายในสิบวินาที ไม่ใช่สิบนาทีกับ Postman
คอลัมน์ Initiator บอกว่าอะไร trigger request — คลิกเพื่อ jump ไปบรรทัด JS ที่ถูกต้อง แท็บ Timing ของ request แยก queue / DNS / connect / SSL / waiting / download time ซึ่งเป็นวิธีแยก “server ช้า” จาก “network ช้า” จาก “ติดคิวหลัง request อื่นหกตัว”
Throttling. dropdown ข้าง “Disable cache” จำลอง Slow 3G / Fast 3G / offline ทดสอบ loading state ที่นี่ — บน localhost มันโกหก
Application panel: cookies, storage, service workers
เวลา bug auth โผล่ panel นี้คือที่แรก
- Cookies — ดูค่าที่ถูก set ของ origin ปัจจุบัน แก้/ลบ inline ได้ ตรวจ
HttpOnly,Secure,SameSite— bug auth เยอะมากซ่อนอยู่ใน cookie attribute - Local Storage / Session Storage / IndexedDB — หลักการเดียวกัน แก้ inline ได้
- Service Workers — “Update on reload”, “Bypass for network” และปุ่ม Unregister service worker ค้างเป็น cause ของ cache bug แปลก ๆ ถ้าไม่แน่ใจ unregister แล้ว hard-reload
- Clear site data — ไม้ตายเด็ด ล้าง cookie, storage, service worker, cache ทั้งหมดของ origin ปัจจุบัน เวลา bug เกิดจาก state ค้าง อันนี้เร็วกว่า debug
Performance panel: เวลาหน้าช้า
กด record ทำสิ่งที่ช้า หยุด คุณจะได้ flame chart ของทุก task ที่ browser รัน
สิ่งที่ต้องดู:
- Long task (สามเหลี่ยมแดงด้านบน) — task ใดก็ตามที่เกิน 50ms บล็อก input
- Scripting (เหลือง) ครอบงำ frame — JS คือคอขวด
- Rendering (ม่วง) / Painting (เขียว) พุ่ง — layout thrashing หรือ over-paint
- Idle (เทา) = มีที่ว่างให้หายใจ
คลิก long task → ดู call tree → jump ไป function ที่เป็นเหตุ รวมกับมุมมอง Bottom-Up (sort ตาม self time) นี่คือวิธีหา function เดียวที่กินเวลา scripting คุณ 300ms
Rendering panel: เห็นว่า browser ทำอะไร
Ctrl+Shift+P → “Show Rendering” toggle สามตัวคุ้มค่า:
- Paint flashing — พื้นที่ที่ repaint จะสว่างเป็นสีเขียว ถ้าทั้งหน้า flash ทุกครั้งที่ state เปลี่ยน แปลว่าคุณ paint เกิน ลอง memoise ดู
- Layout shift regions — highlight พื้นที่ที่ทำให้ CLS ปัญหา “ทำไม layout กระโดด?” แก้ด้วยตาเปล่า
- FPS meter — overlay ถาวรของ frame rate, GPU memory, dropped frame เปิดไว้ตอน scroll list ยาว ๆ
Responsive design mode
Ctrl+Shift+M แถบ device ด้านบนให้เลือก preset (iPhone, iPad) หรือพิมพ์ขนาดเอง หมุน throttle network emulate touch emulate low-end CPU — ทั้งหมดจากที่นี่ toggle “Show device frame” เป็น cosmetic แต่ทำให้ screenshot ดูดี
สำหรับ debug จริงบนมือถือจริง ใช้ chrome://inspect/#devices บน desktop — เสียบ Android ผ่าน USB เปิด USB debugging แล้วคุณจะได้ DevTools เต็มรูปแบบชี้ไป browser มือถือตัวจริง เป็นวิธีเดียวที่จะจับ “ทำได้ใน responsive mode บน desktop แต่พังบน iOS Safari จริง” — และถึงอย่างนั้น iOS ต้องใช้ Safari Web Inspector ไม่ใช่ Chrome
Framework-specific extensions
tool ใน Chrome ครอบคลุม 90% ของการ debug frontend ส่วนที่เหลือ:
- React Developer Tools — component tree, props, state, hook, profiler แท็บ Profiler record render ให้คุณเห็นว่า component ไหน re-render และทำไม
- Vue DevTools / Svelte DevTools / Angular DevTools — หลักการเดียวกัน เฉพาะ framework
- Redux DevTools — time-travel ไปมาใน state change, replay action, diff ก่อน/หลัง
install เป็น Chrome extension แล้วจะโผล่เป็น panel เสริมใน DevTools
Shortcut ที่คุ้มค่าจะจำ
รายการสั้น ๆ ที่ควรท่องไว้:
Ctrl+Shift+P— command menu (เหมือน VS Code) “Screenshot”, “Paint flashing”, “Capture full size screenshot” อยู่ที่นี่ทั้งหมดCtrl+P— เปิด source file ที่โหลดอยู่แบบเร็วCtrl+Shift+F— search ข้าม source ทั้งหมดที่โหลด (JS, CSS, HTML)Esc— toggle drawer (console ที่ด้านล่าง) โดยไม่ออกจาก panel ปัจจุบันCtrl+[/Ctrl+]— เปลี่ยน panel ไปมา- ใน Elements: ลูกศร navigate tree,
hhide node,F2edit เป็น HTML - ใน Sources:
F8resume,F10step over,F11step into,Shift+F11step out
Mindset ของการ debug
สามเรื่องที่แยกคน debug เร็วจากคน debug ช้า:
- ตั้งสมมุติฐานก่อนแตะอะไร “ผมคิดว่า X เกิดเพราะ Y” แล้วใช้ DevTools พิสูจน์หรือหักล้าง การเดาสุ่มยืด session ออกไปไม่มีที่สิ้นสุด
- ลดผู้ต้องสงสัย ถ้า bug อยู่ใน “component ตัวใดตัวหนึ่งใน 20 ตัว” ให้ bisect — comment ครึ่งหนึ่งออก reload ดูว่ายังเกิดไหม binary search สามรอบเร็วกว่าอ่านทีละบรรทัด
- อ่านค่าจริง อย่า assume ว่า
user.idเป็น number เพราะ type บอกแบบนั้น hover ดูใน Sources type โกหก runtime ไม่
DevTools คือกล้องจุลทรรศน์ สมมุติฐานเป็นของคุณ
อ่านเพิ่มเติม
doc ทางการที่ developer.chrome.com/docs/devtools ดีกว่า blog ส่วนใหญ่ (รวมถึงอันนี้) และ update ตาม panel ใหม่ที่ Chrome ship post “What’s New in DevTools” ทุกหกสัปดาห์ใช้เวลาอ่านห้านาที ฟีเจอร์เล็ก ๆ อย่าง “copy as fetch” และ logpoint เงียบ ๆ โผล่ที่นั่นก่อน
พื้นฐานคือ shortcut, breakpoint และ Network panel ทุกอย่างเหนือกว่านั้นเป็นของเฉพาะทาง — ค่อยเรียนตอน bug บังคับให้คุณต้องเรียน