欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

解析React?中的Virtual?DOM

 更新時(shí)間:2022年01月29日 13:21:11   作者:?jiǎn)倘~葉  
React在前端界一直很流行,而且學(xué)起來(lái)也不是很難,只需要學(xué)會(huì)JSX、理解State和Props,然后就可以愉快的玩耍了,但想要成為React的專家你還需要對(duì)React有一些更深入的理解,對(duì)React??Virtual?DOM相關(guān)知識(shí)感興趣的朋友一起看看吧

React在前端界一直很流行,而且學(xué)起來(lái)也不是很難,只需要學(xué)會(huì)JSX、理解State和Props,然后就可以愉快的玩耍了,但想要成為React的專家你還需要對(duì)React有一些更深入的理解,希望本文對(duì)你有用。

React在前端界一直很流行,而且學(xué)起來(lái)也不是很難,只需要學(xué)會(huì)JSX、理解StateProps,然后就可以愉快的玩耍了,但想要成為React的專家你還需要對(duì)React有一些更深入的理解,希望本文對(duì)你有用。

這是Choerodon的一個(gè)前端頁(yè)面

在復(fù)雜的前端項(xiàng)目中一個(gè)頁(yè)面可能包含上百個(gè)狀態(tài),對(duì)React框架理解得更精細(xì)一些對(duì)前端優(yōu)化很重要。曾經(jīng)這個(gè)頁(yè)面點(diǎn)擊一條記錄展示詳情會(huì)卡頓數(shù)秒,而這僅僅是前端渲染造成的。

為了能夠解決這些問(wèn)題,開(kāi)發(fā)者需要了解React組件從定義到在頁(yè)面上呈現(xiàn)(然后更新)的整個(gè)過(guò)程。

React在編寫(xiě)組件時(shí)使用混合HTMLJavaScript的一種語(yǔ)法(稱為JSX)。 但是,瀏覽器對(duì)JSX及其語(yǔ)法一無(wú)所知,瀏覽器只能理解純JavaScript,因此必須將JSX轉(zhuǎn)換為HTML。 這是一個(gè)div的JSX代碼,它有一個(gè)類和一些內(nèi)容:

<div className='cn'>
  文本
</div>

在React中將這段jsx變成普通的js之后它就是一個(gè)帶有許多參數(shù)的函數(shù)調(diào)用:

React.createElement(
  'div',
  { className: 'cn' },
  '文本'
);
React.createElement(
  'div',
  { className: 'cn' },
  ['Content 1!', React.createElement('br'), 'Content 2!']
)
它的第一個(gè)參數(shù)是一個(gè)字符串,對(duì)應(yīng)html中的標(biāo)簽名,第二個(gè)參數(shù)是它的所有屬性所構(gòu)成的對(duì)象,當(dāng)然,它也有可能是個(gè)空對(duì)象,剩下的參數(shù)都是這個(gè)元素下的子元素,這里的文本也會(huì)被當(dāng)作一個(gè)子元素,所以第三個(gè)參數(shù)是 `“文本”` 。

到這里你應(yīng)該就能想象這個(gè)元素下有更多`children`的時(shí)候會(huì)發(fā)生什么。
```html
<div className='cn'>
  文本1
  <br />
  文本2
</div>
React.createElement(
  'div',
  { className: 'cn' },
  '文本1',              // 1st child
  React.createElement('br'), // 2nd child
  '文本1'               // 3rd child
)

目前的函數(shù)有五個(gè)參數(shù):元素的類型,全部屬性的對(duì)象和三個(gè)子元素。 由于一個(gè)child也是React已知的HTML標(biāo)簽,因此它也將被解釋成函數(shù)調(diào)用。

到目前為止,本文已經(jīng)介紹了兩種類型的child參數(shù),一種是string純文本,一種是調(diào)用其他的React.createElement函數(shù)。其實(shí),其他值也可以作為參數(shù),比如: - 基本類型 false,null,undefined和 true - 數(shù)組 - React組件

使用數(shù)組是因?yàn)榭梢詫⒆咏M件分組并作為一個(gè)參數(shù)傳遞:

當(dāng)然,React的強(qiáng)大功能不是來(lái)自`HTML`規(guī)范中描述的標(biāo)簽,而是來(lái)自用戶創(chuàng)建的組件,例如:

```js
function Table({ rows }) {
  return (
    <table>
      {rows.map(row => (
        <tr key={row.id}>
          <td>{row.title}</td>
        </tr>
      ))}
    </table>
  );
}

組件允許開(kāi)發(fā)者將模板分解為可重用的塊。在上面的“純函數(shù)”組件的示例中,組件接受一個(gè)包含表行數(shù)據(jù)的對(duì)象數(shù)組,并返回React.createElement對(duì)table元素及其行作為子元素的單個(gè)調(diào)用 。

每當(dāng)開(kāi)發(fā)者將組件放入JSX布局中時(shí)它看上去是這樣的:

<Table rows={rows} />

但從瀏覽器角度,它看到的是這樣的:

React.createElement(Table, { rows: rows });

請(qǐng)注意,這次的第一個(gè)參數(shù)不是以string描述的HTML元素,而是組件的引用(即函數(shù)名)。第二個(gè)參數(shù)是傳入該組件的props對(duì)象。

將組件放在頁(yè)面上

現(xiàn)在,瀏覽器已經(jīng)將所有JSX組件轉(zhuǎn)換為純JavaScript,現(xiàn)在瀏覽器獲得了一堆函數(shù)調(diào)用,其參數(shù)是其他函數(shù)調(diào)用,還有其他函數(shù)調(diào)用……如何將它們轉(zhuǎn)換為構(gòu)成網(wǎng)頁(yè)的DOM元素?

為此,開(kāi)發(fā)者需要使用ReactDOM庫(kù)及其render方法:

function Table({ rows }) { /* ... */ } // 組件定義

// 渲染一個(gè)組件
ReactDOM.render(
  React.createElement(Table, { rows: rows }), // "創(chuàng)建" 一個(gè) component
  document.getElementById('#root') // 將它放入DOM中
);

當(dāng)ReactDOM.render被調(diào)用時(shí),React.createElement最終也會(huì)被調(diào)用,它返回以下對(duì)象:

// 這個(gè)對(duì)象里還有很多其他的字段,但現(xiàn)在對(duì)開(kāi)發(fā)者來(lái)說(shuō)重要的是這些。
{
  type: Table,
  props: {
    rows: rows
  },
  // ...
}

這些對(duì)象構(gòu)成了React意義上的Virtual DOM

它們將在所有進(jìn)一步渲染中相互比較,并最終轉(zhuǎn)換為真正的DOM(與Virtual DOM對(duì)比)。

這是另一個(gè)例子:這次有一個(gè)div具有class屬性和幾個(gè)子節(jié)點(diǎn):

React.createElement(
  'div',
  { className: 'cn' },
  'Content 1!',
  'Content 2!',
);

變成:

{
  type: 'div',
  props: {
    className: 'cn',
    children: [
      'Content 1!',
      'Content 2!'
    ]
  }
}

所有的傳入的展開(kāi)函數(shù),也就是React.createElement除了第一第二個(gè)參數(shù)剩下的參數(shù)都會(huì)在props對(duì)象中的children屬性中,不管傳入的是什么函數(shù),他們最終都會(huì)作為children傳入props中。

而且,開(kāi)發(fā)者可以直接在JSX代碼中添加children屬性,將子項(xiàng)直接放在children中,結(jié)果仍然是相同的:

<div className='cn' children={['Content 1!', 'Content 2!']} />

在Virtual DOM對(duì)象被建立出來(lái)之后ReactDOM.render會(huì)嘗試按以下規(guī)則把它翻譯成瀏覽器能夠看得懂的DOM節(jié)點(diǎn): -如果Virtual DOM對(duì)象中的type屬性是一個(gè)string類型的tag名稱,創(chuàng)建一個(gè)tag,包含props里的全部屬性。 -如果Virtual DOM對(duì)象中的type屬性是一個(gè)函數(shù)或者class,調(diào)用它,它返回的可能還是一個(gè)Virtual DOM然后將結(jié)果繼續(xù)遞歸調(diào)用此過(guò)程。 -如果props中有children屬性,對(duì)children中的每個(gè)元素進(jìn)行以上過(guò)程,并將返回的結(jié)果放到父DOM節(jié)點(diǎn)中。

最后,瀏覽器獲得了以下HTML(對(duì)于上述table的例子):

<table>
  <tr>
    <td>Title</td>
  </tr>
  ...
</table>

重建DOM

接下瀏覽器要“重建”一個(gè)DOM節(jié)點(diǎn),如果瀏覽器要更新一個(gè)頁(yè)面,顯然,開(kāi)發(fā)者并不希望替換頁(yè)面中的全部元素,這就是React真正的魔法了。如何才能實(shí)現(xiàn)它?先從最簡(jiǎn)單的方法開(kāi)始,重新調(diào)用這個(gè)節(jié)點(diǎn)的ReactDOM.render方法。

// 第二次調(diào)用
ReactDOM.render(
  React.createElement(Table, { rows: rows }),
  document.getElementById('#root')
);

這一次,上面的代碼執(zhí)行邏輯將與看到的代碼不同。React不是從頭開(kāi)始創(chuàng)建所有DOM節(jié)點(diǎn)并將它們放在頁(yè)面上,React將使用“diff”算法,以確定節(jié)點(diǎn)樹(shù)的哪些部分必須更新,哪些部分可以保持不變。

那么它是怎樣工作的?只有少數(shù)幾個(gè)簡(jiǎn)單的情況,理解它們將對(duì)React程序的優(yōu)化有很大幫助。請(qǐng)記住,接下來(lái)看到的對(duì)象是用作表示React Virtual DOM中節(jié)點(diǎn)的對(duì)象。

▌Case 1:type是一個(gè)字符串,type在調(diào)用之間保持不變,props也沒(méi)有改變。

// before update
{ type: 'div', props: { className: 'cn' } }

// after update
{ type: 'div', props: { className: 'cn' } }

這是最簡(jiǎn)單的情況:DOM保持不變。

▌Case 2:type仍然是相同的字符串,props是不同的。

// before update:
{ type: 'div', props: { className: 'cn' } }

// after update:
{ type: 'div', props: { className: 'cnn' } }

由于type仍然代表一個(gè)HTML元素,React知道如何通過(guò)標(biāo)準(zhǔn)的DOM API調(diào)用更改其屬性,而無(wú)需從DOM樹(shù)中刪除節(jié)點(diǎn)。

▌Case 3:type已更改為不同的組件String或從String組件更改為組件。

// before update:
{ type: 'div', props: { className: 'cn' } }

// after update:
{ type: 'span', props: { className: 'cn' } }

由于React現(xiàn)在看到類型不同,它甚至不會(huì)嘗試更新DOM節(jié)點(diǎn):舊元素將與其所有子節(jié)點(diǎn)一起被刪除(unmount)。因此,在DOM樹(shù)上替換完全不同的元素的代價(jià)會(huì)非常之高。幸運(yùn)的是,這在實(shí)際情況中很少發(fā)生。

重要的是要記住React使用===(三等)來(lái)比較type值,因此它們必須是同一個(gè)類或相同函數(shù)的相同實(shí)例。

下一個(gè)場(chǎng)景更有趣,因?yàn)檫@是開(kāi)發(fā)者最常使用React的方式。

▌Case 4:type是一個(gè)組件。

// before update:
{ type: Table, props: { rows: rows } }

// after update:
{ type: Table, props: { rows: rows } }

你可能會(huì)說(shuō),“這好像沒(méi)有任何變化”,但這是不對(duì)的。

如果type是對(duì)函數(shù)或類的引用(即常規(guī)React組件),并且啟動(dòng)了樹(shù)diff比較過(guò)程,那么React將始終嘗試查看組件內(nèi)部的所有child以確保render的返回值沒(méi)有更改。即在樹(shù)下比較每個(gè)組件 - 是的,復(fù)雜的渲染也可能變得昂貴!

組件中的children

除了上面描述的四種常見(jiàn)場(chǎng)景之外,當(dāng)元素有多個(gè)子元素時(shí),開(kāi)發(fā)者還需要考慮React的行為。假設(shè)有這樣一個(gè)元素:

// ...
props: {
  children: [
      { type: 'div' },
      { type: 'span' },
      { type: 'br' }
  ]
},
// ...

開(kāi)發(fā)者開(kāi)發(fā)者想將它重新渲染成這樣(spandiv交換了位置):

// ...
props: {
  children: [
    { type: 'span' },
    { type: 'div' },
    { type: 'br' }
  ]
},
// ...

那么會(huì)發(fā)生什么?

當(dāng)React看到里面的任何數(shù)組類型的props.children,它會(huì)開(kāi)始將它中的元素與之前看到的數(shù)組中的元素按順序進(jìn)行比較:index 0將與index 0,index 1與index 1進(jìn)行比較,對(duì)于每對(duì)子元素,React將應(yīng)用上述規(guī)則集進(jìn)行比較更新。在以上的例子中,它看到div變成一個(gè)span這是一個(gè)情景3中的情況。但這有一個(gè)問(wèn)題:假設(shè)開(kāi)發(fā)者想要從1000行表中刪除第一行。React必須“更新”剩余的999個(gè)孩子,因?yàn)槿绻c先前的逐個(gè)索引表示相比,他們的內(nèi)容現(xiàn)在將不相等。

幸運(yùn)的是,React有一種內(nèi)置的方法來(lái)解決這個(gè)問(wèn)題。如果元素具有key屬性,則元素將通過(guò)key而不是索引進(jìn)行比較。只要key是唯一的,React就會(huì)移動(dòng)元素而不將它們從DOM樹(shù)中移除,然后將它們放回(React中稱為掛載/卸載的過(guò)程)。

// ...
props: {
  children: [ // 現(xiàn)在react就是根據(jù)key,而不是索引來(lái)比較了
    { type: 'div', key: 'div' },
    { type: 'span', key: 'span' },
    { type: 'br', key: 'bt' }
  ]
},
// ...

當(dāng)狀態(tài)改變時(shí)

到目前為止,本文只觸及了props,React哲學(xué)的一部分,但忽略了state。這是一個(gè)簡(jiǎn)單的“有狀態(tài)”組件:

class App extends Component {
  state = { counter: 0 }

  increment = () => this.setState({
    counter: this.state.counter + 1,
  })
  render = () => (<button onClick={this.increment}>
    {'Counter: ' + this.state.counter}
  </button>)
}

現(xiàn)在,上述例子中的state對(duì)象有一個(gè)counter屬性。單擊按鈕會(huì)增加其值并更改按鈕文本。但是當(dāng)用戶點(diǎn)擊時(shí),DOM會(huì)發(fā)生什么?它的哪一部分將被重新計(jì)算和更新?

調(diào)用this.setState也會(huì)導(dǎo)致重新渲染,但不會(huì)導(dǎo)致整個(gè)頁(yè)面重渲染,而只會(huì)導(dǎo)致組件本身及其子項(xiàng)。父母和兄弟姐妹都可以幸免于難。

修復(fù)問(wèn)題

本文準(zhǔn)備了一個(gè)DEMO,這是修復(fù)問(wèn)題前的樣子。你可以在這里查看其源代碼。不過(guò)在此之前,你還需要安裝React Developer Tools。

打開(kāi)demo要看的第一件事是哪些元素以及何時(shí)導(dǎo)致Virtual DOM更新。導(dǎo)航到瀏覽器的Dev Tools中的React面板,點(diǎn)擊設(shè)置然后選擇“Highlight Updates”復(fù)選框:

現(xiàn)在嘗試在表中添加一行。如你所見(jiàn),頁(yè)面上的每個(gè)元素周圍都會(huì)出現(xiàn)邊框。這意味著每次添加行時(shí),React都會(huì)計(jì)算并比較整個(gè)Virtual DOM樹(shù)?,F(xiàn)在嘗試按一行內(nèi)的計(jì)數(shù)器按鈕。你將看到Virtual DOM如何更新 (state僅相關(guān)元素及其子元素更新)。

React DevTools暗示了問(wèn)題可能出現(xiàn)的地方,但沒(méi)有告訴開(kāi)發(fā)者任何細(xì)節(jié):特別是有問(wèn)題的更新是指元素“diff”之后有不同,還是組件被unmount/mount了。要了解更多信息,開(kāi)發(fā)者需要使用React的內(nèi)置分析器(請(qǐng)注意,它不能在生產(chǎn)模式下工作)。

轉(zhuǎn)到Chrome DevTools中的“Performance”標(biāo)簽。點(diǎn)擊record按鈕,然后點(diǎn)擊表格。添加一些行,更改一些計(jì)數(shù)器,然后點(diǎn)擊“Stop”按鈕。稍等一會(huì)兒之后開(kāi)發(fā)者會(huì)看到:

在結(jié)果輸出中,開(kāi)發(fā)者需要關(guān)注“Timing”??s放時(shí)間軸,直到看到“React Tree Reconciliation”組及其子項(xiàng)。這些都是組件的名稱,旁邊有[update]或[mount]。可以看到有一個(gè)TableRow被mount了,其他所有的TableRow都在update,這并不是開(kāi)發(fā)者想要的。

大多數(shù)性能問(wèn)題都由[update]或[mount]引起

一個(gè)組件(以及組件下的所有東西)由于某種原因在每次更新時(shí)重新掛載,開(kāi)發(fā)者不想讓它發(fā)生(重新掛載很慢),或者在大型分支上執(zhí)行代價(jià)過(guò)大的重繪,即使組件似乎沒(méi)有發(fā)生任何改變。

修復(fù)mount/unmount

現(xiàn)在,當(dāng)開(kāi)發(fā)者了解React如何決定更新Virtual DOM并知道幕后發(fā)生的事情時(shí),終于準(zhǔn)備好解決問(wèn)題了!修復(fù)性能問(wèn)題首先要解決 mount/unmount。

如果開(kāi)發(fā)者將任何元素/組件的多個(gè)子元素在內(nèi)部表示為數(shù)組,那么程序可以獲得非常明顯的速度提升。

考慮一下:

<div>
  <Message />
  <Table />
  <Footer />
</div>

在虛擬DOM中,將表示為:

// ...
props: {
  children: [
    { type: Message },
    { type: Table },
    { type: Footer }
  ]
}
// ...

一個(gè)簡(jiǎn)單的Message組件(是一個(gè)div帶有一些文本,像是豬齒魚(yú)的頂部通知)和一個(gè)很長(zhǎng)的Table,比方說(shuō)1000多行。它們都是div元素的child,因此它們被放置在父節(jié)點(diǎn)的props.children之下,并且它們沒(méi)有key。React甚至不會(huì)通過(guò)控制臺(tái)警告來(lái)提醒開(kāi)發(fā)者分配key,因?yàn)樽庸?jié)點(diǎn)React.createElement作為參數(shù)列表而不是數(shù)組傳遞給父節(jié)點(diǎn)。

現(xiàn)在,用戶已經(jīng)關(guān)閉了頂部通知,所以Message從樹(shù)中刪除。TableFooter是剩下的child。

// ...
props: {
  children: [
    { type: Table },
    { type: Footer }
  ]
}
// ...

React如何看待它?它將它視為一系列改變了type的child:children[0]的type本來(lái)是Message,但現(xiàn)在他是Table。因?yàn)樗鼈兌际菍?duì)函數(shù)(和不同函數(shù))的引用,它會(huì)卸載整個(gè)Table并再次安裝它,渲染它的所有子代:1000多行!

因此,你可以添加唯一鍵(但在這種特殊情況下使用key不是最佳選擇)或者采用更智能的trick:使用 && 的布爾短路運(yùn)算,這是JavaScript和許多其他現(xiàn)代語(yǔ)言的一個(gè)特性。像這樣:

<div>
  {isShowMessage && <Message />}
  <Table />
  <Footer />
</div>

即使Message被關(guān)閉了(不再顯示),props.children父母div仍將擁有三個(gè)元素,children[0]具有一個(gè)值false(布爾類型)。還記得true/false,null甚至undefined都是Virtual DOM對(duì)象type屬性的允許值嗎?瀏覽器最終得到類似這樣的東西:

// ...
props: {
  children: [
    false, //  isShowMessage && <Message /> 短路成了false
    { type: Table },
    { type: Footer }
  ]
}
// ...

所以,不管Message是否被顯示,索引都不會(huì)改變,Table仍然會(huì)和Table比較,但僅僅比較Virtual DOM通常比刪除DOM節(jié)點(diǎn)并從中創(chuàng)建它們要快得多。

現(xiàn)在來(lái)看看更高級(jí)的東西。開(kāi)發(fā)者喜歡HOC。高階組件是一個(gè)函數(shù),它將一個(gè)組件作為一個(gè)參數(shù),添加一些行為,并返回一個(gè)不同的組件(函數(shù)):

function withName(SomeComponent) {
  return function(props) {
    return <SomeComponent {...props} name={name} />;
  }
}

開(kāi)發(fā)者在父render方法中創(chuàng)建了一個(gè)HOC 。當(dāng)React需要重新渲染樹(shù)時(shí),React的Virtual DOM將如下所示:

// On first render:
{
  type: ComponentWithName,
  props: {},
}

// On second render:
{
  type: ComponentWithName, // Same name, but different instance
  props: {},
}

現(xiàn)在,React只會(huì)在ComponentWithName上運(yùn)行一個(gè)diff算法,但是這次同名引用了一個(gè)不同的實(shí)例,三等于比較失敗,必須進(jìn)行完全重新掛載。注意它也會(huì)導(dǎo)致?tīng)顟B(tài)丟失,幸運(yùn)的是,它很容易修復(fù):只要返回的實(shí)例都是同一個(gè)就好了:

// 單例
const ComponentWithName = withName(Component);
class App extends React.Component() {
  render() {
    return <ComponentWithName />;
  }
}

修復(fù)update

現(xiàn)在瀏覽器已經(jīng)確保不會(huì)重新裝載東西了,除非必要。但是,對(duì)位于DOM樹(shù)根目錄附近的組件所做的任何更改都將導(dǎo)致其所有子項(xiàng)的進(jìn)行對(duì)比重繪。結(jié)構(gòu)復(fù)雜,價(jià)格昂貴且經(jīng)常可以避免。

如果有辦法告訴React不要查看某個(gè)分支,那將是很好的,因?yàn)樗鼪](méi)有任何變化。

這種方式存在,它涉及一個(gè)叫shouldComponentUpdate的組件生命周期函數(shù)。React會(huì)在每次調(diào)用組件之前調(diào)用此方法,并接收propsstate的新值。然后開(kāi)發(fā)者可以自由地比較新值和舊值之間的區(qū)別,并決定是否應(yīng)該更新組件(返回truefalse)。如果函數(shù)返回false,React將不會(huì)重新渲染有問(wèn)題的組件,也不會(huì)查看其子組件。

通常比較兩組propsstate一個(gè)簡(jiǎn)單的淺層比較就足夠了:如果頂層屬性的值相同,瀏覽器就不必更新了。淺比較不是JavaScript的一個(gè)特性,但開(kāi)發(fā)者很多方法來(lái)自己實(shí)現(xiàn)它,為了不重復(fù)造輪子,也可以使用別人寫(xiě)好的方法

在引入淺層比較的npm包后,開(kāi)發(fā)者可以編寫(xiě)如下代碼:

class TableRow extends React.Component {
  shouldComponentUpdate(nextProps, nextState) {
    const { props, state } = this;
    return !shallowequal(props, nextProps)
           && !shallowequal(state, nextState);
  }
  render() { /* ... */ }
}

但是你甚至不必自己編寫(xiě)代碼,因?yàn)镽eact在一個(gè)名為React.PureComponent的類中內(nèi)置了這個(gè)功能,它類似于React.Component,只是shouldComponentUpdate已經(jīng)為你實(shí)現(xiàn)了淺層props/state比較。

或許你會(huì)有這樣的想法,能替換ComponentPureComponent就去替換。但開(kāi)發(fā)者如果錯(cuò)誤地使用PureComponent同樣會(huì)有重新渲染的問(wèn)題存在,需要考慮下面三種情況:

<Table
    // map每次都會(huì)返回一個(gè)新的數(shù)組實(shí)例,所以每次比較都是不同的
    rows={rows.map(/* ... */)}
    // 每一次傳入的對(duì)象都是新的對(duì)象,引用是不同的。
    style={ { color: 'red' } }
    // 箭頭函數(shù)也一樣,每次都是不同的引用。
    onUpdate={() => { /* ... */ }}
/>

上面的代碼片段演示了三種最常見(jiàn)的反模式,請(qǐng)盡量避免它們!

正確地使用PureComponent,你可以在這里看到所有的TableRow都被“純化”后渲染的效果。

但是,如果你迫不及待想要全部使用純函數(shù)組件,這樣是不對(duì)的。比較兩組propsstate不是免費(fèi)的,對(duì)于大多數(shù)基本組件來(lái)說(shuō)甚至都不值得:運(yùn)行shallowCompare比diff算法需要更多時(shí)間。

可以使用此經(jīng)驗(yàn)法則:純組件適用于復(fù)雜的表單和表格,但它們通常會(huì)使按鈕或圖標(biāo)等簡(jiǎn)單元素變慢。

現(xiàn)在,你已經(jīng)熟悉了React的渲染模式,接下來(lái)就開(kāi)始前端優(yōu)化之旅吧。

到此這篇關(guān)于React 的 Virtual DOM的文章就介紹到這了,更多相關(guān)React 的 Virtual DOM內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

最新評(píng)論