成人国产在线小视频_日韩寡妇人妻调教在线播放_色成人www永久在线观看_2018国产精品久久_亚洲欧美高清在线30p_亚洲少妇综合一区_黄色在线播放国产_亚洲另类技巧小说校园_国产主播xx日韩_a级毛片在线免费

資訊專欄INFORMATION COLUMN

精讀《Scheduling in React》

LeexMuller / 776人閱讀

摘要:調度系統(tǒng),支持不同渲染優(yōu)先級,對進行調度。調度帶來的限制調度系統(tǒng)也存在兩個問題。調度系統(tǒng)能力有限,只能在瀏覽器提供的能力范圍內進行調度,而無法影響比如的渲染回收周期。精讀關于調度系統(tǒng)的剖析,可以讀深入剖析這篇文章,感謝我們團隊的淡蒼提供。

1. 引言

這次介紹的文章是 scheduling-in-react,簡單來說就是 React 的調度系統(tǒng),為了得到更順滑的用戶體驗。

畢竟前端做到最后,都是體驗優(yōu)化,前端帶給用戶的價值核心就在于此。

2. 概述

文章從 Dan 在 JSConf 提到的 Demo 說起:

這是一個測試性能的 Demo,隨著輸入框字符的增加,下方圖表展示的數(shù)據(jù)量會急速提升。在 Synchronous 與 Debounced 模式下的效果都不盡如人意,只有 Concurrent 模式下看起來是順暢的。

那么為什么普通的 Demo 會很卡呢?

這就涉及到瀏覽器 Event Loop 規(guī)則了。

JS 是單線程的,瀏覽器同一時間只能做一件事情,而肉眼能識別的刷新頻率在 60FPS 左右,這意味著我們需要在 16ms 之內完成 Demo 中的三件事:響應用戶輸入,做動畫,Dom 渲染。

然而目前幾乎所有框架都使用同步渲染模式,這意味著如果一個渲染函數(shù)執(zhí)行時間超過了 16ms,則不可避免的發(fā)生卡頓。

總結一下有兩個主要問題:

長時間運行的任務造成頁面卡頓,我們需要保證所有任務能在幾毫秒內完成,這樣才能保證頁面的流暢。

不同任務優(yōu)先級不同,比如響應用戶輸入的任務優(yōu)先級就高于動畫。這個很好理解。

React 調度機制

為了解決這個問題,React16 通過 Concurrent(并行渲染) 與 Scheduler(調度)兩個角度解決問題:

Concurrent: 將同步的渲染變成可拆解為多步的異步渲染,這樣可以將超過 16ms 的渲染代碼分幾次執(zhí)行。

Scheduler: 調度系統(tǒng),支持不同渲染優(yōu)先級,對 Concurrent 進行調度。當然,調度系統(tǒng)對低優(yōu)先級任務會不斷提高優(yōu)先級,所以不會出現(xiàn)低優(yōu)先級任務總得不到執(zhí)行的情況。

為了保證不產(chǎn)生阻塞的感覺,調度系統(tǒng)會將所有待執(zhí)行的回調函數(shù)存在一份清單中,在每次瀏覽器渲染時間分片間盡可能的執(zhí)行,并將沒有執(zhí)行完的內容 Hold 住留到下個分片處理。

Concurrent 的正式 API 會在 2019 Q2 發(fā)布,現(xiàn)在可以通過 API 方式調用:

ReactDOM.render(
  
    
  ,
  rootElement
);

只申明這個是不夠的,因為我們還沒有申明各函數(shù)執(zhí)行的優(yōu)先級。我們可以通過 npm i scheduler 包來申明函數(shù)的優(yōu)先級:

import { unstable_next } from "scheduler";

function SearchBox(props) {
  const [inputValue, setInputValue] = React.useState();

  function handleChange(event) {
    const value = event.target.value;

    setInputValue(value);
    unstable_next(function() {
      props.onChange(value);
      sendAnalyticsNotification(value);
    });
  }

  return ;
}

unstable_next() 作用域下的代碼優(yōu)先級是 Normal,那么產(chǎn)生的效果是:

如果 props.onChange(value) 可以在 16ms 內執(zhí)行完,則與不使用 unstable_next 沒有區(qū)別。

如果 props.onChange(value) 的執(zhí)行時間過長,可能這個函數(shù)會在下次幾次的 Render 中陸續(xù)執(zhí)行,不會阻塞后續(xù)的高優(yōu)先級任務。

調度帶來的限制

調度系統(tǒng)也存在兩個問題。

調度系統(tǒng)只能有一個,如果同時存在兩個調度系統(tǒng),就無法保證調度正確性。

調度系統(tǒng)能力有限,只能在瀏覽器提供的能力范圍內進行調度,而無法影響比如 Html 的渲染、回收周期。

為了解決這個問題,Chrome 正在與 React、Polymer、Ember、Google Maps、Web Standars Community 共同創(chuàng)建一個 瀏覽器調度規(guī)范,提供瀏覽器級別 API,可以讓調度控制更底層的渲染時機,也保證調度器的唯一性。

3. 精讀

關于 React 調度系統(tǒng)的剖析,可以讀 深入剖析 React Concurrent 這篇文章,感謝我們團隊的 淡蒼 提供。

簡單來說,一次 Render 一般涉及到許多子節(jié)點,而 Fiber 架構在 Render 階段可以暫停,一個一個節(jié)點的執(zhí)行,從而實現(xiàn)了調度的能力。

React 調度能力的限制
這意味著,如果你的 React 應用目前是流暢的,開啟 Concurrent 并不會對你的應用帶來性能體驗上的提升,如果你的 React 應用目前是卡頓的,或者在某些場景下是卡頓的,那么 Concurrent 或許可以挽救你一下,帶來一些改變。

正如《深入剖析 React Concurrent》一文提到的,如果你的應用沒有性能問題,就不要指望 React 調度能力有所幫助了。

這也是在說,如果一段代碼邏輯不存在性能問題,就不需要使用 Concurrent 優(yōu)化,因為這種優(yōu)化是無效的。我們需要能分辨哪些邏輯需要優(yōu)化,哪些邏輯不要。

從現(xiàn)在開始嘗試 Function Component

為了配合 React Schedule 的實現(xiàn),學會使用 Function Component 模式編寫組件是很重要的,因為:

Class Component 的生命周期概念阻礙了 React 調度系統(tǒng)對任務的拆分。

調度系統(tǒng)可能對 componentWillMount 重復調用,使得 Class Component 模式下很容易寫出錯誤的代碼。

Function Component 遵循了更嚴格的副作用分離,這使得 Concurrent 執(zhí)行過程不會引發(fā)意外效果。

React.lazy

與 Concurrent 一起發(fā)布的,還有 React 組件動態(tài) import 與載入方案。正常的組件載入是這樣的:

import OtherComponent from "./OtherComponent";

function MyComponent() {
  return (
    
); }

但如果使用了 import() 動態(tài)載入,可以使用 React.lazy 讓動態(tài)引入的組件像普通組件一樣被使用:

const OtherComponent = React.lazy(() => import("./OtherComponent"));

function MyComponent() {
  return (
    
); }

如果要加入 Loading,就可以配合 Suspense 一起使用:

import React, { lazy, Suspense } from "react";
const OtherComponent = lazy(() => import("./OtherComponent"));

function MyComponent() {
  return (
    Loading...
}> ); }

和 Concurrent 類似,React.lazy 方案也是一種對性能有益的組件加載方案。

調度分類

調度分 4 個等級:

Immediate:立即執(zhí)行,最高優(yōu)先級。

render-blocking:會阻塞渲染的優(yōu)先級,優(yōu)先級類似 requestAnimationFrame。如果這種優(yōu)先級任務不能被執(zhí)行,就可能導致 UI 渲染被 block。

default:默認優(yōu)先級,普通的優(yōu)先級。優(yōu)先級可以理解為 setTimeout(0) 的優(yōu)先級。

idle:比如通知等任務,用戶看不到或者不在意的。

目前建議的 API 類似如下:

function mytask() {
  ...
}

myQueue = TaskQueue.default("render-blocking")

先創(chuàng)建一個執(zhí)行隊列,并設置隊列的優(yōu)先級。

taskId = myQueue.postTask(myTask, );

再提交隊列,拿到當前隊列的執(zhí)行 id,通過這個 id 可以判斷隊列何時執(zhí)行完畢。

myQueue.cancelTask(taskId);

必要的時候可以取消某個函數(shù)的執(zhí)行。

4. 總結

隨著 Hooks 的發(fā)布,即將到來的 Concurrent 與 Suspense 你是否準備好了呢?

筆者希望大家一起思考,這三種 API 會給前端開發(fā)帶來什么樣的改變?歡迎留言!

討論地址是:精讀《Scheduling in React》 · Issue #146 · dt-fe/weekly

如果你想?yún)⑴c討論,請 點擊這里,每周都有新的主題,周末或周一發(fā)布。前端精讀 - 幫你篩選靠譜的內容。

關注 前端精讀微信公眾號

文章版權歸作者所有,未經(jīng)允許請勿轉載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。

轉載請注明本文地址:http://systransis.cn/yun/103529.html

相關文章

  • 精讀React 的多態(tài)性》

    摘要:引言本周精讀的文章是,看看作者是如何解釋這個多態(tài)性含義的。讀完文章才發(fā)現(xiàn),文章標題改為的多態(tài)性更妥當,因為整篇文章都在說,而使用場景不局限于。更多討論討論地址是精讀的多態(tài)性如果你想?yún)⑴c討論,請點擊這里,每周都有新的主題,周末或周一發(fā)布。 1 引言 本周精讀的文章是:surprising-polymorphism-in-react-applications,看看作者是如何解釋這個多態(tài)性含...

    tabalt 評論0 收藏0
  • 精讀《Caches API》

    摘要:引言這個是針對的。一般結合使用,因為請求級別的緩存與具有頁面攔截功能的最配。本周精讀的文章是,介紹了瀏覽器緩存接口的基本語法。包含任意命名空間,可以通過創(chuàng)建或訪問。精讀筆者利用實現(xiàn)了純?yōu)g覽器端的后端渲染。前端精讀幫你篩選靠譜的內容。 1 引言 caches 這個 API 是針對 Request Response 的。caches 一般結合 Service Worker 使用,因為請求級...

    Null 評論0 收藏0
  • 精讀《Vue3.0 Function API》

    摘要:拿到的都是而不是原始值,且這個值會動態(tài)變化。精讀對于的與,筆者做一些對比。因此采取了作為優(yōu)化方案只有當?shù)诙€依賴參數(shù)變化時才返回新引用。不需要使用等進行性能優(yōu)化,所有性能優(yōu)化都是自動的。前端精讀幫你篩選靠譜的內容。 1. 引言 Vue 3.0 的發(fā)布引起了軒然大波,讓我們解讀下它的 function api RFC 詳細了解一下 Vue 團隊是怎么想的吧! 首先官方回答了幾個最受關注的...

    voyagelab 評論0 收藏0
  • 精讀react-easy-state 源碼》

    摘要:會自動觸發(fā)函數(shù)內回調函數(shù)的執(zhí)行。因此利用并將依賴置為使代碼在所有渲染周期內,只在初始化執(zhí)行一次。同時代碼里還對等公共方法進行了包裝,讓這些回調函數(shù)中自帶效果。前端精讀幫你篩選靠譜的內容。 1. 引言 react-easy-state 是個比較有趣的庫,利用 Proxy 創(chuàng)建了一個非常易用的全局數(shù)據(jù)流管理方式。 import React from react; import { stor...

    curlyCheng 評論0 收藏0
  • 精讀《Function VS Class 組件》

    摘要:未來可能成為官方之一。討論地址是精讀組件如果你想?yún)⑴c討論,請點擊這里,每周都有新的主題,周末或周一發(fā)布。前端精讀幫你篩選靠譜的內容。 1. 引言 為什么要了解 Function 寫法的組件呢?因為它正在變得越來越重要。 那么 React 中 Function Component 與 Class Component 有何不同? how-are-function-components-di...

    FWHeart 評論0 收藏0

發(fā)表評論

0條評論

LeexMuller

|高級講師

TA的文章

閱讀更多
最新活動
閱讀需要支付1元查看
<