Translate

2026年2月15日 星期日

Optimizing nsWindow::OnMotionNotifyEvent: Fixing the high polling rate mouse overhead in Firefox on Linux

更新速度很慢是因為CPU的編譯太慢了

我始終接受不了在我這裡的firefox性能需求很高。 於是我就最近跳到Thorium Browser AVX,(Chrome)。

但是我真的太過好奇為什麼會有這個問題啊. 我決定去搜尋,我看到了一個網站有人這麼做#3, 於是我決定自己去分析(使用Ai工具補助分析)

你們可以看這個:https://share.firefox.dev/4qDIH7d

PS:這是我單獨開一個設定檔去測試的,什麼設定都沒有修改。

Environment:

  •     OS: Arch Linux
  •     Resolution: 1920x1080 60hz, 2560x1440 75hz
  •     DE: KDE Plasma 6.5.5 (Wayland)
  •     WM: kwin_wayland_wr
  •     CPU: E3-1230 v2 (Ivy Bridge)
  •     GPU: AMD Radeon RX Vega 64 (radeonsi, vega10, ACO, DRM 3.64, 6.18.5-1-cachyos)
  •     Browser: Firefox 147 (Parent Process)


about:support:

  •     Compositing WebRender
  •     Window Protocol wayland
  •     Desktop Environment kde
  •     Target Frame Rate 60


初步觀察amdgpu_top 顯示滑鼠移動時 CPU劇增。

滑鼠不移動:0%。

滑鼠移動:

  •     125Hz:10~14%。
  •     250Hz:23~28%。
  •     500Hz:34~42%。
  •     1000Hz:48~55%),

ALL GPU(GFX) Usage為0%。


對照:同樣硬體,Chromium 核心無此問題#4。

滑鼠不移動:0%。

滑鼠移動:

  •     125Hz:1~3%。
  •     250Hz:1~3%。
  •     500Hz:1~3%。
  •     1000Hz:1~3%。

ALL GPU(GFX) Usage為0%。


PS:根據我的測試不管用什麼firefox的分支 or 官方最新的遊覽器(Firefox、LireWolf、Zen Browser)都是一樣。

可惜我沒有其他的硬體設備可以測試問題 是否是單一性問題還是Firefox程式問題...


證據:Firefox Profiler 顯示主執行緒被 handleEvent 塞滿,且大量的時間消耗在 IPC 通訊 與 Event Dispatching。


EventListener.handleEvent

    handleEvent chrome://browser/content/browser.js:4157:14

        forEach self-hosted:4110:20

            Set.prototype.values

---2026/02/15---

mouse: 1000hz。

第一版的patch確定可以減少了。

mouse.throttle.enabled=true

mouse.throttle.interval=

  • 1: 35~37%
  • 8: 11~13%
  • 20: 10~12% 可以使用。
  • 100: 8~9% Firefox GUI明顯延遲。

PS:system mouse沒有影響。只影響GUI。影響就是你用滑鼠按住複製會有影響,變得變得明顯反應很慢。

$$1000ms \div 60 \approx 16.67ms$$建議數值:16 或 17。

設定為 16 的優點:理論頻率約 62.5Hz,略高於螢幕刷新率,能確保滑鼠軌跡在螢幕更新前就已經準備好數據,體感上會最接近「無延遲」。

設定為 17 優點優點:理論頻率約 58.8Hz,比 60Hz 慢一點點,對 CPU 壓力最輕,但對於極度敏感的人來說,可能會感覺滑鼠稍微有一點點跟不上螢幕(極微小)
因此我最後決定使用16

---2026/02/16---

我發現到第二版的patch可能會有問題,雖然當初考量到精度把mLastMouseCoordinates.Set(aEvent) 被放在函式的最頂端,但是問題就是造成的CPU不斷刷新。


目前現況總結 (Summary of Discoveries)

  1. 效能瓶頸確認 (Performance Bottleneck)

    • 在之前的 Patch 中,mLastMouseCoordinates.Set(aEvent) 被放在函式的最頂端(大門口)。

    • 這導致在高回報率滑鼠(1000Hz)下,CPU 每秒必須強行執行 1000 次座標轉換與物件更新。

    • Profiler 證據:你在截圖中看到的密集彩色波峰,就是這些高頻率、小規模的運算堆疊而成的結果,這會讓 Parent Process 持續處於忙碌狀態。

  2. 節流與合併的權衡 (Throttling vs. Coalescing)

    • 丟棄模式 (Throttling):不執行 Set 直接返回。最省 CPU,但可能導致 16ms 內位置資訊完全跳躍。

    • 合併模式 (Coalescing):即使節流也先執行 Set。這確保了「最後已知座標」永遠是最新的,雖然多了一點開銷,但能維持瀏覽器內部的座標狀態(State)正確。

  3. 手寫筆精度風險 (Stylus Risk)

    • 現有 Patch 預設對所有設備節流。如果使用手寫筆進行繪圖,每 16ms 才取一個點會導致線條變形(失真)。

    • 代碼中雖然有 IsPenEvent 檢測,但尚未與節流邏輯連動。


後續測試計畫 (Testing Plan)

為了驗證上述推論,我們將測試以下三個階段的 Patch,建議你依照順序編譯並觀察 Profiler:

  1. 驗證節流有效性 (Fix 1: Basic)

    • 動作:將 Set 移入判斷式之後。

    • 預期:彩色波峰會大幅稀疏化,CPU 佔用率降至最低。

  2. 驗證合併開銷 (Fix 2: Coalesce Option)

    • 動作:開啟 mouse.throttle.coalesce = true

    • 預期:彩色波峰會比 Fix 1 密一點,但仍遠低於沒打補丁的狀態。

  3. 驗證白名單邏輯 (Fix 3: Pen Bypass)

    • 動作:使用「日誌列印法」或「邏輯反轉法」確認滑鼠不會誤入 Pen 邏輯。

    • 預期:確保未來接入高精度設備時不會發生精度 Regression。


Index Page

索引 (Master Index) 歡迎來到我的blogger。這裡紀錄了我關於技術、實作與靈性的研究紀錄。 電子 (Electronics) 硬體調修、電路板研究與元件實作。 程式 (Programming) Python 語言自動化、邏輯與開發心得。 A...