より生産的な変更のためにreduxストレージを最適化します

この投稿は、Reactアプリケーションでのリストのパフォーマンスの最適化に関する投稿の続きです



ご注意 この投稿では、Reduxアプリケーション専用の例を用意しています。 ただし、アプローチ自体は他のライブラリに適用できます。 また、以下のアドバイスはreact-reduxバージョン5で機能します。 バージョン4では目的の結果を達成できませんでした。 私はその理由を深く理解していませんでした。



したがって、アプリケーションに要素の一部を格納する標準的な方法は、配列に要素を格納することです。



const state = { targets: [{id: 'target1', radius: 10}, {id: 'target2', radius: 2}] };
      
      





次に、ほとんどの場合、アプリケーションのどこかに、このリストを表示するコンポーネントがあります。



 const TargetsList = connect(state => ({targets: state.targets}))( ({ targets }) => <ul> { targets.map((target) => <TargetView key={target.id} target={target} />) } </ul> );
      
      





突然1つの要素を更新する必要がある場合は、配列全体を更新する必要があります(不変です)。



 function appReducer(state, action) { if (action.type === 'UPDATE') { return { target: state.target.map((target) => { if (target.id === action.id) { return { ...target, radius: action.radius }; } else { return target; } }) } } // some other code }
      
      





また、要素を更新すると、TargetsListビュー全体が更新されます(そのレンダーが呼び出されます)。



パフォーマンスを測定するためのテストコードを使用した小さなデモを作成しました。



私のマシンでは、1000のリスト内の1つのアイテムの更新には約21msかかります。 以前の投稿で、子コンポーネントの状態変更に追加のサブスクリプションを使用し、リストを表示するコンポーネントの「shouldComponentUpdate」にいくつかのロジックを追加することにより、生産性を向上させる方法について説明しました。



ただし、データの形式をわずかに変更しても、ほぼ同じ結果が得られます。



最適化する方法



github.com/reactjs/react-reduxを使用する場合、状態フォームを次のように変更することで生産性を向上できます。



 const state = { targetsOrder: ['id-1', 'id-2'], targets: { 'id-1': { id: 'id-1', radius: 10 }, 'id-2': { id: 'id-2', radius: 20 }, } };
      
      





次に、TargetsListコンポーネントをわずかに変更する必要があります。



 const TargetsList = connect(state => ({targetsOrder: state.targetsOrder}))( ({ targetsOrder }) => <ul> { targetsOrder.map((id) => <TargetView key={id} targetId={id} />) } </ul> );
      
      





この場合、要素全体ではなく、子コンポーネントに要素IDを渡すことに注意してください。 その場合、「TargetView」は「ダムコンポーネント」にはならず、状態の変化にサブスクライブする必要があります。



 const TargetView = connect( (state, ownProps) => ({target: state.targets[ownProps.targetId]}) )(({ target }) => { // your render logic return <Circle radius={target.radius} />; });
      
      





TargetViewは状態の変更にサブスクライブしているため、データが更新されると、自身を更新します。 重要なことは、「targetsOrder」は同じままであるため、リスト内のアイテムが変更されても「TargetList」は更新されないことです。 場合によっては、この手法により生産性が大幅に向上します。



デモで測定値を更新



現在、1つのアイテムを更新するには、マシン上で2.2msかかります。 これは、前の例よりもほぼ10倍高速です。



All Articles