即使忘了 JavaScript 的一切知識,也不會忘記:它是阻塞的。
想像一下,你的瀏覽器裡住著一個魔法小精靈,負責瀏覽器的正常運作。不論渲染 HTML,回應選單指令,螢幕渲染,處理滑鼠點擊,或執行 JavaScript 函數,所有事情都歸一個小精靈處理。它哪忙得過來,一次只能處理一件事情。如果同時丟給它一堆任務,它會列出一個長長的待辦列表,按順序完成它們。
人們常常希望初始化元件和事件處理的 JavaScript 可以盡快執行。可是,有些較不重要的後台任務不會直接影響使用者體驗,例如:
記錄統計
發送資料到社群網路(或新增『分享'按鈕)
預先載入內容
預處理或預先渲染 HTML
他們對時序要求不嚴格,但是為了讓頁面仍然回應,直到使用者捲動頁面或與內容互動時才執行。
選擇之一是 Web Workers ,它可以在獨立的執行緒同時執行程式碼。用於預先載入和預處理再好不過,但是你沒有權限直接存取或更新 DOM。你可以在自己的程式碼中避開這一點,但是無法保證第三方腳本例如 Google Analytics 永遠不需要這個。
另一個選擇是setTimeout,例如setTimeout(doSomething, 1);。一旦其它的立即執行任務執行完畢,瀏覽器將執行doSomething()函數。實際上,它被放到了待辦清單的底部。不幸的是,函數將被調用,而不顧處理需求。
#requestIdleCallback
requestIdleCallback 是新API,當瀏覽器稍作喘息的時候,用來執行不太重要的後台排程任務。 難免讓人想起 requestAnimationFrame ,在下次重繪之前,執行函數更新動畫。 想了解更多戳這裡: 使用 requestAnimationFrame 做簡單的動畫 。
requestIdleCallback特性監控:
1 2 3 4 5 6 7 8 9 10 |
|
也可以指定配置參數對象,例如 timeout,
1 |
|
確保函數在3秒內調用,不管瀏覽器是否空閒。
deadline物件傳入下列參數時,requestIdleCallback只執行一次回呼:
didTimeout—— 如果可選的 timeout 觸發,則設定為 true
timeRemaining()—— 函數傳回執行任務剩餘的毫秒數
timeRemaining()最多分配50ms用於任務的執行,超過這個限制,也不會停止任務,但是,最好重新呼叫requestIdleCallback安排進一步的處理。
我們來建立一個簡單的例子,讓幾個任務依序執行。任務的函數引用儲存在數組中:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 |
|
#一次 requestIdleCallback 之間不應該做什麼?
Paul Lewis 在 他的文章 中提到,一次 requestIdleCallback 執行的任務應該切成小塊。它不適用於不可預測時間的情況(例如操作 DOM,使用 requestAnimationFrame 回呼會更好)。 resolving(或 rejecting)Promises 時也要謹慎,即使沒有更多的剩餘時間,空閒回調完成之後,回呼函數也會立即執行。
#requestIdleCallback 瀏覽器支援狀況
requestIdleCallback是試驗性特性,規格仍不穩定,碰到 API 變更時不足為奇。 Chrome 47 已支援… 2015年結束前應該可用了。 Opera 應該會跟上。 Microsoft 和 Mozilla 都在考慮 API 是否應該支援 Promises 。 Apple 像往常一樣不鳥。
Paul Lewis(上文提到的)寫了一個簡單的 requestIdleCallback shim ,它可以模擬瀏覽器的空閒監測行為,但不是一個 polyfill( shim 和 polyfill 的區別 )。
requestIdleCallback shim程式碼如下:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 |
|
ps: How to run a scheduled task
1. Run GPEDIT.MSC
2. Select computer configuration
--- Windows Settings
Security settings
—Local Strategy
—-User Rights Assignment
Double-click Access this computer from the network on the right
Add the required usernames to the list.
3. --- Security settings
---Safe choice
Turn on Allow server operators to schedule tasks
4.-----Local strategy
--- Log in as a batch job
Add the required usernames to the list.
5.-----Local strategy
--- Allow computers and users to be trusted for delegation
Add the required usernames to the list.
It is best to be the administrator user.
If the task plan cannot be started, prompt code: 0X80041315
Solution: There are two possibilities. One is that the "Task Scheduler" service in the system is not started. You can type "services.msc" during operation to check whether the "Task Scheduler" service is set to "Already set". Disabled", if so, just double-click it to change the startup type to "Automatic", reset a scheduled task and it can be executed.
If your current account is set to automatically log in, and its login password is empty, it may also cause the task plan to not be executed on time. In XP Professional Edition, you need to run "gpedit.msc" to edit the group policy: expand "Computer" Configuration→Windows Settings→Security Settings→Local Computer Policy→Security Options"; double-click the "Accounts: Local accounts with blank passwords only allow console login" item on the right, and select "Disabled" in the pop-up dialog box.