← JavaScript Learning Path

JAVASCRIPT V2 · BROWSER · 69

Browser DevTools:不要猜,直接看 Runtime Evidence

「畫面怪怪的」不是 diagnosis。Browser 同時包含 DOM、CSS、JavaScript runtime、storage、network 與 rendering。DevTools 的價值不是面板多,而是讓你回答:最後哪一步成功?第一個哪一步失敗?

Learning outcomes

1. Why now:前兩課建立了 pipeline,這一課學會把它拆開

User
  ↓ event
callback
  ↓ state
render()
  ↓ DOM
fetch()
  ↓ HTTP
API

任何一層失敗都可能最後只表現成「按鈕沒反應」或「資料沒出來」。Debug 的第一原則是不要從 symptom 直接跳到修正。

2. Elements:現在 live DOM 到底長什麼樣

Source:
<main id="app"></main>

Runtime JS:
app.innerHTML =
  "<button>Save</button>";

View Source 可能只有空 main;Elements 則會看到 runtime 加上的 button。你要 debug 畫面,就應該看現在的 DOM,而不是只看原始檔。

3. Styles / Computed:Element 存在,不代表使用者看得到

.action {
  display: block;
}

.hidden {
  display: none;
}

Styles 告訴你哪些 selector 命中、哪些 declaration 被覆蓋;Computed 告訴你最終值。這比看到元素消失就補 !important 更可靠。

4. Console:Runtime value / type / exception 的第一站

const button =
  document.querySelector("#save");

console.log({
  button,
  type: typeof button
});

Console 適合快速驗證 selector、state、function output 與 exception。但不要把 production secrets/token 印出來。

5. Sources:當問題不是一個 log 能看懂時,用 breakpoint

function handleSubmit(event) {
  event.preventDefault();

  const score =
    Number(scoreInput.value);

  saveStudent(score);
}

在 saveStudent(score) 前設 breakpoint,可以看 call stack、local variables、scope、目前 line。這對「值在哪一步變錯」尤其重要。

6. Network:Request / Response 的 protocol evidence

Request URL:
https://example.test/api/students

Method: GET
Status: 403

Response:
{"error":"forbidden"}

403 能證明 server 回了 forbidden response;不能單靠 status 就證明是哪個 RLS policy 或哪個 user identity 出錯。你還要繼續蒐集身份與 server/data evidence。

7. Worked Example A:Spinner 永遠轉

Console:
(no uncaught error)

Network:
GET /api/search?q=js
429 Too Many Requests

Retry-After: 30

第一個 failure evidence 在 HTTP response,不是 CSS。接著才問 UI 的 error state 為何沒有處理 429。

8. Worked Example B:Button 在 DOM,但看不到

Elements:
<button
  id="save"
  class="action hidden"
>
  Save
</button>

Computed:
display: none

DOM evidence 證明 element 存在;CSS evidence 說明 presentation 把它隱藏。不要跳去查 API。

9. Worked Example C:資料成功回來但畫面仍舊

Network:
GET /api/students
200 OK

Response:
[{"name":"Amy","score":90}]

Console:
state.data.length === 1

Elements:
#students is empty

Network 與 state 都成功,第一個可疑 boundary 變成 render / DOM update。這就是「最後成功 / 第一失敗」方法。

10. Storage:確認 Browser-side persistence,而不是憑印象

localStorage:
gradeTrackerV1 = {...}

sessionStorage:
(empty)

Application/Storage panel 可以直接看 key/value。但 storage evidence 只證明 Browser storage 狀態,不代表 server database 有相同資料。

11. Timing:慢不等於 server 一定慢

Queueing   2 ms
DNS       18 ms
Connect   35 ms
TTFB     820 ms
Download   4 ms

如果 TTFB 很長,才比較像 server/upstream waiting;如果 DNS/connect 才長,方向不同。Performance/Network timing 的價值是把「很慢」分段。

12. Common mistakes

A. 一看到 API error 就改 frontend code

先看 request/status/body。

B. 一看到 element 不見就加 CSS

先確認 DOM 是否存在。

C. Console 沒 error就認為 JS 沒問題

Logic bug 可能完全不 throw。

D. 一次改五個地方再重新整理

你會失去哪個 hypothesis 被驗證的資訊。

13. Debug evidence workflow:固定六步

1. Reproduce
2. Classify layer
3. Collect evidence
4. Form hypothesis
5. Change one thing
6. Re-run same reproduction

修好後還要加 regression guard;否則你只是「目前看起來正常」。

14. Guided exercise:Selector Failure

const save =
  document.querySelector(
    "#save-course"
  );

save.addEventListener(
  "click",
  handleSave
);

畫面其實只有 id="save"。請寫出你會開哪個 panel、要看到什麼 evidence、哪一行是 first failure、修正後如何驗證。

15. Independent exercise:三種 fault injection

在 Grade Tracker 故意製造:錯 selector、CSS display:none、API 404。每一個 incident 都記錄 symptom、第一個 panel、evidence、root cause、fix、retest。

16. Challenge:200 OK 但畫面資料錯

Network:
200 OK
{"score":90}

Console:
data.score === 90

Elements:
#score textContent = "0"

你不能再怪 network。設計最短的下一步 evidence chain 找出 render mapping 是否讀了錯 property、舊 state,或 render 根本沒跑。

Project checkpoint:Browser Incident Notebook

Incident #1
Symptom:
Evidence:
Last success:
First failure:
Hypothesis:
Fix:
Regression:

從這一課開始,Project checkpoint 不只保存「完成畫面」,還保存 debug evidence。後面的 Node、Linux、CI 都沿用同一 incident format。

17. Vocabulary / Summary

18. Further reading

Knowledge check

  1. 說明 Elements 與 View Source 為何可能不同。
  2. CSS 覆蓋問題應蒐集哪些 evidence。
  3. HTTP 403 能證明與不能證明什麼。
  4. 解釋「最後成功 / 第一失敗」如何縮小 root cause。
  5. 完成頁面下方三個 Evidence Diagnostic incidents。