AVt天堂网 手机版,亚洲va久久久噜噜噜久久4399,天天综合亚洲色在线精品,亚洲一级Av无码毛片久久精品

當前位置:首頁 > 科技  > 軟件

React 中,用到的幾種淺比較方式及其比較成本科普

來源: 責編: 時間:2024-04-22 09:12:16 150觀看
導讀開發中的絕大多數時候,我們并不需要關注 React 項目的性能問題。雖然我們在前面幾個章節中,也花了幾篇文章來分析如何優化 React 的性能體驗,但是這些知識點在開發過程中能用到的機會其實比較少。面試的時候用得比較多。

sBV28資訊網——每日最新資訊28at.com

開發中的絕大多數時候,我們并不需要關注 React 項目的性能問題。雖然我們在前面幾個章節中,也花了幾篇文章來分析如何優化 React 的性能體驗,但是這些知識點在開發過程中能用到的機會其實比較少。面試的時候用得比較多。sBV28資訊網——每日最新資訊28at.com

但是,當你的項目遇到性能瓶頸,如何優化性能就變得非常重要。當然,我們前面幾篇文章已經把性能優化的方式和方法說得非常清晰了,大家可以回顧一下。這篇文章我們要分享的重點是,當我采用不同的方式優化之后,代碼邏輯執行所要付出的代價到底如何。sBV28資訊網——每日最新資訊28at.com

例如,當我們得知 React 的 DIFF 是全量比較的時候,可能第一個反應就是覺得他性能差。但是具體性能差到什么程度呢?有沒有一個具體的數據來支撐?不確定,這只是一種主觀感受。優化之后的性能到底強不強呢,也不敢肯定。sBV28資訊網——每日最新資訊28at.com

因此,這篇文章主要給大家介紹幾種 react 在 diff 過程中用到的比較方式,以及當這幾種方式大量執行時,執行所要花費的時間。sBV28資訊網——每日最新資訊28at.com

一、對象直接比較

又稱為全等比較,這是一種成本最低的比較方式。在 React 中,state 與 props 的比較都會用到這樣的方式。sBV28資訊網——每日最新資訊28at.com

var prevProps = {}var nextProps = {}if (prevProps === nextProps) {  ...}

那么,這種比較方式的成本有多低呢?我們來寫一個循環簡單驗證一下。分別看看比較一萬次需要多長時間。sBV28資訊網——每日最新資訊28at.com

var markTime = performance.now()var prev = {}var next = {}for(var i = 0; i <= 10000; i++) {  if (prev === next) {    console.log('相等')  }}var endTime = performance.now()console.log(endTime - markTime)

執行結果會有小范圍波動,展示出來的結果都是取的多次執行的平均值,或者出現次數最多的執行結果。比如本案例執行,用時最短的是 0.3 ms,用時最長的是 0.8 ms。sBV28資訊網——每日最新資訊28at.com

可以看到,對比一萬次,用時約  0.6ms。sBV28資訊網——每日最新資訊28at.com

sBV28資訊網——每日最新資訊28at.com

對比一百萬次,用時約 6.4ms。sBV28資訊網——每日最新資訊28at.com

sBV28資訊網——每日最新資訊28at.com

通常情況下,我們項目的規模應該很難超過一萬次,控制得好一點,一般都在 1000 次以內。多一點也應該在 5000 次以內,5000 次用這種方式的對比只需要 0.3ms 左右。sBV28資訊網——每日最新資訊28at.com

二、Object.is

Object.is 是一種與全等比較相似但不同的比較方式,他們的區別就在于處理帶符號的 0 和 NaN 時結果不一樣。sBV28資訊網——每日最新資訊28at.com

+0 === -0 // trueObject.is(+0, -0) // falseNaN === NaN // falseObject.is(NaN, NaN) // true

React 源碼里為 Object.is 做了兼容處理,因此多了一點判斷,所以他的性能上會比全等要差一些。sBV28資訊網——每日最新資訊28at.com

function is(x, y) {  return (    (x === y && (x !== 0 || 1 / x === 1 / y)) || (x !== x && y !== y) // eslint-disable-line no-self-compare  );}const objectIs =  typeof Object.is === 'function' ? Object.is : is;

那么差多少呢?我們先寫一個邏輯來看一下執行一萬次比較需要多久。sBV28資訊網——每日最新資訊28at.com

function is(x, y) {  return (    (x === y && (x !== 0 || 1 / x === 1 / y)) || (x !== x && y !== y) // eslint-disable-line no-self-compare  );}const objectIs =  typeof Object.is === 'function' ? Object.is : is;var markTime = performance.now()var prev = {}var next = {}for(var i = 0; i <= 10000; i++) {  if (objectIs(prev, next)) {    console.log('相等')  }}var endTime = performance.now()console.log(endTime - markTime)

執行結果如下,大概是 0.8ms。sBV28資訊網——每日最新資訊28at.com

sBV28資訊網——每日最新資訊28at.com

執行一百萬次,用時約 11.4ms。sBV28資訊網——每日最新資訊28at.com

sBV28資訊網——每日最新資訊28at.com

那么我們的項目規模在 5000 次比較以內的話,用時估計在 0.4ms 左右,比全等比較多用了 0.1ms。sBV28資訊網——每日最新資訊28at.com

三、shallowEqual

這種淺比較的成本就稍微大一些,例如,當我們對子組件使用了 memo 包裹之后,那么在 diff 過程中,對于 props 的比較方式就會轉變成這樣方式,他們會遍歷判斷 props 第一層每一項子屬性是否相等。sBV28資訊網——每日最新資訊28at.com

function shallowEqual(objA: mixed, objB: mixed): boolean {  if (is(objA, objB)) {    return true;  }  if (    typeof objA !== 'object' ||    objA === null ||    typeof objB !== 'object' ||    objB === null  ) {    return false;  }  const keysA = Object.keys(objA);  const keysB = Object.keys(objB);  if (keysA.length !== keysB.length) {    return false;  }  // Test for A's keys different from B.  for (let i = 0; i < keysA.length; i++) {    const currentKey = keysA[i];    if (      !hasOwnProperty.call(objB, currentKey) ||      !is(objA[currentKey], objB[currentKey])    ) {      return false;    }  }  return true;}

首先,這種比較方式在 React 中出現的次數非常的少,只有我們手動新增了 memo 之后才會進行這種比較,因此,我們測試的時候,先以 1000 次為例看看結果。sBV28資訊網——每日最新資訊28at.com

我們定義兩個數量稍微多一點的 props 對象,他們最有最后一項不相同,因此比較的次數會拉滿。sBV28資訊網——每日最新資訊28at.com

var prev = {a:1, b: 1, c: 1, d: 1, e: 1, f: 1, g: 1}var next = {a:1, b: 1, c: 1, d: 1, e: 1, f: 1, g: 2}

完整代碼如下:sBV28資訊網——每日最新資訊28at.com

function is(x, y) {  return (    (x === y && (x !== 0 || 1 / x === 1 / y)) || (x !== x && y !== y) // eslint-disable-line no-self-compare  );}const objectIs =  typeof Object.is === 'function' ? Object.is : is;function shallowEqual(objA, objB) {  if (is(objA, objB)) {    return true;  }  if (    typeof objA !== 'object' ||    objA === null ||    typeof objB !== 'object' ||    objB === null  ) {    return false;  }  const keysA = Object.keys(objA);  const keysB = Object.keys(objB);  if (keysA.length !== keysB.length) {    return false;  }  // Test for A's keys different from B.  for (let i = 0; i < keysA.length; i++) {    const currentKey = keysA[i];    if (      !Object.hasOwnProperty.call(objB, currentKey) ||      !is(objA[currentKey], objB[currentKey])    ) {      return false;    }  }  return true;}var markTime = performance.now()var prev = {a:1, b: 1, c: 1, d: 1, e: 1, f: 1, g: 1}var next = {a:1, b: 1, c: 1, d: 1, e: 1, f: 1, g: 2}for(var i = 0; i <= 1000; i++) {  if (shallowEqual(prev, next)) {    console.log('相等')  }}var endTime = performance.now()console.log(endTime - markTime)

1000 次比較結果耗時如下,約為 1.4ms。sBV28資訊網——每日最新資訊28at.com

sBV28資訊網——每日最新資訊28at.com

5000 次比較結果耗時如下,約為 3.6ms。sBV28資訊網——每日最新資訊28at.com

sBV28資訊網——每日最新資訊28at.com

10000 次比較結果耗時如下,約為 6.6 ms。sBV28資訊網——每日最新資訊28at.com

sBV28資訊網——每日最新資訊28at.com

這里我們可以做一個簡單的調整,讓對比耗時直接少一半。那就是把唯一的變化量,寫到前面來,如圖所示,耗時只用了 3.1ms。sBV28資訊網——每日最新資訊28at.com

sBV28資訊網——每日最新資訊28at.com

運用到實踐中,就是把 props 中的變量屬性,盡量寫在前面,能夠大幅度提高對比性能。sBV28資訊網——每日最新資訊28at.com

四、總結

次數
sBV28資訊網——每日最新資訊28at.com

全等
sBV28資訊網——每日最新資訊28at.com

is
sBV28資訊網——每日最新資訊28at.com

shallow
sBV28資訊網——每日最新資訊28at.com

五千
sBV28資訊網——每日最新資訊28at.com

0.3
sBV28資訊網——每日最新資訊28at.com

0.4
sBV28資訊網——每日最新資訊28at.com

3.6
sBV28資訊網——每日最新資訊28at.com

一萬
sBV28資訊網——每日最新資訊28at.com

0.6
sBV28資訊網——每日最新資訊28at.com

0.8
sBV28資訊網——每日最新資訊28at.com

6.6
sBV28資訊網——每日最新資訊28at.com

百萬
sBV28資訊網——每日最新資訊28at.com

6.4
sBV28資訊網——每日最新資訊28at.com

11.4
sBV28資訊網——每日最新資訊28at.com

162
sBV28資訊網——每日最新資訊28at.com

因此我們從測試結果中看到,全量 diff 并不可怕,如果你對性能優化的理解非常到位,那么能你的項目中,全量 diff 所花費的時間只有 0.幾ms,理論的極限性能就是只在你更新的組件里對比出差異,執行 re-render。sBV28資訊網——每日最新資訊28at.com

當然,由于對于 React 內部機制的理解程度不同,會導致一些差異,例如有些同學的項目中,會執行過多的冗余 re-render。從而導致在大型項目中性能體驗可能出現問題。那么這種情況下,也不用擔心,有一種超級笨辦法,那就是在項目中,結合我們剛才在 shallowEqual 中提高的優化方案,無腦使用 useCallback 與 memo,你的項目性能就能得到明顯的提高,當然,這個方案不夠優雅但是管用。sBV28資訊網——每日最新資訊28at.com

可以看出,React 性能優化最重要的手段非常簡單:就是控制當前渲染內容的節點規模。sBV28資訊網——每日最新資訊28at.com

本文鏈接:http://www.tebozhan.com/showinfo-26-84462-0.htmlReact 中,用到的幾種淺比較方式及其比較成本科普

聲明:本網頁內容旨在傳播知識,若有侵權等問題請及時與本網聯系,我們將在第一時間刪除處理。郵件:2376512515@qq.com

上一篇: 利用RSA加密打造強大License驗證,確保軟件正版合法運行

下一篇: 針對尺寸單位,為什么不應該使用 px 作為尺寸單位?以及最佳實踐!

標簽:
  • 熱門焦點
Top