隨著我們的應用程式規模日益龐大,系統內部的 JavaScript 程式碼基礎也變得越來越複雜。在早期的開發階段,為了快速迭代與推出新功能,我們往往依賴了一些較為寬鬆的寫法。然而,這種為了追求速度而妥協的開發模式,逐漸在系統中累積了可觀的技術債。其中最明顯的問題在於變數宣告的混亂以及作用域(Scope)管理的失控。在未啟用嚴格模式的情況下,JavaScript 引擎對於未宣告的變數會採取隱式全域變數(Implicit Globals)的處理方式,這對長期運行的單頁應用程式(SPA)來說,無疑是一場災難。
為了解決這些潛在的穩定性問題,我們決定進行一次大規模的程式碼重構,並在整個專案中全面啟用 ECMAScript 5 引入的嚴格模式(Strict Mode)。這不僅僅是一次簡單的語法升級,更是我們對軟體工程品質要求的提升。透過重構,我們期望能為使用者帶來更流暢、更不易崩潰的操作體驗,同時也為未來的架構擴展打下堅實的基礎。
在推動這次重構的過程中,我們遇到了一個極為隱蔽且難以除錯的坑:嚴重的記憶體外洩(Memory Leaks)問題。在某次例行性的效能壓力測試中,我們觀察到當使用者在應用程式內頻繁切換不同資料視圖時,瀏覽器的記憶體佔用量會呈現階梯式的異常增長。長時間運行後,甚至會導致頁面無回應或直接崩潰。
起初,我們懷疑是 DOM 節點沒有被正確卸載,或者是事件監聽器(Event Listeners)未被移除。我們花費了大量時間使用 Chrome DevTools 的 Memory 面板進行 Heap Snapshot 記憶體快照比對,分析了無數個 Retainers 樹狀結構。最終,我們驚訝地發現,問題的根源竟然是幾處不起眼的拼寫錯誤與隱式全域變數。
在舊版的程式碼中,開發者在迴圈或函式內部給變數賦值時,不小心漏寫了 var 關鍵字。在非嚴格模式下,JavaScript 引擎並不會報錯,反而會自動在全域物件(在瀏覽器中即為 window)上建立這個變數。由於這些隱式創建的全域變數一直被全域作用域參照,垃圾回收機制(Garbage Collector)便永遠無法回收它們所佔用的記憶體空間。隨著應用程式的運行,這些未預期的資料不斷累積,最終吃光了所有可用記憶體。
確立了問題的根源後,我們隨即展開了修復行動。首先,我們在所有 JavaScript 檔案的頂部加入了 "use strict"; 宣告。這個看似簡單的字串,實際上徹底改變了 JavaScript 引擎的解析與執行行為。嚴格模式下,任何試圖賦值給未宣告變數的操作,都會直接拋出 ReferenceError,從而將這些隱蔽的錯誤在開發階段就暴露出來,而不是等到正式環境才引發記憶體外洩。
接下來,我們全面盤點了系統中所有的變數宣告。我們不僅修復了那些導致記憶體外洩的隱式全域變數,更進一步將所有舊版的 var 替換為 ES6 引入的 let 與 const。let 和 const 提供了區塊作用域(Block Scope),這能更精確地控制變數的生命週期,避免了變數提升(Hoisting)所帶來的邏輯混亂。對於那些初始化後就不應被修改的參考,我們一律使用 const,這也讓程式碼的意圖變得更加清晰可讀。
// 舊版寫法:容易產生隱式全域變數與記憶體外洩
function processData(dataList) {
// 漏寫 var,result 變成全域變數
result = [];
for (i = 0; i < dataList.length; i++) {
// i 也是全域變數
var item = dataList[i];
if (item.active) {
result.push(item);
}
}
return result;
}
"use strict";
// 新版寫法:嚴格模式與區塊作用域,確保記憶體安全
function processData(dataList) {
const result = [];
for (let i = 0; i < dataList.length; i++) {
const item = dataList[i];
if (item.active) {
result.push(item);
}
}
return result;
}
這次的系統更新雖然主要集中在底層程式碼架構的重構上,並未直接新增肉眼可見的大型功能面板,但它為使用者體驗(UX)帶來了質的飛躍。透過消除隱式全域變數與徹底解決記憶體外洩問題,應用程式的整體運行效能得到了顯著提升。
過去,使用者在長時間使用系統進行複雜操作後,常會感到畫面開始卡頓,甚至需要手動重新整理網頁才能恢復正常。現在,由於垃圾回收機制能夠順利且即時地清理不再使用的記憶體,我們大幅減少了 JavaScript 引擎在執行垃圾回收時造成的畫面凍結(Jank)現象。應用程式現在能夠保持長時間的穩定與流暢,無論使用者如何頻繁地切換功能或處理巨量資料,介面反應始終如一地敏捷。這種底層效能的穩定,正是建立使用者對產品信任感的最重要基石。