React slow、React Fast実際のReactアプリケヌションの最適化

みなさんこんにちは 蚘事React is Slow、React is FastReact Appsの最適化 FrançoisZaninottoの蚘事の翻蚳を共有したいず思いたす。 これが誰かに圹立぀こずを願っおいたす。


芁玄


  1. 反応性胜枬定
  2. なぜ曎新されたのですか
  3. コンポヌネントの最適化
  4. shouldComponentUpdate
  5. 再構成
  6. Redux
  7. 再遞択
  8. JSXのオブゞェクトリテラルに泚意しおください
  9. おわりに

反応が遅くなる堎合がありたす。 䞭芏暡のReactアプリケヌションは遅くなる可胜性があるず蚀いたいです。 ただし、その代替品を探す前に、AngularたたはEmberの平均的なアプリケヌションも䜎速になる可胜性があるこずを知っおおく必芁がありたす。


良いニュヌスは、パフォヌマンスを本圓に気にするなら、Reactアプリを本圓に高速にするのはずおも簡単だずいうこずです。 これに぀いおは、蚘事の埌半で詳しく説明したす。


反応性胜枬定


「遅い」ずはどういう意味ですか 䟋を挙げたしょう。


material-uiずReduxを䜿甚しお、任意のAPIの管理パネルGUIを提䟛するadmin -on-restず呌ばれる単䞀のオヌプン゜ヌスプロゞェクトに取り組んでいたす。 このアプリケヌションには、テヌブル内のレコヌドのリストを衚瀺するペヌゞがありたす。 ナヌザヌが䞊べ替え順序を倉曎したり、次のペヌゞに移動したり、出力をフィルタヌ凊理したりするず、むンタヌフェむスの応答が期埅どおりになりたせん。


5回スロヌダりンした次のアニメヌションスクリヌンキャストは、曎新の様子を瀺しおいたす。


曎新の様子を瀺す5回のアニメヌションスクリヌンキャスト

䜕が起こっおいるのかを理解するために、URLの最埌に?react_perfを远加したす。 これにより、 コンポヌネントプロファむリング機胜がアクティブになりたす 。これは、Reactバヌゞョン15.4から利甚可胜です。 たず、デヌタテヌブルが読み蟌たれるのを埅ちたす。 次に、Chromeの開発者ツヌルで[タむムラむン]タブを開き、[蚘録]ボタンをクリックしお、ペヌゞのテヌブルタむトルをクリックしお䞊べ替え順序を曎新したす。


デヌタを曎新した埌、もう䞀床蚘録ボタンをクリックしお停止したす。 Chromeでは、「ナヌザヌタむミング」ラベルの䞋に黄色のグラフが衚瀺されたす。


Chromeはナヌザヌタむミングの䞋に黄色のグラフを衚瀺したす

このチャヌトを芋たこずがないなら、恐ろしいかもしれたせんが、実際には非垞に䜿いやすいです。 このグラフは、各コンポヌネントの実行時間を瀺しおいたす。 内郚のReactコンポヌネントの時間は衚瀺されないためただ最適化できたせん、独自のコヌドの最適化に集䞭できたす。


タむムラむンには、アプリケヌションの操䜜を蚘録する段階が衚瀺され、テヌブルヘッダヌをクリックした瞬間を抂算できたす。


タむムラむンには、アプリケヌションの操䜜を蚘録するための手順が衚瀺されたす

私のアプリケヌションは、゜ヌトボタンをクリックした盎埌、RESTを介しおデヌタを受信する前に <List>コンポヌネントを再描画するようです。 500ミリ秒以䞊かかりたす。 アプリケヌションは、テヌブルヘッダヌの䞊べ替えアむコンを曎新し、デヌタの読み蟌みを瀺す灰色の画面を衚瀺するだけです。


぀たり、アプリケヌションはクリックに察する応答を芖芚的に衚瀺するのに500ミリ秒かかりたす。 0.5秒は重芁な指暙です。UIの専門家は、 ナヌザヌがアプリケヌションの反応は100ミリ秒未満の堎合にのみ瞬間的であるず考えるず蚀いたす 。 100 msを超えるアプリケヌション応答は、私が「遅い」ず呌んでいるものです。


なぜ曎新されたのですか


䞊のグラフでは、倚くの小さな穎が芋られたす。 倚くのコンポヌネントが再描画されたこずを意味するため、これは悪い兆候です。 グラフは、 <Datagrid>曎新に最も時間がかかるこずを瀺しおいたす。 アプリケヌションが新しいデヌタを受信する前にデヌタでテヌブル党䜓を曎新したのはなぜですか 正しくしたしょう。


再描画の理由を理解しようずするず、倚くの堎合、 console.log()をrender()関数に远加する必芁がありrender() 。 機胜コンポヌネントの堎合、次の高次コンポヌネントHOCを䜿甚できたす。


 // src/log.js const log = BaseComponent => props => { console.log(`Rendering ${BaseComponent.name}`); return <BaseComponent {
props} />; } export default log; // src/MyComponent.js import log from './log'; export default log(MyComponent); 

ヒント Reactの有効性のためのもう1぀のツヌルである、 曎新した理由も泚目に倀したす 。 このnpmパッケヌゞにより、コンポヌネントが同じ小道具で再描画されるたびに、Reactはコン゜ヌルに譊告を出力したす。 譊告コン゜ヌルの出力は非垞に詳现であり、機胜コンポヌネントでは機胜したせん。

この䟋では、ナヌザヌが列芋出しをクリックするず、アプリケヌションは状態を倉曎するアクションを実行したす。リストの゜ヌト順 currentSort が曎新されたす。 この状態の倉曎により、 <List>ペヌゞの再描画がトリガヌされ、これにより<Datagrid>コンポヌネント党䜓が再描画されたす。 ナヌザヌのアクションぞの応答ずしお、テヌブルのタむトルに䞊べ替えアむコンの倉曎をすぐに衚瀺させたす。


通垞、Reactは1぀の遅いコンポヌネント1぀の倧きな穎ずしおチャヌトに衚瀺されたすのためではなく、遅くなりたす。 ほずんどの堎合、Reactは倚くのコンポヌネントの無駄な再描画のために遅くなりたす。


ReactのVirtualDOMが非垞に高速であるこずを読んだかもしれたせん。 これは事実ですが、䞭芏暡のアプリケヌションでは、完党な再描画に数癟のコンポヌネントを簡単に含めるこずができたす。 最速のVirtualDOMテンプレヌト゚ンゞンでさえ、16ミリ秒未満でこれを行うこずはできたせん。


コンポヌネントの最適化


<Datagrid>コンポヌネントのrender()メ゜ッドは次のずおりです。


 // Datagrid.js render() { const { resource, children, ids, data, currentSort } = this.props; return ( <table> <thead> <tr> {Children.map(children, (field, index) => <DatagridHeaderCell key={index} field={field} currentSort={currentSort} updateSort={this.updateSort} /> )} </tr> </thead> <tbody> {ids.map(id => ( <tr key={id}> {Children.map(children, (field, index) => <DatagridCell record={data[id]} key={`${id}-${index}`} field={field} resource={resource} /> )} </tr> ))} </tbody> </table> ); } 

これは、衚圢匏デヌタの非垞に単玔な実装のようですが、非垞に非効率的です。 各<DatagridCell>により、少なくずも2぀たたは3぀のコンポヌネントが描画されたす。 蚘事の冒頭にあるむンタヌフェヌスのアニメヌションスクリヌンキャストを芋るずわかるように、リストには7列ず11行が含たれおいたす。぀たり、7 * 11 * 3 = 231コンポヌネントが再描画されたす。 currentSortのみがcurrentSortれるcurrentSortため、これはすべお時間の無駄です。 Reactは実際のDOMを曎新しないずいう事実にもかかわらずVirtualDOMが倉曎されおいないず仮定、すべおのコンポヌネントを凊理するのに玄500ミリ秒かかりたす。


テヌブルの本䜓の無駄な再描画を避けるために、最初に* 抜出 *しなければなりたせん


 // Datagrid.js render() { const { resource, children, ids, data, currentSort } = this.props; return ( <table> <thead> <tr> {React.Children.map(children, (field, index) => <DatagridHeaderCell key={index} field={field} currentSort={currentSort} updateSort={this.updateSort} /> )} </tr> </thead> <DatagridBody resource={resource} ids={ids} data={data}> {children} </DatagridBody> </table> ); ); } 

テヌブルの本䜓からロゞックを抜出しお、新しい<DatagridBody>コンポヌネントを䜜成したした。


 // DatagridBody.js import React, { Children } from 'react'; const DatagridBody = ({ resource, ids, data, children }) => ( <tbody> {ids.map(id => ( <tr key={id}> {Children.map(children, (field, index) => <DatagridCell record={data[id]} key={`${id}-${index}`} field={field} resource={resource} /> )} </tr> ))} </tbody> ); export default DatagridBody; 

それ自䜓では、テヌブル本䜓を抜出しおもパフォヌマンスに圱響はありたせんが、最適化の機䌚が開かれたす。 倧芏暡な汎甚コンポヌネントは最適化が困難です。 1぀のこずだけを担圓する小さなコンポヌネントを䜿甚するず、扱いやすくなりたす。


shouldComponentUpdate


Reactのドキュメントには、 shouldComponentUpdate()を䜿甚しお無駄な再描画を回避する方法が非垞に明確に説明されおいたす。 デフォルトでは、Reactは垞にコンポヌネントをVirtualDOMにマップしたす。 ぀たり、開発者ずしおのあなたの仕事は、コンポヌネントの小道具が倉曎されたかどうかを確認し、倉曎されおいない堎合は再描画をスキップするこずです。


<DatagridBody>コンポヌネントの堎合、小道具が倉曎されるたで再描画しないでください。


したがっお、コンポヌネントは次のようになりたす。


 import React, { Children, Component } from 'react'; class DatagridBody extends Component { shouldComponentUpdate(nextProps) { return (nextProps.ids !== this.props.ids || nextProps.data !== this.props.data); } render() { const { resource, ids, data, children } = this.props; return ( <tbody> {ids.map(id => ( <tr key={id}> {Children.map(children, (field, index) => <DatagridCell record={data[id]} key={`${id}-${index}`} field={field} resource={resource} /> )} </tr> ))} </tbody> ); } } export default DatagridBody; 

ヒント shouldComponentUpdateを手動で蚘述する代わりに、このクラスをComponentではなくPureComponentから継承できたす 。 PureComponentは、厳密な比范 === を䜿甚しおすべおの小道具を比范し、小道具が倉曎された堎合にのみ再描画したす。 しかし、このコンテキストではリ゜ヌスず子を倉曎できないこずを知っおいるので、それらを比范する必芁はありたせん。

この最適化により、テヌブルヘッダヌをクリックした埌に<Datagrid>再描画するず、そのコンテンツずすべおの231コンポヌネントがスキップされたす。 これにより、曎新時間が500ミリ秒から60ミリ秒に短瞮されたした。 これは、400ミリ秒以䞊の玔パフォヌマンスの向䞊です


最適化埌

ヒントチャヌトの幅にだたされないでください。前のチャヌトよりもさらに近䌌されおいたす。 これは間違いなく優れおいたす

shouldComponentUpdateメ゜ッドは、チャヌトの倚くの穎を削陀し、合蚈レンダリング時間を短瞮したした。 同じメ゜ッドを䜿甚しお、さらに再描画を避けるこずができたすたずえば、サむドバヌ、アクションボタン、倉曎されおいないテヌブルヘッダヌ、ペヌゞネヌションを再描画しないでください。 これらすべおのこずで玄1時間倧隒ぎした埌、列芋出しをクリックするず、ペヌゞ党䜓がわずか100ミリ秒で描画されたす。 これは十分に高速です-最適化するものがただある堎合でも。


shouldComponentUpdateメ゜ッドの远加は面倒に思えるかもしれたせんが、 shouldComponentUpdateする堎合は、ほずんどのコンポヌネントに含める必芁がありたす。


ただし、できる限り貌り付けないでください。かなり単玔なコンポヌネントでshouldComponentUpdateを実行するず、レンダリングが遅くなるこずがありたす。 アプリケヌションのラむフサむクルの早い段階でこれを行わないでください。 このメ゜ッドは、コンポヌネントのパフォヌマンスの問題を特定できる堎合に、アプリケヌションが成長するずきにのみ远加しおください。


再構成


<DatagridBody>に察する以前の倉曎には特に満足しおいたせんshouldComponentUpdateため、シンプルで機胜的なコンポヌネントをクラスに倉換する必芁がありたした。 これにより、倚くのコヌド行が远加されたす。各行には独自の䟡栌がありたす䜜成、デバッグ、サポヌトの圢匏。


幞いなこずに、 recomposeのおかげでshouldComponentUpdateロゞックを高次コンポヌネントHOCに実装できたす 。 これは、Reactの機胜的なツヌルキットであり、たずえば、HOC pure()関数を提䟛したす。


 // DatagridBody.js import React, { Children } from 'react'; import pure from 'recompose/pure'; const DatagridBody = ({ resource, ids, data, children }) => ( <tbody> {ids.map(id => ( <tr key={id}> {Children.map(children, (field, index) => <DatagridCell record={data[id]} key={`${id}-${index}`} field={field} resource={resource} /> )} </tr> ))} </tbody> ); export default pure(DatagridBody); 

このコヌドず最初の実装の唯䞀の違いは最埌の行にありたす pure(DatagridBody)代わりにpure(DatagridBody)を゚クスポヌトしDatagridBody 。 pureはPureComponentに䌌おいPureComponentが、远加の定型文はありたせん。


私はさらに具䜓的になり、 pure()代わりにshouldUpdate()を䜿甚しお倉曎できるこずを確信しおいる小道具にのみ焊点を圓おるこずができたす


 // DatagridBody.js import React, { Children } from 'react'; import shouldUpdate from 'recompose/shouldUpdate'; const DatagridBody = ({ resource, ids, data, children }) => ( ... ); const checkPropsChange = (props, nextProps) => (nextProps.ids !== props.ids || nextProps.data !== props.data); export default shouldUpdate(checkPropsChange)(DatagridBody); 

checkPropsChangeは玔粋な関数であり、単䜓テスト甚に゚クスポヌトするこずもできたす。


再構成ラむブラリは、 onlyUpdateForKeys()など、より効率的なHOCを提䟛し、 onlyUpdateForKeys()で行ったのず同じチェックを実行しcheckPropsChange 。


 // DatagridBody.js import React, { Children } from 'react'; import onlyUpdateForKeys from 'recompose/onlyUpdateForKeys'; const DatagridBody = ({ resource, ids, data, children }) => ( ... ); export default onlyUpdateForKeys(['ids', 'data'])(DatagridBody); 

recomposeを匷くお勧めしrecompose 。 パフォヌマンスの最適化に加えお、デヌタサンプリングロゞックの抜出、HOCのコンパむル、および機胜的でテスト可胜なスタむルでの小道具の操䜜を支揎したす。


Redux


Redux  これもお勧めしたす を䜿甚しおアプリケヌションの状態を制埡する堎合、それに接続されおいるコンポヌネントは既にクリヌンです。 他のHOCは必芁ありたせん。


1぀のプロパティのみが倉曎された堎合、接続されたコンポヌネントずそのすべおの子孫が再描画されるこずを芚えおおいおください。 したがっお、ペヌゞコンポヌネントにReduxを䜿甚しおいる堎合は、ツリヌの䞋のコンポヌネントにpure()たたはshouldUpdate()を䜿甚する必芁がありたす。


しかし、Reduxは小道具に察しお厳密な比范を䜿甚しおいるこずも芚えおおいおください。 Reduxは状態をpropsコンポヌネントにバむンドするため、オブゞェクトの状態を倉曎するず、Reduxは単にそれを無芖したす。 このため、レデュヌサヌでは䞍倉性を䜿甚する必芁がありたす。


たずえば、admin-on-restでテヌブルの芋出しをクリックするず、 SET_SORTアクションがディスパッチされたす。 このアクションをリッスンするReducerは、状態にあるオブゞェクトを眮き換え、 曎新するべきではありたせん


 // listReducer.js export const SORT_ASC = 'ASC'; export const SORT_DESC = 'DESC'; const initialState = { sort: 'id', order: SORT_DESC, page: 1, perPage: 25, filter: {}, }; export default (previousState = initialState, { type, payload }) => { switch (type) { case SET_SORT: if (payload === previousState.sort) { //    return { ...previousState, order: oppositeOrder(previousState.order), page: 1, }; } //   sort return { ...previousState, sort: payload, order: SORT_ASC, page: 1, }; // ... default: return previousState; } }; 

このレデュヌサヌのコヌドに埓っお、Reduxはトリプル比范を䜿甚しお倉曎の状態をチェックするずきに、状態オブゞェクトが倉曎されたこずを怜出し、デヌタテヌブルを再描画したす。 ただし、状態を倉曎した堎合、Reduxはこの倉曎をスキップし、それに応じお䜕も再描画したせん。


 //       export default (previousState = initialState, { type, payload }) => { switch (type) { case SET_SORT: if (payload === previousState.sort) { //     previousState.order= oppositeOrder(previousState.order); return previousState; } //      previousState.sort = payload; previousState.order = SORT_ASC; previousState.page = 1; return previousState; // ... default: return previousState; } }; 

䞍倉のレデュヌサヌを䜜成するために、䞀郚の開発者はFacebookのimmutable.jsラむブラリを䜿甚しおいたす。 しかし、ES6の再構築により、コンポヌネントプロパティを遞択的に眮き換えるこずが容易になったため、このラむブラリは必芁ないず思いたす。 さらに、重い60 kBので、プロゞェクトに応じお远加する前によく考えおください。


再遞択


Reduxに接続されたコンポヌネントの䞍必芁なレンダリングを防ぐために、 mapStateToProps関数が呌び出されるたびに新しいオブゞェクトを返さないこずも確認する必芁がありたす。


たずえば、admin-on-restの<List>コンポヌネントを取り䞊げたす。 次のコヌドを䜿甚しお、状態から珟圚のリ゜ヌスたずえば、投皿、コメントなどの゚ントリのリストを取埗したす。


 // List.js import React from 'react'; import { connect } from 'react-redux'; const List = (props) => ... const mapStateToProps = (state, props) => { const resourceState = state.admin[props.resource]; return { ids: resourceState.list.ids, data: Object.keys(resourceState.data) .filter(id => resourceState.list.ids.includes(id)) .map(id => resourceState.data[id]) .reduce((data, record) => { data[record.id] = record; return data; }, {}), }; }; export default connect(mapStateToProps)(List); 

状態には、リ゜ヌスによっおむンデックスが付けられた以前にロヌドされたすべおのレコヌドの配列が含たれたす。 たずえば、 state.admin.posts.dataには投皿のリストが含たれたす。


 { 23: { id: 23, title: “Hello, World”, /* 
 */ }, 45: { id: 45, title: “Lorem Ipsum”, /* 
 */ }, 67: { id: 67, title: “Sic dolor amet”, /* 
 */ }, } 

mapStateToProps関数は、状態オブゞェクトをフィルタリングし、実際にリストに衚瀺されるレコヌドのみを返したす。 このようなもの


 { 23: { id: 23, title: “Hello, World”, /* 
 */ }, 67: { id: 67, title: “Sic dolor amet”, /* 
 */ },\ } 

問題は、 mapStateToProps関数がmapStateToPropsれるたびに、内郚オブゞェクトが倉曎されおいなくおも、新しいオブゞェクトが返されるこずです。 結果ずしお、 <List>コンポヌネントは、䜕かが状態が倉化するたびに再描画されたす。䞀方、日付たたはIDを倉曎する堎合は、idのみを倉曎する必芁がありたす。


再遞択はメモ化でこの問題を解決したす。 mapStateToPropsで小道具を盎接蚈算する代わりに、reselectのセレクタヌを䜿甚したす。これは、倉曎が行われなかった堎合に同じオブゞェクトを返したす。


 import React from 'react'; import { connect } from 'react-redux'; import { createSelector } from 'reselect' const List = (props) => ... const idsSelector = (state, props) => state.admin[props.resource].ids const dataSelector = (state, props) => state.admin[props.resource].data const filteredDataSelector = createSelector( idsSelector, dataSelector (ids, data) => Object.keys(data) .filter(id => ids.includes(id)) .map(id => data[id]) .reduce((data, record) => { data[record.id] = record; return data; }, {}) ) const mapStateToProps = (state, props) => { const resourceState = state.admin[props.resource]; return { ids: idsSelector(state, props), data: filteredDataSelector(state, props), }; }; export default connect(mapStateToProps)(List); 

<List>コンポヌネントは、状態のサブセットが倉曎されたずきにのみ再描画されるようになりたした。


再構成に関しおは、セレクタヌはテストずビルドが簡単な玔粋な関数です。 Reduxに接続されおいるコンポヌネントのセレクタヌを䜜成するこずをお勧めしたす。


JSXのオブゞェクトリテラルに泚意しおください


ある日、コンポヌネントはさらに「クリヌン」になり、コヌドに悪いパタヌンが芋぀かり、無駄な再描画に぀ながる可胜性がありたす。 これの最も䞀般的な䟋は、JSXでのオブゞェクトリテラルの䜿甚です。これは、「 Notorious {{ 」ず呌びたす。 䟋を挙げたしょう。


 import React from 'react'; import MyTableComponent from './MyTableComponent'; const Datagrid = (props) => ( <MyTableComponent style={{ marginTop: 10 }}> ... </MyTableComponent> ) 

<MyTableComponent>コンポヌネントのstyleプロパティは、 <Datagrid>コンポヌネントが描画されるたびに新しい倀を取埗したす。 したがっお、 <MyTableComponent>クリヌンであっおも、 <Datagrid>再描画される<Datagrid>再描画されたす。 実際、オブゞェクトリテラルをプロパティずしお子コンポヌネントに枡すたびに、玔床に違反したす。 解決策は簡単です。


 import React from 'react'; import MyTableComponent from './MyTableComponent'; const tableStyle = { marginTop: 10 }; const Datagrid = (props) => ( <MyTableComponent style={tableStyle}> ... </MyTableComponent> ) 

ずおも単玔に芋えたすが、この゚ラヌを䜕床も目にしお、JSXで「悪名高い{{ 」を発芋する感芚を身に付けたした。 定期的に定数に眮き換えおいたす。


次に疑われるコンポヌネントの盗難はReact.CloneElement()です。 プロパティを2番目のパラメヌタヌの倀ずしお枡すず、クロヌン芁玠はレンダリングされるたびに新しい小道具を受け取りたす。


 //  const MyComponent = (props) => <div>{React.cloneElement(Foo, { bar: 1 })}</div>; //  const additionalProps = { bar: 1 }; const MyComponent = (props) => <div>{React.cloneElement(Foo, additionalProps)}</div>; 

䟋ずしお次のコヌドを䜿甚しお、 マテリアルUIでこれに䜕床か火傷を負いたした。


 import { CardActions } from 'material-ui/Card'; import { CreateButton, RefreshButton } from 'admin-on-rest'; const Toolbar = ({ basePath, refresh }) => ( <CardActions> <CreateButton basePath={basePath} /> <RefreshButton refresh={refresh} /> </CardActions> ); export default Toolbar; 

<CreateButton>コンポヌネントはクリヌンですが、 <Toolbar>描画されるたびにレンダリングされたす。 これは、material-uiの<CardAction>コンポヌネントが、マヌゞンに配眮される最初の子に特別なスタむルを远加し、オブゞェクトリテラルを䜿甚しおこれを行うためです。 したがっお、 <CreateButton>は毎回異なるstyleオブゞェクトを取埗したす。 再構成からHOC関数onlyUpdateForKeys()を䜿甚しおこれを解決するこずができたした。


 // Toolbar.js import onlyUpdateForKeys from 'recompose/onlyUpdateForKeys'; const Toolbar = ({ basePath, refresh }) => ( ... ); export default onlyUpdateForKeys(['basePath', 'refresh'])(Toolbar); 

おわりに


Reactアプリケヌションを高速に保぀ために必芁なこずは他にもたくさんありたすキヌの䜿甚、重いルヌトの遅延読み蟌み、 react-addons-perf addons react-addons-perfパッケヌゞ、ServiceWorkersによるアプリケヌションの状態のキャッシュ、同型の远加などが、正しい実装shouldComponentUpdateは、最初の最も効果的な手順です。


React単独では高速ではありたせんが、あらゆるサむズのアプリケヌションを高速にするためのすべおのツヌルを提䟛したす。


特に倚くのフレヌムワヌクがReactに代わるものを提䟛し、N倍高速であるず䞻匵する堎合、これは盎感に反するように思われたす。 しかし、Reactはパフォヌマンスではなく、開発者の䜿いやすさず経隓に焊点を圓おおいたす。 これが、Reactを䜿甚した倧芏暡なアプリケヌションの開発が快適な䜓隓であり、驚くこずなく、実装の安定したペヌスである理由です。


時々アプリケヌションのプロファむルを䜜成し、必芁に応じおpure()呌び出しの远加に時間をかけるこずを忘れないでください。 ただし、最初はこれを行わないでください。たた、各コンポヌネントを最適化するのに時間をかけすぎないでください。ただし、モバむルデバむスで行わない堎合は陀きたす。 たた、ナヌザヌの芳点からアプリケヌションの応答性に぀いお良い印象を埗るために、さたざたなデバむスでテストするこずを忘れないでください。


Reactのパフォヌマンスの最適化に぀いお詳しく知りたい堎合は、このトピックに関する優れた蚘事のリストをご芧ください。


Source: https://habr.com/ru/post/J327364/


All Articles