狠狠色丁香婷婷综合尤物/久久精品综合一区二区三区/中国有色金属学报/国产日韩欧美在线观看 - 国产一区二区三区四区五区tv

LOGO OA教程 ERP教程 模切知識交流 PMS教程 CRM教程 開發文檔 其他文檔  
 
網站管理員

新穎的 setTimeout() 替代方案 scheduler.yield()

admin
2024年10月18日 23:11 本文熱度 105

在前端開發中,長時間運行的JavaScript任務一直是一個棘手的問題。它們會導致頁面無響應,影響用戶體驗。傳統上,開發者使用setTimeout()來分割長任務,但這種方法存在明顯的缺陷。最近,Chrome 129引入了一種新的、更高效的方法:scheduler.yield()。本文將深入探討這種新技術,并比較其與傳統方法的優劣。

長任務的問題

為了說明長任務的問題,以下是一個示例,任何字符都有其代碼,但并非所有代碼都有相關字符。所有非字符代碼都顯示為白色垂直矩形。您可以在下面顯示與一系列代碼相對應的字符的頁面中看到許多代碼:

?

有很多垂直的矩形,想把它們過濾掉,通過遍歷一系列Unicode字符代碼,過濾掉未分配的代碼點。

const MIN = 127734, MAX = 129686;

function insertChar(code, parent{
    parent.insertAdjacentText('beforeend'String.fromCodePoint(code));
}

function add(i, parent{
    if (!likeNull(i)) // 比較字符i和0的canvas
        insertChar(i, parent);
}

function one(div{
    for (let i = MIN; i < MAX; i++)
        add(i, div);
}

function onClick(func{
    btn.addEventListener('click'async () => {
        btn.remove();
        const start = Date.now();
        await func(div);
        div.insertAdjacentText("afterend"Date.now() - start);
    });
}

onClick(one);

這段代碼在執行過程中會使頁面凍結約4279毫秒,而在此期間,頁面一直處于凍結狀態。即使點擊后代碼會首先移除按鈕,但只要代碼還在運行,瀏覽器就無法更新屏幕。代碼運行結束后,瀏覽器也無法顯示任何字符,按鈕會被移除,字符也會一并顯示, 導致用戶體驗不佳。

因此,在長時間工作時,一定要暫停,讓瀏覽器更新屏幕??梢允褂妙愃频恼Z句暫時中止或中斷長代碼的執行.

使用setTimeout()分割任務

傳統的解決方法是使用setTimeout()來分割任務:

function pause({
    return new Promise(resolve => setTimeout(resolve));
}

async function two(div{
    for (let i = MIN; i < MAX; i++) {
        await pause();
        add(i, div);
    }
}

onClick(two);

這種方法雖然使頁面保持響應,但執行時間顯著增加到約17568毫秒。

setTimeout()的缺點

1.最小超時時間為4毫秒,即使指定為0

即使瀏覽器無事可做,主任務也會暫停至少 4 毫秒。即使指定為零,setTimeout()的最小超時時間 也是 >4 ms。事實上,讓我們來計算一下。在第一頁中,評估 1952 個代碼點需要 4279 毫秒,即每個代碼需要 ~2 毫秒。在第二個頁面中,評估 1952 個代碼點需要 17568 毫秒,即每個代碼點 ~17568/1952=9毫秒。頁面響應速度保持不變,但性能下降也令人印象深刻,這主要是由于超時的持續時間盡可能短。

2.任務繼續執行時被放置在隊列末尾,可能導致優先級問題。

當任務暫停時,setTimeout() 會將其作為一個新任務放置在隊列的最末端。因此,瀏覽器不僅會更新屏幕,還會先執行隊列中的所有任務,然后再繼續執行暫停的任務。

在上面的頁面中,兩個函數two()同時運行:

 onClick(()=>Promise.race([two(div),two(div2)]));

當第一個two()提交給主線程時,第二個two()會在第一個two()繼續執行之前被執行。執行時間會稍有增加,從 17 秒增加到 23 秒,但不會增加兩倍,因為大部分運行時間都是由最小超時加起來的。

scheduler.yield():新的解決方案

scheduler.yield()提供了一種更高效的方法來讓出主線程:

async function three(div{
    for (let i = MIN; i < MAX; i++) {
        await scheduler.yield();
        add(i, div);
    }
}

onClick(three);

使用scheduler.yield(),執行時間減少到約5646毫秒,顯著優于setTimeout()方法。

scheduler.yield()的優勢

  1. 更高的性能:執行時間更接近于未中斷的任務。
  2. 優先級處理:被暫停的任務被放置在隊列頭部,而不是末尾。

示例比較:

// 同時執行兩個three()函數
onClick(() => Promise.race([three(div), three(div2)]));

// three()與setTimeout()基于的two()比較
onClick(() => Promise.race([three(div), two(div2)]));

結果與上述基于setTimeout()的index4.html的不同之處僅在于執行時間。10183 毫秒相當于兩次 5645 毫秒。兩個任務似乎都沒有優先級。

優先級似乎不起作用,因為兩個函數three()都不在隊列中等待。但看看這個:


在與setTimeout()基于的方法比較時,scheduler.yield()顯示出明顯的優先級優勢。

結語

scheduler.yield()為JavaScript中的任務調度提供了一個強大的新工具。它不僅性能更優,還能更好地處理任務優先級。對于需要處理長時間運行任務的前端開發者來說,這是一個值得關注和采用的新技術。

在實際應用中,開發者可以考慮在處理大量數據處理、復雜計算或頻繁DOM操作等場景時使用scheduler.yield()。這將有助于保持頁面的響應性,同時不會顯著影響任務的執行效率。隨著瀏覽器支持的增加,scheduler.yield()有望成為前端性能優化的重要工具。


該文章在 2024/10/19 12:30:12 編輯過
關鍵字查詢
相關文章
正在查詢...
點晴ERP是一款針對中小制造業的專業生產管理軟件系統,系統成熟度和易用性得到了國內大量中小企業的青睞。
點晴PMS碼頭管理系統主要針對港口碼頭集裝箱與散貨日常運作、調度、堆場、車隊、財務費用、相關報表等業務管理,結合碼頭的業務特點,圍繞調度、堆場作業而開發的。集技術的先進性、管理的有效性于一體,是物流碼頭及其他港口類企業的高效ERP管理信息系統。
點晴WMS倉儲管理系統提供了貨物產品管理,銷售管理,采購管理,倉儲管理,倉庫管理,保質期管理,貨位管理,庫位管理,生產管理,WMS管理系統,標簽打印,條形碼,二維碼管理,批號管理軟件。
點晴免費OA是一款軟件和通用服務都免費,不限功能、不限時間、不限用戶的免費OA協同辦公管理系統。
Copyright 2010-2024 ClickSun All Rights Reserved