国产av日韩一区二区三区精品,成人性爱视频在线观看,国产,欧美,日韩,一区,www.成色av久久成人,2222eeee成人天堂

characters

在內(nèi)部,React 使用幾種聰明的技術(shù)來最小化更新 UI 所需的昂貴 DOM 操作的數(shù)量。對于許多應(yīng)用程序而言,使用 React 將導(dǎo)致快速的用戶界面,而無需專門針對性能進(jìn)行優(yōu)化。不過,有幾種方法可以加速您的 React 應(yīng)用程序。

使用生產(chǎn)構(gòu)建

如果您在 React 應(yīng)用程序中進(jìn)行基準(zhǔn)測試或遇到性能問題,請確保您正在使用縮小的生產(chǎn)版本進(jìn)行測試。

默認(rèn)情況下,React 包含許多有用的警告。這些警告在開發(fā)中非常有用。但是,他們會使React變得越來越大,所以您應(yīng)該確保在部署應(yīng)用程序時使用生產(chǎn)版本。

如果您不確定您的構(gòu)建過程是否設(shè)置正確,可以通過安裝適用于 Chrome 的 React Developer Tools 進(jìn)行檢查。如果您在生產(chǎn)模式下使用 React 訪問網(wǎng)站,該圖標(biāo)將具有黑色背景:

如果您以開發(fā)模式訪問 React 網(wǎng)站,該圖標(biāo)將具有紅色背景:

預(yù)計(jì)在使用應(yīng)用程序時使用開發(fā)模式,在將應(yīng)用程序部署到用戶時使用生產(chǎn)模式。

您可以在下面找到有關(guān)為您的應(yīng)用生成應(yīng)用的說明。

創(chuàng)建 React App

如果您的項(xiàng)目是使用 Create React App 構(gòu)建的,請運(yùn)行:

npm run build

這將在build/您的項(xiàng)目文件夾中創(chuàng)建您的應(yīng)用程序的生產(chǎn)版本。

請記住,這只是在部署到生產(chǎn)之前需要的。對于正常的開發(fā),使用npm start。

單文件構(gòu)建

我們提供 React 和 React DOM 的生產(chǎn)就緒版本作為單個文件:

<script src="https://unpkg.com/react@16/umd/react.production.min.js"></script><script src="https://unpkg.com/react-dom@16/umd/react-dom.production.min.js"></script>

請記住,只有以結(jié)尾的 React 文件.production.min.js適用于生產(chǎn)。

分支

為了最有效的 Brunch 生產(chǎn)版本,安裝uglify-js-brunch插件:

# If you use npm
npm install --save-dev uglify-js-brunch

# If you use Yarn
yarn add --dev uglify-js-brunch

然后,要創(chuàng)建生產(chǎn)版本,請將-p標(biāo)志添加到build命令中:

brunch build -p

請記住,您只需要為生產(chǎn)構(gòu)建執(zhí)行此操作。你不應(yīng)該-p在開發(fā)中通過標(biāo)志或應(yīng)用這個插件,因?yàn)樗鼤[藏有用的 React 警告,并且使構(gòu)建慢得多。

Browserify

對于最高效的 Browserify 生產(chǎn)版本,安裝一些插件:

# If you use npm
npm install --save-dev envify uglify-js uglifyify 

# If you use Yarn
yarn add --dev envify uglify-js uglifyify

要創(chuàng)建生產(chǎn)版本,請確保您添加這些轉(zhuǎn)換(順序很重要)

  • envify變換確保正確的編譯環(huán)境設(shè)置。使其成為全球(-g)。

  • uglifyify轉(zhuǎn)換消除了開發(fā)導(dǎo)入。使它成為全局(-g)。

  • 最后,產(chǎn)生的束被傳送到束縛uglify-js(閱讀為什么)。

例如:

browserify ./index.js \  -g [ envify --NODE_ENV production ] \  -g uglifyify \  | uglifyjs --compress --mangle > ./bundle.js

注意:   包名稱是uglify-js,但它提供的二進(jìn)制文件被調(diào)用uglifyjs。這不是一個錯字。

請記住,您只需要為生產(chǎn)構(gòu)建執(zhí)行此操作。你不應(yīng)該在開發(fā)中應(yīng)用這些插件,因?yàn)樗鼈儠[藏有用的 React 警告,并使構(gòu)建更慢。

卷起

要獲得最高效的匯總生產(chǎn)版本,請安裝一些插件:

# If you use npm
npm install --save-dev rollup-plugin-commonjs rollup-plugin-replace rollup-plugin-uglify 

# If you use Yarn
yarn add --dev rollup-plugin-commonjs rollup-plugin-replace rollup-plugin-uglify

要創(chuàng)建生產(chǎn)版本,請確保您添加這些插件(該訂單很重要)

  • replace插件確保設(shè)置正確的構(gòu)建環(huán)境。

  • commonjs插件提供對 Rollup 中 CommonJS 的支持。

  • uglify插件壓縮和軋液最終束。

plugins: [  // ...  require('rollup-plugin-replace')({    'process.env.NODE_ENV': JSON.stringify('production')  }),  require('rollup-plugin-commonjs')(),  require('rollup-plugin-uglify')(),  // ...]

有關(guān)完整的設(shè)置示例,請參閱此要點(diǎn)。

請記住,您只需要為生產(chǎn)構(gòu)建執(zhí)行此操作。您不應(yīng)該在開發(fā)中將uglify插件或replace插件應(yīng)用于'production'值,因?yàn)樗鼈儠[藏有用的 React 警告,并且使構(gòu)建更慢。

WebPack

注意:   如果您使用 Create React App,請按照上述說明操作。本節(jié)僅與直接配置 webpack 有關(guān)。

要獲得最高效的 webpack 生產(chǎn)版本,請確保將這些插件包含在您的生產(chǎn)配置中:

new webpack.DefinePlugin({  'process.env.NODE_ENV': JSON.stringify('production')}),new webpack.optimize.UglifyJsPlugin()

你可以在 webpack 文檔中了解更多。

請記住,您只需要為生產(chǎn)構(gòu)建執(zhí)行此操作。你不應(yīng)該在開發(fā)中應(yīng)用UglifyJsPlugin或者DefinePlugin具有'production'價值,因?yàn)樗鼈儠[藏有用的React警告,并且使構(gòu)建變得更慢。

使用 Chrome 性能標(biāo)簽分析組件

開發(fā)模式中,您可以使用受支持的瀏覽器中的性能工具來可視化組件的安裝,更新和卸載方式。例如:

在 Chrome 中執(zhí)行此操作:

  1. 在查詢字符串中?react_perf加載您的應(yīng)用程序(例如,http://localhost:3000/?react_perf)。

  1. 打開 Chrome DevTools 性能選項(xiàng)卡并按下記錄。

  1. 執(zhí)行你想要分析的動作。記錄時間不要超過20秒,否則 Chrome 可能會掛起。

  1. 停止錄制。

5. 反應(yīng)事件將被分組在User Timing標(biāo)簽下。

請注意,這些數(shù)字是相對的,因此組件在生產(chǎn)中會呈現(xiàn)更快速度 不過,這應(yīng)該有助于您意識到不相關(guān)的用戶界面被錯誤更新的時間,以及用戶界面更新發(fā)生的頻率和頻率。

目前Chrome,Edge和IE是唯一支持此功能的瀏覽器,但我們使用標(biāo)準(zhǔn)的User Timing API,因此我們希望更多瀏覽器為其增加支持。

避免調(diào)節(jié)

React構(gòu)建并維護(hù)呈現(xiàn)的UI的內(nèi)部表示。它包含從組件返回的React元素。這種表示讓React避免了創(chuàng)建DOM節(jié)點(diǎn)和訪問現(xiàn)有的節(jié)點(diǎn),因?yàn)檫@可能比JavaScript對象上的操作慢。有時它被稱為“虛擬DOM”,但它在React Native上的工作方式相同。

當(dāng)組件的道具或狀態(tài)發(fā)生變化時,React通過比較新返回的元素和先前渲染的元素來決定是否需要實(shí)際的DOM更新。當(dāng)它們不相等時,React將更新DOM。

在某些情況下,您的組件可以通過重寫生命周期函數(shù)來加速所有這些,生命周期函數(shù)shouldComponentUpdate在重新呈現(xiàn)過程開始之前觸發(fā)。該函數(shù)的默認(rèn)實(shí)現(xiàn)返回true,使React執(zhí)行更新:

shouldComponentUpdate(nextProps, nextState) {  return true;}

如果你知道,在某些情況下,你的組件并不需要更新,您可以返回falseshouldComponentUpdate而是跳過整個渲染過程,包括調(diào)用render()此組件和下方。

shouldComponentUpdate In Action

這是一個組件的子樹。對于每一個,SCU指示shouldComponentUpdate返回的內(nèi)容,并vDOMEq指出呈現(xiàn)的React元素是否相同。最后,圓圈的顏色表示組件是否需要調(diào)和。

由于以C2為基礎(chǔ)的子樹shouldComponentUpdate返回false,因此React不會嘗試渲染C2,因此甚至不必shouldComponentUpdate在C4和C5上調(diào)用。

對于C1和C3,shouldComponentUpdate返回true,所以React必須下到葉子并檢查它們。對于shouldComponentUpdate返回的C6 true,由于渲染的元素不相同,React必須更新DOM。

最后一個有趣的案例是C8。React必須渲染這個組件,但是由于它返回的React元素與之前渲染的元素相同,所以它不必更新DOM。

請注意,React只需對C6進(jìn)行DOM突變,這是不可避免的。對于C8,它通過比較渲染的React元素和C2的子樹和C7來保護(hù),甚至不需要比較我們保存的元素shouldComponentUpdate,render也沒有調(diào)用。

示例

如果你的組件改變的唯一方式是當(dāng)變量props.colorstate.count變量發(fā)生變化時,你可以shouldComponentUpdate檢查:

class CounterButton extends React.Component {  constructor(props) {    super(props);    
    this.state = {count: 1};  }  shouldComponentUpdate(nextProps, nextState) {    if (this.props.color !== nextProps.color) {      
        return true;    }    if (this.state.count !== nextState.count) {      return true;    }    return false;  }  render() {    <button
      color={this.props.color}
      onClick={() => this.setState(state => ({count: state.count + 1}))}>
      Count: {this.state.count}    </button>  }}

在這段代碼,shouldComponentUpdate只是檢查是否有任何變化props.colorstate.count。如果這些值不會更改,則組件不會更新。如果你的組件變得更加復(fù)雜,你可以使用類似的模式在組件的所有字段之間進(jìn)行“淺層比較” props,state以確定組件是否應(yīng)該更新。這種模式很普遍,React提供了一個幫助器來使用這個邏輯 - 只是從中繼承而來的React.PureComponent。所以這段代碼是一個簡單的方法來實(shí)現(xiàn)同樣的事情:

class CounterButton extends React.PureComponent {  constructor(props) {    super(props);    
    this.state = {count: 1};  }  render() {    <button
      color={this.props.color}
      onClick={() => this.setState(state => ({count: state.count + 1}))}>
      Count: {this.state.count}    </button>  }}

大多數(shù)時候,你可以使用React.PureComponent而不是寫自己的shouldComponentUpdate。它只是進(jìn)行淺層比較,所以如果道具或狀態(tài)可能以淺層比較錯過的方式進(jìn)行了變異,則不能使用它。

這可能是一個更復(fù)雜的數(shù)據(jù)結(jié)構(gòu)的問題。例如,假設(shè)您希望ListOfWords組件呈現(xiàn)以逗號分隔的單詞列表,并使用父WordAdder組件通過單擊按鈕將單詞添加到列表中。此代碼無法正常工作:

class ListOfWords extends React.PureComponent {  render() {    return <div>{this.props.words.join(',')}</div>;  }}
class WordAdder extends React.Component {  constructor(props) {    super(props);    this.state = {
      words: ['marklar']    };    
      this.handleClick = this.handleClick.bind(this);  }  handleClick() {    // This section is bad style and causes a bug    
      const words = this.state.words;
      words.push('marklar');    
      this.setState({words: words});  }  render() {    return (      
          <div><button onClick={this.handleClick} /><ListOfWords words={this.state.words} /></div>    );  }
          }

問題是PureComponent將會對舊的和新的值進(jìn)行簡單的比較this.props.words。由于這段代碼wordshandleClick方法中改變了數(shù)組,所以即使數(shù)組中的實(shí)際字已經(jīng)改變WordAdder,舊的和新的值this.props.words也會相等。該ListOfWords因此將不再更新,即使它有768,16呈現(xiàn)新詞。

不突變數(shù)據(jù)的力量

避免此問題的最簡單方法是避免將您正在用作道具或狀態(tài)的值進(jìn)行變異。例如,handleClick上面的方法可以使用concatas 重寫:

handleClick() {  this.setState(prevState => ({
    words: prevState.words.concat(['marklar'])  }));}

ES6支持?jǐn)?shù)組的擴(kuò)展語法,這可以使這更容易。如果您正在使用Create React App,則默認(rèn)情況下此語法可用。

handleClick() {  this.setState(prevState => ({
    words: [...prevState.words, 'marklar'],  }));};

您也可以以類似的方式重寫改變對象以避免突變的代碼。例如,假設(shè)我們有一個名為object的對象,colormap并且我們想要編寫一個更改colormap.right為的函數(shù)'blue'。我們可以寫:

function updateColorMap(colormap) {
  colormap.right = 'blue';}

要寫這個而不改變原始對象,我們可以使用Object.assign方法:

function updateColorMap(colormap) {  return Object.assign({}, colormap, {right: 'blue'});}

updateColorMap現(xiàn)在返回一個新對象,而不是改變舊對象。Object.assign在ES6中,需要填充。

JavaScript提議添加對象傳播屬性,以便更容易更新對象而無需進(jìn)行突變:

function updateColorMap(colormap) {  return {...colormap, right: 'blue'};}

如果您使用的是創(chuàng)建React應(yīng)用程序,Object.assign則默認(rèn)情況下都可以使用對象傳播語法。

使用不可變數(shù)據(jù)結(jié)構(gòu)

Immutable.js是解決這個問題的另一種方法。它提供了通過結(jié)構(gòu)共享工作的不變的,持久的集合:

  • Immutable:一旦創(chuàng)建,一個集合不能在另一個時間點(diǎn)被修改。

  • Persistent:可以根據(jù)以前的集合和諸如集合之類的變體創(chuàng)建新集合。新集合創(chuàng)建后,原始集合仍然有效。

  • Structural Sharing:使用與原始集合盡可能多的相同結(jié)構(gòu)創(chuàng)建新集合,盡量減少復(fù)制以提高性能。

不變性使追蹤變化便宜。更改總是會導(dǎo)致一個新的對象,所以我們只需要檢查對象的引用是否已經(jīng)改變。例如,在這個常規(guī)的 JavaScript 代碼中:

const x = { foo: 'bar' };const y = x;y.foo = 'baz';x === y; // true

雖然y是編輯過的,但由于它是對同一個對象的引用,所以x此比較返回true。你可以用 immutable.js 編寫類似的代碼:

const SomeRecord = Immutable.Record({ foo: null });
const x = new SomeRecord({ foo: 'bar' });
const y = x.set('foo', 'baz');const z = x.set('foo', 'bar');
x === y; // falsex === z; // true

在這種情況下,由于在變異時返回一個新的引用x,所以我們可以使用引用相等性檢查(x === y)來驗(yàn)證存儲的新值與存儲在y其中的原始值不同x

另外兩個可以幫助使用不可變數(shù)據(jù)的庫是無縫不可變和不可變的幫助器。

不可變的數(shù)據(jù)結(jié)構(gòu)為您提供了一種便捷的方式來跟蹤對象的變化,這是我們需要實(shí)現(xiàn)的shouldComponentUpdate。這通??梢詾槟闾峁┖芎玫男阅芴嵘?。

Previous article: Next article: