- 資訊首頁(yè) > 開(kāi)發(fā)技術(shù) > web開(kāi)發(fā) > JavaScript >
- React 并發(fā)功能體驗(前端的并發(fā)模式)
React 是一個(gè)開(kāi)源 JavaScript 庫,開(kāi)發(fā)人員使用它來(lái)創(chuàng )建基于 Web 和移動(dòng)的應用程序,并且支持構建交互式用戶(hù)界面和 UI 組件。React 是由 Facebook 軟件工程師 Jordan Walke 創(chuàng )建,React 的第一個(gè)版本在七年前問(wèn)世,現在,Facebook 負責維護。React框架自首次發(fā)布以來(lái),React 的受歡迎程度直線(xiàn)飆升,熱度不減。
2020 年 10 月,React 17 發(fā)布了,但令人驚訝的是——“零新功能”。當然,這并不是真的表示沒(méi)有任何新添加的功能,讓廣大程序員使用者興奮。事實(shí)上,這個(gè)版本為我們帶來(lái)了很多重大功能的升級及16版本的bug修復,并推出了:Concurrent Mode 和Suspense。
雖然這兩個(gè)功能尚未正式發(fā)布,這些功能已提供給開(kāi)發(fā)人員進(jìn)行測試。一旦發(fā)布,它們將改變 React 呈現其 UI 的方式,從而達到雙倍提高性能和用戶(hù)體驗。
簡(jiǎn)要說(shuō)明, Concurrent Mode 和Suspense 可以使用戶(hù)無(wú)縫處理數據加載,加載狀態(tài),用戶(hù)界面操作更加平滑和無(wú)縫切換。 在Concurrent Mode 下,React可以暫停高消耗的,非緊急的組件的渲染,并聚焦在更加緊迫的任務(wù)處理,如UI 渲染,始終保持應用為可響應式,避免白屏,卡頓等現象。
本文主要分享深入了解Concurrent Mode 和Suspense 模式下的數據提取功能。
眾所周知,JavaScript 框架或庫是單線(xiàn)程的工作。因此,當一個(gè)代碼塊運行時(shí),其余的塊必須等待執行。無(wú)法并發(fā)執行多線(xiàn)程工作。界面渲染也是一樣的。
一旦 React 開(kāi)始渲染某些東西,無(wú)法中斷直到運行完成。React 開(kāi)發(fā)人員將這種渲染稱(chēng)為“阻塞渲染”。 這種阻塞渲染會(huì )創(chuàng )建一個(gè)不穩定的用戶(hù)界面,并且隨時(shí)可能停止響應。
假如,我們需要顯示一個(gè)很長(cháng)的可選列表用于過(guò)濾產(chǎn)品的應用程序。我們使用搜索框用于過(guò)濾記錄,設計方案是當用戶(hù)點(diǎn)擊搜索按鈕后,用戶(hù)界面需要重新刷新列出相關(guān)聯(lián)的數據。
如果列表過(guò)長(cháng),數據過(guò)多,UI“卡頓”,即渲染對用戶(hù)可見(jiàn)。這種卡頓也會(huì )大大降低產(chǎn)品性能。開(kāi)發(fā)人員可以使用一些技術(shù),如節流和防抖,這些技術(shù)會(huì )有一定幫助,但不是完美的解決方案。
節流限制特定函數被調用的次數。使用節流,我們可以避免重復調用昂貴和耗時(shí)的API或函數。這個(gè)過(guò)程能夠提高性能,尤其是在用戶(hù)界面上呈現信息。
防抖會(huì )在預定的時(shí)間內忽略對函數的調用。函數調用僅在經(jīng)過(guò)預定時(shí)間后進(jìn)行。
下圖描述了卡頓現象:
在等待非緊急 API 調用完成時(shí),UI 卡頓,從而阻止呈現用戶(hù)界面。解決方案是使用并發(fā)模式進(jìn)行可中斷渲染。
通過(guò)可中斷渲染,React.js 在處理和重新渲染列表時(shí)不會(huì )阻塞 UI。它通過(guò)暫?,嵥榈墓ぷ?、更新 DOM 并確保 UI 不會(huì )卡頓,使 React.js 更加細化。React 使用用戶(hù)輸入并行更新或重繪輸入框。React 使用用戶(hù)輸入并重繪輸入框并行執行。它還更新內存中的列表。React 完成更新后,它會(huì )更新 DOM 并在用戶(hù)的顯示器上重新呈現列表。本質(zhì)上,無(wú)中斷渲染使 React 能夠“多任務(wù)”。此功能提供了更流暢的 UI 體驗。
并發(fā)模式是一組功能,可幫助 React 應用程序保持響應并平滑地適應用戶(hù)的設備和網(wǎng)絡(luò )速度能力。并發(fā)模式將其擁有的任務(wù)劃分為更小的塊。 React 的調度程序可以挑選并選擇要執行的作業(yè)。作業(yè)的調度取決于它們的優(yōu)先級。通過(guò)對任務(wù)進(jìn)行優(yōu)先級排序,它可以停止瑣碎或不緊急的事情,或者進(jìn)一步推動(dòng)它們。 React 始終將用戶(hù)界面更新和渲染放在首位。
使用并發(fā)模式,我們可以:
隨著(zhù) UI 渲染,并發(fā)模式改進(jìn)了對傳入數據的響應,懶加載控件,異步處理過(guò)程。并發(fā)模式保證了用戶(hù)界面始終處于激活狀態(tài),并且持續在后臺更新數據,并發(fā)模式也始終使用React 的兩個(gè)鉤掛:useTransition
和useDeferredValue
使用useDeferredValue Hook
useDeferredValue Hook
的定義如下:
const deferredValue = useDeferredValue(value, { timeoutMs: <some value> });
此命令設置值在timeoutMs
中設置的時(shí)間后“滯后”。 用戶(hù)界面是必須立即更新還是必須等待數據,該命令使用戶(hù)界面保持激活狀態(tài)和響應性,該Hook避免了 UI 卡頓,并始終保持用戶(hù)界面響應,以保持獲取數據滯后的較小成本。
useTransition Hook
是React
中主要用于掛起的Hook
,假設這樣的場(chǎng)景下:其中有一個(gè)帶有用戶(hù)名按鈕的網(wǎng)頁(yè)。只需點(diǎn)擊一個(gè)按鈕,網(wǎng)頁(yè)就會(huì )在屏幕上顯示用戶(hù)的詳細信息。
假設用戶(hù)首先單擊一個(gè)按鈕,然后單擊下一個(gè)。屏幕要么變成空白,要么我們在屏幕上看到一個(gè)微調器。如果獲取詳細信息花費的時(shí)間太長(cháng),用戶(hù)界面可能會(huì )凍結。
useTransition
方法返回兩個(gè)Hook
的值:startTransition
和 isPending
。定義的語(yǔ)法如下:
const [startTransition, isPending] = useTransition({ timeoutMs: 3000 });
startTransition
定義的語(yǔ)法:
<button disabled={isPending} startTransition(() => { <fetch Calls> }); </button> {isPending? " Loading...": null}
使用 useTransition
鉤子,React.js
繼續顯示沒(méi)有用戶(hù)詳細信息的用戶(hù)界面,直到用戶(hù)詳細信息準備好,但 UI 是響應式的。React
優(yōu)先考慮用戶(hù)界面,以在并行獲取數據時(shí)保持響應。
Suspense
是React
與并發(fā)模式一起引入的另一個(gè)實(shí)驗性功能。Suspense
使組件能夠在渲染前等待一段預定的時(shí)間。
Suspense
的主要作用是從組件異步讀取數據,而無(wú)需擔心數據的來(lái)源。Suspense
最適合延遲加載的概念。Suspense
允許數據獲取庫通知React
數據組件是否可以使用。在必要的組件準備就緒之前,React
不會(huì )更新 UI。
使用Suspense
的好處:
1.數據獲取庫和React
組件之間的集成
2.控制視覺(jué)加載狀態(tài)
3.避免競爭條件
Spinner
組件的基本語(yǔ)法如下:
import Spinner from './Spinner'; <Suspense fallback={<Spinner />}> <SomeComponent /> </Suspense>
Concurrent Mode
中使用的Suspense
允許耗時(shí)的組件在等待數據的同時(shí)開(kāi)始渲染。同時(shí)顯示占位符。這種組合產(chǎn)生了更流暢的UI體驗。
React.lazy
是一個(gè)新功能,它使React.js
能夠延遲加載組件。懶加載意味著(zhù)僅在需要時(shí)才加載組件(檢索和呈現它們的代碼)。他們會(huì )優(yōu)先考慮最關(guān)鍵的用戶(hù)界面組件。React
開(kāi)發(fā)人員建議將懶加載組件包裝在Suspense
組件中。
這樣做可確保組件在渲染時(shí)不會(huì )出現“不良狀態(tài)”。用戶(hù)界面在整個(gè)過(guò)程中保持響應,并帶來(lái)更流暢的用戶(hù)體驗。
啟用并發(fā)模式
要啟用并發(fā)模式,請安裝最新的測試版本。安裝 React 的先決條件是節點(diǎn)數據包管理器 (npm)。要安裝測試版本,請執行以下命令:
npm install react@experimental react-dom@experimental
要測試是否設置了測試版本,請創(chuàng )建一個(gè)示例 React 應用程序。沒(méi)有測試功能的渲染代碼如下:
import * as React from 'react'; import { render } from 'react-dom'; render(<App />, document.getElementById('root'));
并發(fā)模式的,具體代碼如下:
import * as React from 'react'; import { createRoot } from 'react-dom'; createRoot(document.getElementById('root')).render(<App />);
這將為整個(gè)應用程序啟用并發(fā)模式。React 將渲染調用分為兩部分:
目前,React 計劃維護三種模式:
阻塞模式是使用createBlockingRoot 調用來(lái)替換createRoot 調用,在并發(fā)模式的開(kāi)發(fā)情況下,阻塞模式為開(kāi)發(fā)者提供了機會(huì )來(lái)修復bug或解決問(wèn)題。
React 官方文檔中也說(shuō)明了每種模式支持的功能:
本文也創(chuàng )建了一個(gè)測試程序來(lái)驗證并發(fā)模式和其他模式的用法和效果。本文以像素應用為例在150*150的畫(huà)布上隨機分布像素并包含一個(gè)搜索框,每次用戶(hù)點(diǎn)擊搜索框時(shí)候,畫(huà)布會(huì )重新渲染自己。
即使UI 界面無(wú)法在并發(fā)模式下渲染,用戶(hù)輸入也不會(huì )停止更新。像素畫(huà)布在處理完成后重新渲染。在傳統模式下,快速鍵入時(shí),UI 會(huì )停止,有時(shí)會(huì )在再次渲染畫(huà)布之前停止。用戶(hù)輸入也會(huì )停止并且不會(huì )更新。
構建像素應用程序的主要文件是 canvas.js。我們還制作了一個(gè)輸入框,用戶(hù)可以在其中輸入任何內容。每次按下一個(gè)鍵都會(huì )重新渲染像素畫(huà)布。
代碼示例:Index.js
import React from "react"; import ReactDOM from "react-dom"; import App from "./App"; // Traditional or non-Concurrent Mode react const rootTraditional = document.getElementById("root"); ReactDOM.render(<App caption="Traditional or Block Rendering" />, rootTraditional); // Concurrent Mode enabled const rootConcurrent = document.getElementById("root-concurrent"); ReactDOM.createRoot(rootConcurrent).render(<App caption="Interruptible Rendering" />);
App.js
import React, { useState, useDeferredValue } from "react"; import "./App.css"; import { Canvas } from "./Canvas"; export default function App(props) { const [value, setValue] = useState(""); //This is available only in the Concurrent mode. const deferredValue = useDeferredValue(value, { timeoutMs: 5000 }); const keyPressHandler = e => { setValue(e.target.value); }; return ( <div className="App"> <h1>{props.caption}</h1> <input onKeyUp={keyPressHandler} /> <Canvas value={deferredValue} /> </div> ); }
Canvas.js
import React from "react"; const CANVAS_SIZE = 70; const generateRandomColor = () => { var letters = "0123456789ABCDEF"; var color = "#"; for (var i = 0; i < 6; i++) { color += letters[Math.floor(Math.random() * 16)]; } return color; }; const createCanvas = (rows, columns) => { let array = []; for (let i = 0; i < rows; i++) { let row = []; for (let j = 0; j < columns; j++) { row.push(0); } array.push(row); } return array; }; //This is the square with the pixels const drawCanvas = value => { const canvas = createCanvas(CANVAS_SIZE, CANVAS_SIZE); return canvas.map((row, rowIndex) => { let cellsArrJSX = row.map((cell, cellIndex) => { let key = rowIndex + "-" + cellIndex; return ( <div style={{ backgroundColor: generateRandomColor() }} className="cell" key={"cell-" + key} /> ); }); return ( <div key={"row-" + rowIndex} className="canvas-row"> {cellsArrJSX} </div> ); }); }; export const Canvas = ({ value }) => { return ( <div> <h2 style={{ minHeight: 30 }}>{value}</h2> <div className="canvas">{drawCanvas(value)}</div> </div> ); };
Index.html
<!DOCTYPE html> <html lang="en"> <head> <meta charset="utf-8" /> <meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no" /> <meta name="theme-color" content="#000000" /> <title>React App Concurrent Mode</title> </head> <body> <noscript> You need to enable JavaScript to run this app. </noscript> <div id="container"> <div id="root" class="column"></div> <div id="root-concurrent" class="column"></div> </div> </body> </html>
讓我們看看我們的代碼。我們看到的第一個(gè)屏幕是初始屏幕。使用傳統或塊渲染是現在React 的做法??芍袛噤秩臼遣l(fā)模式的測試功能。我們先看看傳統的渲染工作。
像素畫(huà)布在每次擊鍵時(shí)重新渲染。在傳統渲染中,整個(gè) UI 會(huì )在每次擊鍵時(shí)暫停,直到它可以重新渲染屏幕。在此期間,即使我們繼續打字,用戶(hù)輸入不會(huì )更新。
下圖顯示可中斷渲染。在可中斷渲染中,用戶(hù)可以繼續輸入。在為每次擊鍵并行重新渲染畫(huà)布時(shí),UI 不會(huì )停止或停止。
重新渲染完成后,React 會(huì )更新 UI。雖然在靜態(tài)截圖中很難看到,但我們可以看到網(wǎng)格在變化,但用戶(hù)仍然可以打字而不會(huì )出現 UI 卡頓的情況。
在本文中,我們研究了 React 的測試并發(fā)功能和 Suspense。使用并發(fā)模式,React.js 始終保持用戶(hù)界面響應。它將應用程序的任務(wù)分解為更小的塊,并允許對用戶(hù)界面任務(wù)進(jìn)行優(yōu)先級排序。因此,此模式可提供更流暢和無(wú)縫的用戶(hù)體驗,并提高應用程序的整體性能。
結合并發(fā)模式,Suspense 允許用戶(hù)界面保持響應。同時(shí),數據獲取等繁重耗時(shí)的任務(wù)可以并行完成,從而提供整體無(wú)縫體驗。
有關(guān)并發(fā)模式的完整詳細信息可在 React 官方文檔中了解。
隨著(zhù)React版本的改進(jìn), React框架越來(lái)越被更多的中國前端開(kāi)發(fā)者所熟知并且廣泛應用到他們的項目開(kāi)發(fā)中。是繼續Vue.js 后又一備受歡迎的前端主流框架,現在也因此衍生除了很多支持與React框架集成的功能工具, 如前端報表ActiveReportsJS控件,提供了與 React 直接集成的在線(xiàn)編輯器和報表展示工具,完善前端的數據展示功能。
到此這篇關(guān)于React 并發(fā)功能體驗-前端的并發(fā)模式已經(jīng)到來(lái)的文章就介紹到這了,更多相關(guān)React 并發(fā)功能內容請搜索腳本之家以前的文章或繼續瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
免責聲明:本站發(fā)布的內容(圖片、視頻和文字)以原創(chuàng )、來(lái)自本網(wǎng)站內容采集于網(wǎng)絡(luò )互聯(lián)網(wǎng)轉載等其它媒體和分享為主,內容觀(guān)點(diǎn)不代表本網(wǎng)站立場(chǎng),如侵犯了原作者的版權,請告知一經(jīng)查實(shí),將立刻刪除涉嫌侵權內容,聯(lián)系我們QQ:712375056,同時(shí)歡迎投稿傳遞力量。
Copyright ? 2009-2022 56dr.com. All Rights Reserved. 特網(wǎng)科技 特網(wǎng)云 版權所有 特網(wǎng)科技 粵ICP備16109289號
域名注冊服務(wù)機構:阿里云計算有限公司(萬(wàn)網(wǎng)) 域名服務(wù)機構:煙臺帝思普網(wǎng)絡(luò )科技有限公司(DNSPod) CDN服務(wù):阿里云計算有限公司 百度云 中國互聯(lián)網(wǎng)舉報中心 增值電信業(yè)務(wù)經(jīng)營(yíng)許可證B2
建議您使用Chrome、Firefox、Edge、IE10及以上版本和360等主流瀏覽器瀏覽本網(wǎng)站