這部分內容包括 JavaScript 和瀏覽器中近期引入的性能優化工具和 API,這些新特性主要幫助開發者提升代碼的執行效率和加載速度。主要的新特性可能包括:
performance.now()
提供高精度的時間戳,用於性能測試。Performance.mark()
和 Performance.measure()
的擴展功能Performance.mark()
和 Performance.measure()
是 Web Performance API 的一部分,用於標記和測量程式碼執行時間,2024 年的擴展使得這些方法更加靈活和精確。
mark()
方法在瀏覽器的效能緩衝區中使用給定名稱新增一個 timestamp(時間戳)。
measure()
方法在瀏覽器效能記錄快取中建立了一個名為時間戳記的記錄來記錄兩個特殊標誌位元(通常稱為開始標誌和結束標誌)。
優點
這些方法可以用於精確測量程式碼區塊的效能,幫助開發者分析執行時間和最佳化效能。
performance.mark('start');
// do somthing...
performance.mark('end');
performance.measure('My Measurement', 'start', 'end');
const measures = performance.getEntriesByName('My Measurement');
console.log(measures);
SharedArrayBuffer
和 Atomics
的改進MDN:SharedArrayBuffer、Atomics
參考文章:SharedArrayBuffer和Atomics是什么
功能
一直以來 Javascript 都是單線程的,因為在運行時頁面是不能響應用戶的交互的,因此如果運行時間較長,用戶就會感覺頁面卡死了,使用者體驗下降,慢慢造訪的人就會降低;SharedArrayBuffer
和 Atomics
的改進使得在多執行緒環境中對共享記憶體的操作更有效率。
SharedArrayBuffer
是一種新的記憶體類型,可以在多個線程之間共享,允許多個執行緒直接存取相同的記憶體區域,從而實現共享資料的功能。
Atomics
是一個全域對象,它提供了一組原子操作的方法,用於在多個線程之間安全地讀寫 SharedArrayBuffer
中的記憶體。
優點
改進後的 API 提供了更有效率的同步和通訊方式,適合併發程式設計和效能最佳化。
const sharedBuffer = new SharedArrayBuffer(1024);
const int32Array = new Int32Array(sharedBuffer);
Atomics.store(int32Array, 0, 42);
console.log(Atomics.load(int32Array, 0));
這部分內容關注於如何測試和改進代碼的性能,包括:
性能測試工具:
內存分析:識別內存泄漏和過度使用的情況。
減少重排和重繪:優化 DOM 操作,減少不必要的重排和重繪。
🔔 推薦壓縮圖片檔的網站:
Smart WebP, PNG and JPEG Compression for Faster Websites
🤔 這麼多內容,到底怎麼做才有點優化的效果呢?
以下是實戰以來有遇到後改變寫法提升效能的範例,雖然最後多半還是靠後端 api 速度提升,前端減少呼叫才讓使用者體感變好!
減少 DOM 操作:盡量減少存取和操作 DOM 的次數,因為很慢
// 原來寫法
document.getElementById('myElement').style.color = 'gold';
document.getElementById('myElement').style.backgroundColor = 'black';
// 建議寫法
const element = document.getElementById('myElement');
element.style.color = 'gold';
element.style.backgroundColor = 'black';
使用高效率的循環結構:當效能至關重要時,優先選擇「for
」迴圈或是用高階函數
const arr = [1, 2, 3, 4, 5];
// 原來寫法
for (let i in arr) {
console.log(arr[i]);
}
// 建議寫法
for (let i = 0; i < arr.length; i++) {
console.log(arr[i]);
}
避免不必要的函數呼叫
// 原來寫法
function getSquare(num) {
return num * num;
}
for (let i = 0; i < 1000; i++) {
const square = getSquare(i);
}
// 建議寫法
for (let i = 0; i < 1000; i++) {
const square = i * i;
}
使用適當的資料結構:在適用的情況下使用映射、集合和類型化陣列 -> 這個在套件中要轉成顯示的架構用過,之後鮮少使用
const map = new Map();
map.set('key', 'value');
console.log(map, map.get('key')) // Map(1) {'key' => 'value'} 'value'
Debounce and ThrottleDebounce
:如果多次點擊按鈕,就有可能出現無回應的情況,並且會出現過多的請求 API 呼叫,去抖動是一種程式設計實踐,確保某些任務不會過於頻繁地觸發。
<button type="submit" id="debounce">submit</button>
const debounce = (fn, delay) => {
let timeoutID;
return function (...args) {
if (timeoutID) {
clearTimeout(timeoutID);
}
timeoutID = setTimeout(() => {
fn(...args);
}, delay);
}
}
document.getElementById('debounce').addEventListener('click',
debounce((e) => {
console.count('debounce_click');
}, 2000)
);
Throttle
:當第一次單擊按鈕時,它將執行操作,如果繼續單擊該按鈕,直到時間間隔過去,它才會觸發事件,如果繼續單擊它會在每次完成間隔時觸發。
<button type="submit" id="throttle">submit</button>
const throttle = (fn, delay) => {
let last = 0;
return (...args) => {
const now = new Date();
if (now - last < delay) return;
last = now;
return fn(...args)
}
}
document.getElementById('throttle').addEventListener('click',
throttle((e) => {
console.count('throttle_click');
}, 2000)
);
如果圖片太模糊,可以到 YT 看錄製的 透過 console.log 認識 Debounce and Throttle 13 秒影片唷!我嘗試多種轉檔,畫面如果真的不行,首先還是謝謝您的觀賞,但是也請告訴我,一起想辦法吧!感謝您!