From 04884124a066213c19b297e6c759d12c552ef424 Mon Sep 17 00:00:00 2001 From: "UEHARA, Junji" <59012+uehaj@users.noreply.github.com> Date: Wed, 6 Feb 2019 20:45:21 +0900 Subject: [PATCH 01/31] add initial japanese version from crowdin --- content/docs/optimizing-performance.md | 179 +++++++++++++++++++++++++ 1 file changed, 179 insertions(+) diff --git a/content/docs/optimizing-performance.md b/content/docs/optimizing-performance.md index aaed723c4..d127753a7 100644 --- a/content/docs/optimizing-performance.md +++ b/content/docs/optimizing-performance.md @@ -8,39 +8,67 @@ redirect_from: Internally, React uses several clever techniques to minimize the number of costly DOM operations required to update the UI. For many applications, using React will lead to a fast user interface without doing much work to specifically optimize for performance. Nevertheless, there are several ways you can speed up your React application. +React は UI 更新時に必要となる高コストな DOM 操作の数を最小化するために、内部的にいくつかの賢いテクニックを使用しています。 +多くのアプリケーションでは、React を使用することで、苦労して特別にパフォーマンスを最適化することなく、高速なユーザーインターフェースを実現できます。 +それでもなお、React アプリケーションを高速化するための方法はいくつか存在します。 + ## Use the Production Build +## 本番用ビルドを使用する If you're benchmarking or experiencing performance problems in your React apps, make sure you're testing with the minified production build. +React アプリケーションでベンチマークを行う場合やパフォーマンスの問題が発生している場合には、ミニファイされた本番用ビルドでテストしていることを確認して下さい。 + By default, React includes many helpful warnings. These warnings are very useful in development. However, they make React larger and slower so you should make sure to use the production version when you deploy the app. +デフォルトで React は多くの有用な警告文を含んでいます。 +これらの警告文は開発時にはとても有用です。 +しかし、それらによって React は肥大化し、低速化するので、アプリケーションのデプロイ時には本番バージョンを使用していることを確認する必要があります。 + If you aren't sure whether your build process is set up correctly, you can check it by installing [React Developer Tools for Chrome](https://chrome.google.com/webstore/detail/react-developer-tools/fmkadmapgofadopljbjfkapdkoienihi). If you visit a site with React in production mode, the icon will have a dark background: + +ビルドプロセスが正しく設定されているか分からない場合、React Developer Tools for Chrome をインストールして確認できます。 +本番用モードの React のサイトを訪れた場合、アイコンは暗い背景となっています: + React DevTools on a website with production version of React If you visit a site with React in development mode, the icon will have a red background: +開発モードの React のサイトを訪れた場合、アイコンは赤い背景となっています: + React DevTools on a website with development version of React It is expected that you use the development mode when working on your app, and the production mode when deploying your app to the users. +アプリケーションで作業中の場合は開発モードを使用し、ユーザーに向けてアプリケーションをデプロイする場合には本番用モードを使用することが推奨されます。 + You can find instructions for building your app for production below. +以下で本番用のアプリケーションのビルド手順を見ることができます。 + ### Create React App If your project is built with [Create React App](https://github.com/facebookincubator/create-react-app), run: +プロジェクトが Create React App で構築されているなら、以下のコードを実行して下さい: + ``` npm run build ``` This will create a production build of your app in the `build/` folder of your project. +これによりアプリケーションの本番用ビルドがプロジェクト内の build/ フォルダに作成されます。 + Remember that this is only necessary before deploying to production. For normal development, use `npm start`. +これは本番バージョンをデプロイする前のみ必要な作業であることに留意してください。通常の開発作業では、npm start を使用してください。 ### Single-File Builds +### 単一ファイル版ビルド We offer production-ready versions of React and React DOM as single files: +本番環境で使える、単一ファイル化されたバージョンの React と ReactDOM が提供されています。 ```html @@ -49,10 +77,14 @@ We offer production-ready versions of React and React DOM as single files: Remember that only React files ending with `.production.min.js` are suitable for production. +ファイル名の末尾が .production.min.js の React ファイルのみが本番用に適していることを覚えておいてください。 + ### Brunch For the most efficient Brunch production build, install the [`uglify-js-brunch`](https://github.com/brunch/uglify-js-brunch) plugin: +最も効率のよい Brunch を使った本番用ビルドのために、uglify-js-brunch をインストールしてください: + ``` # If you use npm npm install --save-dev uglify-js-brunch @@ -63,16 +95,25 @@ yarn add --dev uglify-js-brunch Then, to create a production build, add the `-p` flag to the `build` command: +本番用ビルドを作成する際は、-p フラグを build コマンドに追加します: + ``` brunch build -p ``` Remember that you only need to do this for production builds. You shouldn't pass the `-p` flag or apply this plugin in development, because it will hide useful React warnings and make the builds much slower. + +これは本番用ビルドにのみ必要な作業であることに留意してください。 +開発用では -p フラグを指定したり、このプラグインを適用すると React の有用な警告文を隠したり、ビルド速度が大幅に遅くなるので使用しないでください。 + ### Browserify For the most efficient Browserify production build, install a few plugins: +最も効率の良い Browserify による本番用ビルドを行うため、いくつかプラグインをインストールしてください: + + ``` # If you use npm npm install --save-dev envify uglify-js uglifyify @@ -82,12 +123,20 @@ yarn add --dev envify uglify-js uglifyify ``` To create a production build, make sure that you add these transforms **(the order matters)**: +本番用ビルドを作成するには、以下のトランスフォームを追加してください(順番通りに追加してください): * The [`envify`](https://github.com/hughsk/envify) transform ensures the right build environment is set. Make it global (`-g`). +* envify トランスフォームは正しいビルド環境が設定されていることを保証します。グローバルに設定してください (-g)。 + * The [`uglifyify`](https://github.com/hughsk/uglifyify) transform removes development imports. Make it global too (`-g`). +* uglifyify トランスフォームは開発用にインポートしたライブラリを削除します。これもグローバルに設定してください (-g)。 + * Finally, the resulting bundle is piped to [`uglify-js`](https://github.com/mishoo/UglifyJS2) for mangling ([read why](https://github.com/hughsk/uglifyify#motivationusage)). +* 最後に結果として出力されたものを、名前の圧縮のために uglify-js にパイプします(理由はこちら)。 For example: +例えば: + ``` browserify ./index.js \ @@ -100,12 +149,16 @@ browserify ./index.js \ > >The package name is `uglify-js`, but the binary it provides is called `uglifyjs`.
>This is not a typo. +>パッケージ名は uglify-js ですが、パッケージが提供するバイナリは uglifyjs という名前です。タイプミスではありません。 Remember that you only need to do this for production builds. You shouldn't apply these plugins in development because they will hide useful React warnings, and make the builds much slower. +これは本番用ビルドにのみ必要な作業であることに留意してください。これらのプラグインは開発版に適用すると React の有用な警告文を隠して、ビルド速度を遅くしていまいます。 + ### Rollup For the most efficient Rollup production build, install a few plugins: +最も効率の良い Rollup による本番用ビルドを行うため、いくつかプラグインをインストールします: ``` # If you use npm @@ -116,10 +169,16 @@ yarn add --dev rollup-plugin-commonjs rollup-plugin-replace rollup-plugin-uglify ``` To create a production build, make sure that you add these plugins **(the order matters)**: +本番用ビルドを作成するには、以下のプラグインを追加してください(順番通りに追加してください): * The [`replace`](https://github.com/rollup/rollup-plugin-replace) plugin ensures the right build environment is set. +* replace プラグインは確実に正しいビルド環境が設定されるようにします。 + * The [`commonjs`](https://github.com/rollup/rollup-plugin-commonjs) plugin provides support for CommonJS in Rollup. +* commonjs プラグインは Rollup で CommonJS をサポートできるようにします。 + * The [`uglify`](https://github.com/TrySound/rollup-plugin-uglify) plugin compresses and mangles the final bundle. +* uglify プラグインは最後の出力されたものを圧縮して余分なものを削ぎ落とします。 ```js plugins: [ @@ -134,17 +193,25 @@ plugins: [ ``` For a complete setup example [see this gist](https://gist.github.com/Rich-Harris/cb14f4bc0670c47d00d191565be36bf0). +設定例の全体はこの gist を確認してください。 + Remember that you only need to do this for production builds. You shouldn't apply the `uglify` plugin or the `replace` plugin with `'production'` value in development because they will hide useful React warnings, and make the builds much slower. +これは本番用ビルドにのみ必要な作業であることに留意してください。 +React の有用な警告文が隠され、ビルド速度が大幅に遅くなるので、開発環境で 'production' という値で uglify プラグインもしくは replace プラグインを適用しないでください。 + ### webpack >**Note:** > >If you're using Create React App, please follow [the instructions above](#create-react-app).
>This section is only relevant if you configure webpack directly. +> Create React App を利用している場合は、上記のガイドに従うようにしてください。 +>このセクションは直接 webpack の設定を行いたい人向けです。 For the most efficient webpack production build, make sure to include these plugins in your production configuration: +効率的な本番用ビルドを生成するために、本番環境の設定中に必ず以下のプラグインを含めるようにしてください。 ```js new webpack.DefinePlugin({ @@ -154,41 +221,62 @@ new webpack.optimize.UglifyJsPlugin() ``` You can learn more about this in [webpack documentation](https://webpack.js.org/guides/production-build/). +詳細な説明は webpack のドキュメントにあります。 Remember that you only need to do this for production builds. You shouldn't apply `UglifyJsPlugin` or `DefinePlugin` with `'production'` value in development because they will hide useful React warnings, and make the builds much slower. +これは本番用ビルドにのみ必要な作業であることに留意してください。 +React の有用な警告文が隠され、ビルド速度が大幅に遅くなるので、開発環境で 'production' という値で UglifyJsPlugin もしくは DefinePlugin を適用しないでください。 ## Profiling Components with the Chrome Performance Tab +## Chrome のパフォーマンスタブでコンポーネントをプロファイルする In the **development** mode, you can visualize how components mount, update, and unmount, using the performance tools in supported browsers. For example: +開発モードでは、対応ブラウザのパフォーマンス分析ツールを使って、どのようにコンポーネントがマウントし、更新して、アンマウントするのかを視覚化することができます。例えば:
React components in Chrome timeline
To do this in Chrome: +Chrome でこれを行うには: 1. Temporarily **disable all Chrome extensions, especially React DevTools**. They can significantly skew the results! +1. 一時的に React DevTools を含むすべての Chrome 拡張機能を無効にする。無効にしないと、結果が正確でなくなる可能性があります。 2. Make sure you're running the application in the development mode. +2. 開発モードでアプリケーションが動作していることを確認する。 3. Open the Chrome DevTools **[Performance](https://developers.google.com/web/tools/chrome-devtools/evaluate-performance/timeline-tool)** tab and press **Record**. +3. Chrome DevTools のパフォーマンスタブを開いて記録ボタンを押す。 4. Perform the actions you want to profile. Don't record more than 20 seconds or Chrome might hang. +4. プロファイル対象のアクションを実行する。20秒以上記録しないでください、さもなくば Chrome がハングすることがあります。 5. Stop recording. +5. 記録を停止する。 6. React events will be grouped under the **User Timing** label. +6. Reactイベントが User Timing ラベルの下にグループ化される。 For a more detailed walkthrough, check out [this article by Ben Schwarz](https://calibreapp.com/blog/2017-11-28-debugging-react/). +Reactイベントが User Timing ラベルの下にグループ化される。 Note that **the numbers are relative so components will render faster in production**. Still, this should help you realize when unrelated UI gets updated by mistake, and how deep and how often your UI updates occur. +プロファイル結果の数字は相対的なものであり、コンポーネントは本番環境ではより速くレンダリングされることに注意してください。 +それでも、関係のない UI が誤って更新されているのを見つけたり、どの程度の頻度と深さで UI の更新が発生するのかを知る手助けになるはずです。 Currently Chrome, Edge, and IE are the only browsers supporting this feature, but we use the standard [User Timing API](https://developer.mozilla.org/en-US/docs/Web/API/User_Timing_API) so we expect more browsers to add support for it. +現時点では、Chrome、Edge、そして IE のみがこの機能をサポートするブラウザですが、私達は標準の User Timing API を採用しているので、より多くのブラウザがサポートしてくれることを期待しています。 + ## Profiling Components with the DevTools Profiler +## 長いリストの仮想化 `react-dom` 16.5+ and `react-native` 0.57+ provide enhanced profiling capabilities in DEV mode with the React DevTools Profiler. An overview of the Profiler can be found in the blog post ["Introducing the React Profiler"](/blog/2018/09/10/introducing-the-react-profiler.html). A video walkthrough of the profiler is also [available on YouTube](https://www.youtube.com/watch?v=nySib7ipZdk). +アプリケーションがデータの長いリスト(数百〜数千行) を描画する場合は、 「ウィンドウイング」 と呼ばれる技術を使用することをおすすめします。 この技術は任意の時点での行の小さなサブセットのみを描画し、作成されたDOM ノードの数と同じく、コンポーネントの再描画にかかる時間を大幅に削減することができます。 +React Virtualized は人気のあるウィンドウイングのライブラリのひとつです。 リスト、グリッド、および表形式のデータを表示するための、いくつかの再利用可能なコンポーネントを提供しています。 Twitter のようにアプリケーションの特定のユースケースに合わせてより多くの何かをしたい場合は、独自のウィンドウイングのコンポーネントを作成することもできます。 + If you haven't yet installed the React DevTools, you can find them here: - [Chrome Browser Extension](https://chrome.google.com/webstore/detail/react-developer-tools/fmkadmapgofadopljbjfkapdkoienihi?hl=en) @@ -207,18 +295,30 @@ If your application renders long lists of data (hundreds or thousands of rows), [react-window](https://react-window.now.sh/) and [react-virtualized](https://bvaughn.github.io/react-virtualized/) are popular windowing libraries. They provide several reusable components for displaying lists, grids, and tabular data. You can also create your own windowing component, like [Twitter did](https://medium.com/@paularmstrong/twitter-lite-and-high-performance-react-progressive-web-apps-at-scale-d28a00e780a3), if you want something more tailored to your application's specific use case. ## Avoid Reconciliation +## ツリーの突き合わせ処理を避ける React builds and maintains an internal representation of the rendered UI. It includes the React elements you return from your components. This representation lets React avoid creating DOM nodes and accessing existing ones beyond necessity, as that can be slower than operations on JavaScript objects. Sometimes it is referred to as a "virtual DOM", but it works the same way on React Native. +React はレンダリングされた UI の内部表現を構築して維持します。 +それにはユーザ自身のコンポーネントから返された React 要素も含まれます。 +この内部表現を使って React は、JavaScript オブジェクトの操作よりも遅くなりうる DOM ノードの作成や DOM ノードへのアクセスを必要以上に行うことを回避します。 +しばしばこの内部表現は "仮想DOM (virtual DOM)" と呼ばれますが、React Native でも同様に動作します。 + When a component's props or state change, React decides whether an actual DOM update is necessary by comparing the newly returned element with the previously rendered one. When they are not equal, React will update the DOM. +コンポーネントの props か state が変更された場合、React は新しく返された要素を以前にレンダリングされたものと比較することで、本物の DOM の更新が必要かを判断します。 +それらが等しくない場合、React は DOM を更新します。 + You can now visualize these re-renders of the virtual DOM with React DevTools: +それらが等しくない場合、React は DOM を更新します。 + - [Chrome Browser Extension](https://chrome.google.com/webstore/detail/react-developer-tools/fmkadmapgofadopljbjfkapdkoienihi?hl=en) - [Firefox Browser Extension](https://addons.mozilla.org/en-GB/firefox/addon/react-devtools/) - [Standalone Node Package](https://www.npmjs.com/package/react-devtools) In the developer console select the **Highlight Updates** option in the **React** tab: +デベロッパコンソールのReact タブで Highlight Updates オプションを選択します:
How to enable highlight updates
@@ -230,6 +330,9 @@ Consider this example: Note that when we're entering a second todo, the first todo also flashes on the screen on every keystroke. This means it is being re-rendered by React together with the input. This is sometimes called a "wasted" render. We know it is unnecessary because the first todo content has not changed, but React doesn't know this. +2つ目のTODOを入力しているとき、1つ目のTODOもキーストロークの度に画面上で点滅することに注意してください。 これは、 React が入力によって一緒に再描画していることを意味します。 これは「無駄な」描画と呼ばれることがあります。 我々は 最初の TODO は、内容が変わっていないために再描画の必要がないことを知っていますが、 React はそれを知りません。 +この関数のデフォルトの実装は true を返し、React にそのまま更新処理を実行させます: + Even though React only updates the changed DOM nodes, re-rendering still takes some time. In many cases it's not a problem, but if the slowdown is noticeable, you can speed all of this up by overriding the lifecycle function `shouldComponentUpdate`, which is triggered before the re-rendering process starts. The default implementation of this function returns `true`, leaving React to perform the update: ```javascript @@ -240,26 +343,47 @@ shouldComponentUpdate(nextProps, nextState) { If you know that in some situations your component doesn't need to update, you can return `false` from `shouldComponentUpdate` instead, to skip the whole rendering process, including calling `render()` on this component and below. +いくつかの状況においてコンポーネントが更新される必要がないと分かっているなら、shouldComponentUpdate から代わりに false を返すことにより、該当コンポーネントおよび配下への render() 呼び出しを含む、レンダリング処理の全体をスキップすることができます。 + In most cases, instead of writing `shouldComponentUpdate()` by hand, you can inherit from [`React.PureComponent`](/docs/react-api.html#reactpurecomponent). It is equivalent to implementing `shouldComponentUpdate()` with a shallow comparison of current and previous props and state. +ほとんどの場合、手で shouldComponentUpdate() を書く代わりに、 React.PureComponent から継承できます。 現在と直前のプロパティや状態の浅い比較と一緒に、shouldComponentUpdate() を実装することと同じです。 ## shouldComponentUpdate In Action +## shouldComponentUpdate の実際の動作 Here's a subtree of components. For each one, `SCU` indicates what `shouldComponentUpdate` returned, and `vDOMEq` indicates whether the rendered React elements were equivalent. Finally, the circle's color indicates whether the component had to be reconciled or not. +以下のようなコンポーネントのサブツリーがあるとします。 +それぞれ、SCU は shouldComponentUpdate が返したものを示し、vDOMEq はレンダリングされた React 要素が等しかったかどうかを示します。 +最後に、円の色はコンポーネントに対してツリーを比較して合わせ込むための「突き合わせ」処理が(本来)必要だったのかどうかを示します。 +
Since `shouldComponentUpdate` returned `false` for the subtree rooted at C2, React did not attempt to render C2, and thus didn't even have to invoke `shouldComponentUpdate` on C4 and C5. +C2 をルートとするサブツリーでは shouldComponentUpdate が false を返したので、React は C2 をレンダリングしようとしませんでした。したがって C4 と C5 については shouldComponentUpdate を実行する必要すらなかったわけです。 + For C1 and C3, `shouldComponentUpdate` returned `true`, so React had to go down to the leaves and check them. For C6 `shouldComponentUpdate` returned `true`, and since the rendered elements weren't equivalent React had to update the DOM. +C1 と C3 では、shouldComponentUpdate が true を返したので、React は葉ノードにも移動してチェックする必要がありました。 +C6 では shouldComponentUpdate が true を返し、レンダリングされた要素は等しくなかったので、React は DOM を更新する必要がありました。 + The last interesting case is C8. React had to render this component, but since the React elements it returned were equal to the previously rendered ones, it didn't have to update the DOM. +最後に、興味深いケースが C8 です。React はこのコンポーネントをレンダリングする必要がありましたが、返された React 要素は以前にレンダリングされたものと一緒なので、DOM の更新は必要ありませんでした。 + Note that React only had to do DOM mutations for C6, which was inevitable. For C8, it bailed out by comparing the rendered React elements, and for C2's subtree and C7, it didn't even have to compare the elements as we bailed out on `shouldComponentUpdate`, and `render` was not called. +React が DOM を更新しなければならなかったのは、C6 だけだったことに注目してください。C6 の更新は避けられないものでした。 +C8 では、レンダリングされた React 要素の比較を実行してから処理が終わったのですが、C2 のサブツリーと C7 では shouldComponentUpdate のところで処理が終わって render メソッドが呼ばれなかったため、要素の比較は実行する必要すらありませんでした。 + ## Examples +## 例 If the only way your component ever changes is when the `props.color` or the `state.count` variable changes, you could have `shouldComponentUpdate` check that: +コンポーネントが変更される唯一の方法が props.color または state.count 変数が変更される時のみだとしたら、shouldComponentUpdate では以下のようなチェックを行えます: + ```javascript class CounterButton extends React.Component { constructor(props) { @@ -291,6 +415,12 @@ class CounterButton extends React.Component { In this code, `shouldComponentUpdate` is just checking if there is any change in `props.color` or `state.count`. If those values don't change, the component doesn't update. If your component got more complex, you could use a similar pattern of doing a "shallow comparison" between all the fields of `props` and `state` to determine if the component should update. This pattern is common enough that React provides a helper to use this logic - just inherit from `React.PureComponent`. So this code is a simpler way to achieve the same thing: +このコードでは、shouldComponentUpdate は単に props.color もしくは state.count に変更があったかチェックしているだけです。 +これらの値に変更がなければ、コンポーネントは更新されません。 +コンポーネントがより複雑な場合は、同じようなパターンで、props と state のすべてのフィールドの間で "浅い比較 (shallow comparison)" を行うことで、コンポーネントを更新するべきかを決定できます。 +このパターンはあまりに一般的なものなので、React はこのロジックを使用するためのヘルパーを提供しています ― React.PureComponent から継承するだけです。 +そのため以下のコードで前述のコードと同じことをよりシンプルに実装できます: + ```js class CounterButton extends React.PureComponent { constructor(props) { @@ -312,8 +442,15 @@ class CounterButton extends React.PureComponent { Most of the time, you can use `React.PureComponent` instead of writing your own `shouldComponentUpdate`. It only does a shallow comparison, so you can't use it if the props or state may have been mutated in a way that a shallow comparison would miss. +ほとんどの場合、自身で shouldComponentUpdate を記述する代わりに React.PureComponent を使うことができます。 +浅い (shallow) 比較を行うだけですので、浅く比較した場合に見失うような形で props や state が変更されてしまっている可能性がある場合には使えません。 +この事はもっと複雑なデータ構造を持つ場合には問題となります。 + This can be a problem with more complex data structures. For example, let's say you want a `ListOfWords` component to render a comma-separated list of words, with a parent `WordAdder` component that lets you click a button to add a word to the list. This code does *not* work correctly: +例えば、 カンマ区切りで単語をレンダリングする ListOfWords コンポーネントと、ボタンをクリックしてリストに単語を追加できる親コンポーネント WordAdder とが必要だとしましょう。 +以下のコードは正しく動作しません: + ```javascript class ListOfWords extends React.PureComponent { render() { @@ -350,10 +487,18 @@ class WordAdder extends React.Component { The problem is that `PureComponent` will do a simple comparison between the old and new values of `this.props.words`. Since this code mutates the `words` array in the `handleClick` method of `WordAdder`, the old and new values of `this.props.words` will compare as equal, even though the actual words in the array have changed. The `ListOfWords` will thus not update even though it has new words that should be rendered. +問題は PureComponent が this.props.words の古い値と新しい値を単純に比較することにあります。 +上記のコードでは WordAdder の handleClick メソッド内で words 配列の内容を変更するので、this.props.words の新旧の値は、たとえ配列内の実際の単語が変更されていたとしても、比較の結果同じだとみなしてしまうのです。 +そのため ListOfWords はレンダリングすべき新しい単語が追加されているにも関わらず、更新されません。 + ## The Power Of Not Mutating Data +## データを変更しないことの効果 The simplest way to avoid this problem is to avoid mutating values that you are using as props or state. For example, the `handleClick` method above could be rewritten using `concat` as: +この問題を避ける最も単純な方法は、props や state として使用している値の変更を避けることです。 +例えば、上記の handleClick メソッドは concat を使って以下のように書き換えることができます: + ```javascript handleClick() { this.setState(state => ({ @@ -364,6 +509,9 @@ handleClick() { ES6 supports a [spread syntax](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Spread_operator) for arrays which can make this easier. If you're using Create React App, this syntax is available by default. +ES6 はこれをより簡単に実装できる配列用のスプレッド構文をサポートしています。 +Create React App を使用していれば、この構文はデフォルトで利用できます。 + ```js handleClick() { this.setState(state => ({ @@ -374,6 +522,10 @@ handleClick() { You can also rewrite code that mutates objects to avoid mutation, in a similar way. For example, let's say we have an object named `colormap` and we want to write a function that changes `colormap.right` to be `'blue'`. We could write: +同様に、オブジェクトを変更するコードを変更が起きないものに書き換えることができます。 +例えば、colormap というオブジェクトがあり、colormap.right を 'blue' に変更する関数が必要だとしましょう。 +以下のように書くことも可能ですが… + ```js function updateColorMap(colormap) { colormap.right = 'blue'; @@ -382,6 +534,8 @@ function updateColorMap(colormap) { To write this without mutating the original object, we can use [Object.assign](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/assign) method: +元のオブジェクトを変更することなく実装するのには、Object.assign が使用できます: + ```js function updateColorMap(colormap) { return Object.assign({}, colormap, {right: 'blue'}); @@ -392,6 +546,11 @@ function updateColorMap(colormap) { There is a JavaScript proposal to add [object spread properties](https://github.com/sebmarkbage/ecmascript-rest-spread) to make it easier to update objects without mutation as well: + +これで、updateColorMap は古いオブジェクトを変更するのではなく新しいオブジェクトを返すようになります。Object.assign は ES6 からの機能であり、ポリフィルが必要です。 +オブジェクトでも変更を伴わない更新を容易にするオブジェクトのスプレッドプロパティを JavaScript に追加することが提案されています: + + ```js function updateColorMap(colormap) { return {...colormap, right: 'blue'}; @@ -400,15 +559,26 @@ function updateColorMap(colormap) { If you're using Create React App, both `Object.assign` and the object spread syntax are available by default. +Create React App を使用しているなら、Object.assign とオブジェクトのスプレッド構文の両方がデフォルトで利用できます。 + ## Using Immutable Data Structures +## イミュータブルなデータ構造の使用 [Immutable.js](https://github.com/facebook/immutable-js) is another way to solve this problem. It provides immutable, persistent collections that work via structural sharing: +Immutable.js はこの問題を解決する別の方法です。Immutable.js は構造の共有により動作する不変で永続的なデータのコレクションを提供します: + * *Immutable*: once created, a collection cannot be altered at another point in time. +* イミュータブル(不変性): 一度作成されたら、データのコレクションは他の時点で変更することはできない。 * *Persistent*: new collections can be created from a previous collection and a mutation such as set. The original collection is still valid after the new collection is created. +* 永続性: 新しいデータのコレクションは以前のコレクションか setメソッドなどによる変更で作成できる。元のデータのコレクションは新しいデータのコレクションが作成された後も有効である。 * *Structural Sharing*: new collections are created using as much of the same structure as the original collection as possible, reducing copying to a minimum to improve performance. +* 構造の共有: 新しいデータのコレクションを、可能な限り元のコレクションと同じ構造を利用して作ることで、データのコピー量を減らしてパフォーマンスを改善する。 Immutability makes tracking changes cheap. A change will always result in a new object so we only need to check if the reference to the object has changed. For example, in this regular JavaScript code: +不変性により変更を追跡することのコストが下がります。 +データの変更は常に新しいオブジェクトを作成することになるので、オブジェクトへの参照が変更されたかのみをチェックすればよくなるのです。 +例えば、以下の標準のJavaScriptコードで: ```javascript const x = { foo: 'bar' }; @@ -418,6 +588,8 @@ x === y; // true ``` Although `y` was edited, since it's a reference to the same object as `x`, this comparison returns `true`. You can write similar code with immutable.js: +y は編集されたにも関わらず、x と同じオブジェクトを参照しているため、上記の比較は true を返します。これと同様のコードは immutable.js でも書くことができますが: + ```javascript const SomeRecord = Immutable.Record({ foo: null }); @@ -430,6 +602,13 @@ x === z; // true In this case, since a new reference is returned when mutating `x`, we can use a reference equality check `(x === y)` to verify that the new value stored in `y` is different than the original value stored in `x`. +このケースでは、x に変更を加える際に新しい参照が返されるので、参照が同じであるかを比較する (x === y) ことで、y に保存されている新しい値が x に保存されていた値とは違うものだ、と確かめられます。 + Two other libraries that can help use immutable data are [seamless-immutable](https://github.com/rtfeldman/seamless-immutable) and [immutability-helper](https://github.com/kolodny/immutability-helper). +その他には、seamless-immutable や immutability-helper の2つのライブラリがイミュータブルなデータの使用に役立ちます。 + Immutable data structures provide you with a cheap way to track changes on objects, which is all we need to implement `shouldComponentUpdate`. This can often provide you with a nice performance boost. + +イミュータブルなデータ構造はオブジェクトにおける変更の追跡を容易にし、shouldComponentUpdate を実装する際にはこれを使うだけでよくなるのです。 +これによりパフォーマンスを大幅に向上できることがしばしばあります。 From de697b7139cea9012d6c555253693065c24baf4c Mon Sep 17 00:00:00 2001 From: "UEHARA, Junji" <59012+uehaj@users.noreply.github.com> Date: Sat, 9 Feb 2019 17:01:43 +0900 Subject: [PATCH 02/31] basic tranlation completed --- content/docs/optimizing-performance.md | 248 ++++++++++++++----------- 1 file changed, 136 insertions(+), 112 deletions(-) diff --git a/content/docs/optimizing-performance.md b/content/docs/optimizing-performance.md index d127753a7..7ce0f4b0e 100644 --- a/content/docs/optimizing-performance.md +++ b/content/docs/optimizing-performance.md @@ -8,9 +8,7 @@ redirect_from: Internally, React uses several clever techniques to minimize the number of costly DOM operations required to update the UI. For many applications, using React will lead to a fast user interface without doing much work to specifically optimize for performance. Nevertheless, there are several ways you can speed up your React application. -React は UI 更新時に必要となる高コストな DOM 操作の数を最小化するために、内部的にいくつかの賢いテクニックを使用しています。 -多くのアプリケーションでは、React を使用することで、苦労して特別にパフォーマンスを最適化することなく、高速なユーザーインターフェースを実現できます。 -それでもなお、React アプリケーションを高速化するための方法はいくつか存在します。 +React は UI の更新時に必要となる高コストな DOM 操作の回数を最小化するために、内部的にいくつかの賢いテクニックを使用しています。多くのアプリケーションでは React を使用するだけで、パフォーマンス向上のための特別な最適化で苦労しなくても、反応速度の速いユーザーインターフェースを実現できます。それでもなお、React アプリケーションを高速化するための方法はいくつか存在します。 ## Use the Production Build ## 本番用ビルドを使用する @@ -21,54 +19,57 @@ React アプリケーションでベンチマークを行う場合やパフォ By default, React includes many helpful warnings. These warnings are very useful in development. However, they make React larger and slower so you should make sure to use the production version when you deploy the app. -デフォルトで React は多くの有用な警告文を含んでいます。 -これらの警告文は開発時にはとても有用です。 -しかし、それらによって React は肥大化し、低速化するので、アプリケーションのデプロイ時には本番バージョンを使用していることを確認する必要があります。 +デフォルトで React は多くの有用な警告チェックを行いますが、これは開発時にはとても有用です。でもそもために React アプリケーションのサイズは肥大化し、速度が低下してしまうので、アプリケーションのデプロイ時には本番バージョンを使用していることを確認してください。 If you aren't sure whether your build process is set up correctly, you can check it by installing [React Developer Tools for Chrome](https://chrome.google.com/webstore/detail/react-developer-tools/fmkadmapgofadopljbjfkapdkoienihi). If you visit a site with React in production mode, the icon will have a dark background: -ビルドプロセスが正しく設定されているか分からない場合、React Developer Tools for Chrome をインストールして確認できます。 -本番用モードの React のサイトを訪れた場合、アイコンは暗い背景となっています: +ビルドプロセスが正しく設定されているか分からない場合、[React Developer Tools for Chrome](https://chrome.google.com/webstore/detail/react-developer-tools/fmkadmapgofadopljbjfkapdkoienihi) をインストールして確認できます。 +本番用モードの React のサイトを訪れた場合、アイコンは暗い背景となっています。 React DevTools on a website with production version of React If you visit a site with React in development mode, the icon will have a red background: -開発モードの React のサイトを訪れた場合、アイコンは赤い背景となっています: +開発モードの React のサイトを訪れた場合、アイコンは赤い背景となっています。 React DevTools on a website with development version of React It is expected that you use the development mode when working on your app, and the production mode when deploying your app to the users. -アプリケーションで作業中の場合は開発モードを使用し、ユーザーに向けてアプリケーションをデプロイする場合には本番用モードを使用することが推奨されます。 +アプリケーションに対して作業をしているときは開発モードを使用し、利用者に配布する場合には本番用モードを使用することをお勧めします。 You can find instructions for building your app for production below. -以下で本番用のアプリケーションのビルド手順を見ることができます。 +本番用にアプリを構築するための手順は以下のとおりです。 ### Create React App +### Reactアプリを作成する + If your project is built with [Create React App](https://github.com/facebookincubator/create-react-app), run: -プロジェクトが Create React App で構築されているなら、以下のコードを実行して下さい: +プロジェクトが [Create React App](https://github.com/facebookincubator/create-react-app) で構築されているなら、以下のコードを実行して下さい: ``` npm run build ``` This will create a production build of your app in the `build/` folder of your project. -これによりアプリケーションの本番用ビルドがプロジェクト内の build/ フォルダに作成されます。 + +これによりアプリケーションの本番用ビルドがプロジェクト内の `build/` フォルダに作成されます。 Remember that this is only necessary before deploying to production. For normal development, use `npm start`. -これは本番バージョンをデプロイする前のみ必要な作業であることに留意してください。通常の開発作業では、npm start を使用してください。 + +これは本番バージョンをデプロイする前のみ必要な作業であることに留意してください。通常の開発作業では、`npm start` を使用してください。 ### Single-File Builds ### 単一ファイル版ビルド We offer production-ready versions of React and React DOM as single files: -本番環境で使える、単一ファイル化されたバージョンの React と ReactDOM が提供されています。 + +React と ReactDOM をそれぞれ単一ファイル化した本番環境用のバージョンを提供しています。 ```html @@ -77,13 +78,13 @@ We offer production-ready versions of React and React DOM as single files: Remember that only React files ending with `.production.min.js` are suitable for production. -ファイル名の末尾が .production.min.js の React ファイルのみが本番用に適していることを覚えておいてください。 +本番用に適しているのは、React ファイル名の末尾が `.production.min.js` であるもののみであることに留意ください。 ### Brunch For the most efficient Brunch production build, install the [`uglify-js-brunch`](https://github.com/brunch/uglify-js-brunch) plugin: -最も効率のよい Brunch を使った本番用ビルドのために、uglify-js-brunch をインストールしてください: +Brunch で最も効率のよい本番用ビルドを行うためには、[`uglify-js-brunch`](https://github.com/brunch/uglify-js-brunch) をインストールしてください: ``` # If you use npm @@ -95,7 +96,7 @@ yarn add --dev uglify-js-brunch Then, to create a production build, add the `-p` flag to the `build` command: -本番用ビルドを作成する際は、-p フラグを build コマンドに追加します: +そして、本番用ビルドを作成するために、`build` コマンドに`-p` オプションを指定して実行します。 ``` brunch build -p @@ -104,15 +105,13 @@ brunch build -p Remember that you only need to do this for production builds. You shouldn't pass the `-p` flag or apply this plugin in development, because it will hide useful React warnings and make the builds much slower. -これは本番用ビルドにのみ必要な作業であることに留意してください。 -開発用では -p フラグを指定したり、このプラグインを適用すると React の有用な警告文を隠したり、ビルド速度が大幅に遅くなるので使用しないでください。 +これが必要なのは本番用ビルドだけであることに留意してください。React の有用な警告表示が隠されたり、ビルド速度が大幅に遅くなったりしますので、開発用では `-p` フラグを指定したり、`uglify-js-brunch` プラグインを適用したりしないでください。 ### Browserify For the most efficient Browserify production build, install a few plugins: -最も効率の良い Browserify による本番用ビルドを行うため、いくつかプラグインをインストールしてください: - +Browserify で最も効率の良い本番用ビルドを行うため、いくつかのプラグインをインストールしてください。 ``` # If you use npm @@ -123,20 +122,22 @@ yarn add --dev envify uglify-js uglifyify ``` To create a production build, make sure that you add these transforms **(the order matters)**: -本番用ビルドを作成するには、以下のトランスフォームを追加してください(順番通りに追加してください): + +本番用ビルドを作成するには、以下の変換(transform)を追加してください(**順番は重要です**)。 * The [`envify`](https://github.com/hughsk/envify) transform ensures the right build environment is set. Make it global (`-g`). -* envify トランスフォームは正しいビルド環境が設定されていることを保証します。グローバルに設定してください (-g)。 + +* [`envify`](https://github.com/hughsk/envify) 変換は正しいビルド環境が確実に設定されるようにします。グローバルに設定してください (`-g`)。 * The [`uglifyify`](https://github.com/hughsk/uglifyify) transform removes development imports. Make it global too (`-g`). -* uglifyify トランスフォームは開発用にインポートしたライブラリを削除します。これもグローバルに設定してください (-g)。 +* [`uglifyify`](https://github.com/hughsk/uglifyify) 変換は開発用にインポートしたライブラリを削除します。これもグローバルに設定してください (`-g`)。 * Finally, the resulting bundle is piped to [`uglify-js`](https://github.com/mishoo/UglifyJS2) for mangling ([read why](https://github.com/hughsk/uglifyify#motivationusage)). -* 最後に結果として出力されたものを、名前の圧縮のために uglify-js にパイプします(理由はこちら)。 +* 最後に結果として出力されたものを、名前の圧縮のために [`uglify-js`](https://github.com/mishoo/UglifyJS2) にパイプします([理由を読む](https://github.com/hughsk/uglifyify#motivationusage))。 For example: -例えば: +以下に例を示します。 ``` browserify ./index.js \ @@ -149,16 +150,19 @@ browserify ./index.js \ > >The package name is `uglify-js`, but the binary it provides is called `uglifyjs`.
>This is not a typo. ->パッケージ名は uglify-js ですが、パッケージが提供するバイナリは uglifyjs という名前です。タイプミスではありません。 +> +>パッケージ名は `uglify-js` ですが、パッケージが提供するバイナリ名は `uglifyjs` です。タイプミスではありません。 Remember that you only need to do this for production builds. You shouldn't apply these plugins in development because they will hide useful React warnings, and make the builds much slower. -これは本番用ビルドにのみ必要な作業であることに留意してください。これらのプラグインは開発版に適用すると React の有用な警告文を隠して、ビルド速度を遅くしていまいます。 + +これが必要なのは本番用ビルドだけであることに留意してください。React の有用な警告文が隠されたり、ビルド速度が大幅に遅くなったりしますので、開発用ではこれらのプラグインを適用しないで下さい。 ### Rollup For the most efficient Rollup production build, install a few plugins: -最も効率の良い Rollup による本番用ビルドを行うため、いくつかプラグインをインストールします: + +Rollup で最も効率のよい本番用ビルドを行うためには、いくつかのプラグインを以下のようにインストールします。 ``` # If you use npm @@ -169,16 +173,17 @@ yarn add --dev rollup-plugin-commonjs rollup-plugin-replace rollup-plugin-uglify ``` To create a production build, make sure that you add these plugins **(the order matters)**: -本番用ビルドを作成するには、以下のプラグインを追加してください(順番通りに追加してください): + +本番用ビルドを作成するには、以下のプラグインを追加してください(**順番は重要です**)。 * The [`replace`](https://github.com/rollup/rollup-plugin-replace) plugin ensures the right build environment is set. -* replace プラグインは確実に正しいビルド環境が設定されるようにします。 +* [`replace`](https://github.com/rollup/rollup-plugin-replace) プラグインは正しいビルド環境が確実に設定されるようにします。 * The [`commonjs`](https://github.com/rollup/rollup-plugin-commonjs) plugin provides support for CommonJS in Rollup. -* commonjs プラグインは Rollup で CommonJS をサポートできるようにします。 +* [`commonjs`](https://github.com/rollup/rollup-plugin-commonjs) プラグインは Rollup で CommonJS をサポートできるようにします。 * The [`uglify`](https://github.com/TrySound/rollup-plugin-uglify) plugin compresses and mangles the final bundle. -* uglify プラグインは最後の出力されたものを圧縮して余分なものを削ぎ落とします。 +* [`uglify`](https://github.com/TrySound/rollup-plugin-uglify) プラグインは出力された最終的なバンドルを圧縮し、mangle(訳注: 変数名や識別子を短縮)します。 ```js plugins: [ @@ -193,13 +198,13 @@ plugins: [ ``` For a complete setup example [see this gist](https://gist.github.com/Rich-Harris/cb14f4bc0670c47d00d191565be36bf0). -設定例の全体はこの gist を確認してください。 + +設定例の全体はこの [gist を参照](https://gist.github.com/Rich-Harris/cb14f4bc0670c47d00d191565be36bf0)してください。 Remember that you only need to do this for production builds. You shouldn't apply the `uglify` plugin or the `replace` plugin with `'production'` value in development because they will hide useful React warnings, and make the builds much slower. -これは本番用ビルドにのみ必要な作業であることに留意してください。 -React の有用な警告文が隠され、ビルド速度が大幅に遅くなるので、開発環境で 'production' という値で uglify プラグインもしくは replace プラグインを適用しないでください。 +これが必要なのは本番用ビルドだけであることに留意してください。React の有用な警告表示が隠されたり、ビルド速度が大幅に遅くなったりしますので、開発用では `uglify` プラグインもしくは `replace` プラグインを`'production'` という値で適用しないでください。 ### webpack @@ -207,11 +212,13 @@ React の有用な警告文が隠され、ビルド速度が大幅に遅くな > >If you're using Create React App, please follow [the instructions above](#create-react-app).
>This section is only relevant if you configure webpack directly. -> Create React App を利用している場合は、上記のガイドに従うようにしてください。 +> +> Create React App を利用している場合は、[上記のガイド](#create-react-app)に従ってください。 >このセクションは直接 webpack の設定を行いたい人向けです。 For the most efficient webpack production build, make sure to include these plugins in your production configuration: -効率的な本番用ビルドを生成するために、本番環境の設定中に必ず以下のプラグインを含めるようにしてください。 + +webpack で最も効率のよい本番用ビルドを行うためには、本番ビルドの設定中に必ず以下のプラグインを含めるようにしてください。 ```js new webpack.DefinePlugin({ @@ -221,120 +228,145 @@ new webpack.optimize.UglifyJsPlugin() ``` You can learn more about this in [webpack documentation](https://webpack.js.org/guides/production-build/). -詳細な説明は webpack のドキュメントにあります。 + +より詳細な説明については [webpack のドキュメント](https://webpack.js.org/guides/production-build/)を参照ください。 Remember that you only need to do this for production builds. You shouldn't apply `UglifyJsPlugin` or `DefinePlugin` with `'production'` value in development because they will hide useful React warnings, and make the builds much slower. -これは本番用ビルドにのみ必要な作業であることに留意してください。 -React の有用な警告文が隠され、ビルド速度が大幅に遅くなるので、開発環境で 'production' という値で UglifyJsPlugin もしくは DefinePlugin を適用しないでください。 + +これが必要なのは本番用ビルドだけであることに留意してください。React の有用な警告文が隠されたり、ビルド速度が大幅に遅くなったりしますので、開発用では `UglifyJsPlugin` もしくは `DefinePlugin` を`'production'` という値で適用しないでください。 ## Profiling Components with the Chrome Performance Tab ## Chrome のパフォーマンスタブでコンポーネントをプロファイルする In the **development** mode, you can visualize how components mount, update, and unmount, using the performance tools in supported browsers. For example: -開発モードでは、対応ブラウザのパフォーマンス分析ツールを使って、どのようにコンポーネントがマウントし、更新して、アンマウントするのかを視覚化することができます。例えば: + +**開発** モードでは、対応ブラウザのパフォーマンス分析ツールでコンポーネントのマウント・更新・アンマウントの様子を視覚化することができます。例えば以下のとおり。
React components in Chrome timeline
To do this in Chrome: -Chrome でこれを行うには: + +Chrome でこれを行うには以下を行います。 1. Temporarily **disable all Chrome extensions, especially React DevTools**. They can significantly skew the results! -1. 一時的に React DevTools を含むすべての Chrome 拡張機能を無効にする。無効にしないと、結果が正確でなくなる可能性があります。 +1. 一時的に **React DevTools を含むすべての Chrome 拡張機能を無効にする**。無効にしないと、結果が正確でなくなる可能性があります。 2. Make sure you're running the application in the development mode. -2. 開発モードでアプリケーションが動作していることを確認する。 +2. アプリケーションが開発モードで動作していることを確認する。 3. Open the Chrome DevTools **[Performance](https://developers.google.com/web/tools/chrome-devtools/evaluate-performance/timeline-tool)** tab and press **Record**. -3. Chrome DevTools のパフォーマンスタブを開いて記録ボタンを押す。 +3. Chrome DevTools の**[パフォーマンス](https://developers.google.com/web/tools/chrome-devtools/evaluate-performance/timeline-tool)タブ**を開いて **Record(記録)** ボタンを押す。 4. Perform the actions you want to profile. Don't record more than 20 seconds or Chrome might hang. -4. プロファイル対象のアクションを実行する。20秒以上記録しないでください、さもなくば Chrome がハングすることがあります。 +4. プロファイル対象のアクションを実行する。なお、20秒以上は記録しないでください。さもないと Chrome がハングアップすることがあります。 5. Stop recording. 5. 記録を停止する。 6. React events will be grouped under the **User Timing** label. -6. Reactイベントが User Timing ラベルの下にグループ化される。 +6. React イベントが **User Timing** ラベルの下にグループ化される。 For a more detailed walkthrough, check out [this article by Ben Schwarz](https://calibreapp.com/blog/2017-11-28-debugging-react/). Reactイベントが User Timing ラベルの下にグループ化される。 Note that **the numbers are relative so components will render faster in production**. Still, this should help you realize when unrelated UI gets updated by mistake, and how deep and how often your UI updates occur. -プロファイル結果の数字は相対的なものであり、コンポーネントは本番環境ではより速くレンダリングされることに注意してください。 + +**プロファイル結果の数値は相対的なものであり、コンポーネントは本番環境ではより速くレンダリングされる**ことに注意してください。 それでも、関係のない UI が誤って更新されているのを見つけたり、どの程度の頻度と深さで UI の更新が発生するのかを知る手助けになるはずです。 Currently Chrome, Edge, and IE are the only browsers supporting this feature, but we use the standard [User Timing API](https://developer.mozilla.org/en-US/docs/Web/API/User_Timing_API) so we expect more browsers to add support for it. -現時点では、Chrome、Edge、そして IE のみがこの機能をサポートするブラウザですが、私達は標準の User Timing API を採用しているので、より多くのブラウザがサポートしてくれることを期待しています。 +現時点では、Chrome、Edge、そして IE のみがこの機能をサポートするブラウザですが、私達は標準の [User Timing API](https://developer.mozilla.org/en-US/docs/Web/API/User_Timing_API) を採用しているので、より多くのブラウザがサポートしてくれることを期待しています。 ## Profiling Components with the DevTools Profiler -## 長いリストの仮想化 +## DevToolsプロファイラを使用したコンポーネントのプロファイリング `react-dom` 16.5+ and `react-native` 0.57+ provide enhanced profiling capabilities in DEV mode with the React DevTools Profiler. An overview of the Profiler can be found in the blog post ["Introducing the React Profiler"](/blog/2018/09/10/introducing-the-react-profiler.html). A video walkthrough of the profiler is also [available on YouTube](https://www.youtube.com/watch?v=nySib7ipZdk). -アプリケーションがデータの長いリスト(数百〜数千行) を描画する場合は、 「ウィンドウイング」 と呼ばれる技術を使用することをおすすめします。 この技術は任意の時点での行の小さなサブセットのみを描画し、作成されたDOM ノードの数と同じく、コンポーネントの再描画にかかる時間を大幅に削減することができます。 -React Virtualized は人気のあるウィンドウイングのライブラリのひとつです。 リスト、グリッド、および表形式のデータを表示するための、いくつかの再利用可能なコンポーネントを提供しています。 Twitter のようにアプリケーションの特定のユースケースに合わせてより多くの何かをしたい場合は、独自のウィンドウイングのコンポーネントを作成することもできます。 + +`react-dom` 16.5 以降と`react-native` 0.57 以降では、DEV モードにおける強化されたプロファイリング機能を React DevTools プロファイラにて提供しています。このプロファイラの概要がブログ記事「[Introduction the React Profiler](/blog/2018/09/10/introducing-the-react-profiler.html)」で説明されています。チュートリアル動画も[YouTubeで入手できます](https://www.youtube.com/watch?v=nySib7ipZdk)。 + If you haven't yet installed the React DevTools, you can find them here: -- [Chrome Browser Extension](https://chrome.google.com/webstore/detail/react-developer-tools/fmkadmapgofadopljbjfkapdkoienihi?hl=en) -- [Firefox Browser Extension](https://addons.mozilla.org/en-GB/firefox/addon/react-devtools/) -- [Standalone Node Package](https://www.npmjs.com/package/react-devtools) +React DevToolsをまだインストールしていない場合は、以下で見つけることができます。 + +- [Chromeブラウザ拡張](https://chrome.google.com/webstore/detail/react-developer-tools/fmkadmapgofadopljbjfkapdkoienihi?hl=en) +- [Firefoxブラウザ拡張](https://addons.mozilla.org/en-GB/firefox/addon/react-devtools/) +- [スタンドアロンのNodeパッケージ](https://www.npmjs.com/package/react-devtools) > Note > > A production profiling bundle of `react-dom` is also available as `react-dom/profiling`. > Read more about how to use this bundle at [fb.me/react-profiling](https://fb.me/react-profiling) +> +> 注意 +> +> 本番ビルド版 `react-dom` のプロファイリング可能なバンドルは `react-dom/profiling` として利用可能です。このバンドルの使い方の詳細については、[fb.me/react-profiling](https://fb.me/react-profiling) を参照してください。 ## Virtualize Long Lists +## 長いリストの仮想化 If your application renders long lists of data (hundreds or thousands of rows), we recommended using a technique known as "windowing". This technique only renders a small subset of your rows at any given time, and can dramatically reduce the time it takes to re-render the components as well as the number of DOM nodes created. +アプリケーションがデータの長いリスト(数百〜数千行)を描画する場合は、「ウィンドウイング」として知られるテクニックを使うことをおすすめします。このテクニックでは、ある瞬間においてリストの小さな部分集合のみを描画することで、作成する DOM ノードの数およびコンポーネントの再描画にかかる時間を大幅に削減することができます。 + [react-window](https://react-window.now.sh/) and [react-virtualized](https://bvaughn.github.io/react-virtualized/) are popular windowing libraries. They provide several reusable components for displaying lists, grids, and tabular data. You can also create your own windowing component, like [Twitter did](https://medium.com/@paularmstrong/twitter-lite-and-high-performance-react-progressive-web-apps-at-scale-d28a00e780a3), if you want something more tailored to your application's specific use case. +[react-window](https://react-window.now.sh/)と[react-virtualized](https://bvaughn.github.io/react-virtualized/)はウィンドウイング処理のための人気があるライブラリです。これらはリスト、グリッド、および表形式のデータを表示するための、いくつかの再利用可能コンポーネントを提供しています。[Twitter did](https://medium.com/@paularmstrong/twitter-lite-and-high-performance-react-progressive-web-apps-at-scale-d28a00e780a3)が行なっているように、アプリケーションの特定のユースケースに合わせてより多くの何かをしたい場合は、独自のウィンドウイング処理のコンポーネントを作成することもできます。 + + ## Avoid Reconciliation -## ツリーの突き合わせ処理を避ける +## リコンシリエーション(差分検出、突き合せ処理)を避ける React builds and maintains an internal representation of the rendered UI. It includes the React elements you return from your components. This representation lets React avoid creating DOM nodes and accessing existing ones beyond necessity, as that can be slower than operations on JavaScript objects. Sometimes it is referred to as a "virtual DOM", but it works the same way on React Native. -React はレンダリングされた UI の内部表現を構築して維持します。 -それにはユーザ自身のコンポーネントから返された React 要素も含まれます。 -この内部表現を使って React は、JavaScript オブジェクトの操作よりも遅くなりうる DOM ノードの作成や DOM ノードへのアクセスを必要以上に行うことを回避します。 -しばしばこの内部表現は "仮想DOM (virtual DOM)" と呼ばれますが、React Native でも同様に動作します。 +React はレンダリングされた UI の内部表現を構築し、維持します。それにはコンポーネントが返した React 要素も含まれています。 +この内部表現を使うことで React は、JavaScript オブジェクトの操作よりも遅くなりうる DOM ノードの作成やアクセスを必要以上に行うことを回避します。しばしばこの内部表現は "仮想DOM (virtual DOM)" と呼ばれますが、React Native でも同様に動作します。 When a component's props or state change, React decides whether an actual DOM update is necessary by comparing the newly returned element with the previously rendered one. When they are not equal, React will update the DOM. -コンポーネントの props か state が変更された場合、React は新しく返された要素を以前にレンダリングされたものと比較することで、本物の DOM の更新が必要かを判断します。 -それらが等しくない場合、React は DOM を更新します。 +コンポーネントの props か state が変更された場合、React は新しく返された要素を以前にレンダリングされたものと比較することで、本物の DOM の更新が必要かを判断します。それらが等しくない場合、React は DOM を更新します。 You can now visualize these re-renders of the virtual DOM with React DevTools: - -それらが等しくない場合、React は DOM を更新します。 +React DevToolsを使用して仮想DOMのこれらの再レンダリングを視覚化できるようになりました。 - [Chrome Browser Extension](https://chrome.google.com/webstore/detail/react-developer-tools/fmkadmapgofadopljbjfkapdkoienihi?hl=en) - [Firefox Browser Extension](https://addons.mozilla.org/en-GB/firefox/addon/react-devtools/) - [Standalone Node Package](https://www.npmjs.com/package/react-devtools) + +- [Chromeブラウザ拡張](https://chrome.google.com/webstore/detail/react-developer-tools/fmkadmapgofadopljbjfkapdkoienihi?hl=en) +- [Firefoxブラウザ拡張](https://addons.mozilla.org/en-GB/firefox/addon/react-devtools/) +- [スタンドアロンNodeパッケージ](https://www.npmjs.com/package/react-devtools) + In the developer console select the **Highlight Updates** option in the **React** tab: -デベロッパコンソールのReact タブで Highlight Updates オプションを選択します: + +開発者コンソールの **React** タブで **Highlight Updates** オプションを選択します:
How to enable highlight updates
Interact with your page and you should see colored borders momentarily appear around any components that have re-rendered. This lets you spot re-renders that were not necessary. You can learn more about this React DevTools feature from this [blog post](https://blog.logrocket.com/make-react-fast-again-part-3-highlighting-component-updates-6119e45e6833) from [Ben Edelstein](https://blog.logrocket.com/@edelstein). +ページを操作すると、再レンダリングされたコンポーネントの周囲に色付きの枠線が一定時間表示されます。これにより、不要な再レンダリングを見つけることができます。この React DevTools 機能の詳細については、[Ben Edelstein](https://blog.logrocket.com/@edelstein)による[このブログ投稿](https://blog.logrocket.com/make-react-fast-again-part-3-highlighting-component-updates-6119e45e6833)から学ぶことができます。 + Consider this example: +以下の例を考えてください。 +
React DevTools Highlight Updates example
Note that when we're entering a second todo, the first todo also flashes on the screen on every keystroke. This means it is being re-rendered by React together with the input. This is sometimes called a "wasted" render. We know it is unnecessary because the first todo content has not changed, but React doesn't know this. -2つ目のTODOを入力しているとき、1つ目のTODOもキーストロークの度に画面上で点滅することに注意してください。 これは、 React が入力によって一緒に再描画していることを意味します。 これは「無駄な」描画と呼ばれることがあります。 我々は 最初の TODO は、内容が変わっていないために再描画の必要がないことを知っていますが、 React はそれを知りません。 -この関数のデフォルトの実装は true を返し、React にそのまま更新処理を実行させます: +2つ目の TODO を入力しているとき、1つ目の TODO もキーストロークの度に画面上で点滅することに注意してください。これは、React が入力によって一緒に再レンダリングしていることを意味します。 これは「無駄な」レンダリングと呼ばれることがあります。最初の TODO の内 +容は変更されておらず、再レンダリングの必要がないことを我々は知っていますが、React はそれを知りません。 Even though React only updates the changed DOM nodes, re-rendering still takes some time. In many cases it's not a problem, but if the slowdown is noticeable, you can speed all of this up by overriding the lifecycle function `shouldComponentUpdate`, which is triggered before the re-rendering process starts. The default implementation of this function returns `true`, leaving React to perform the update: +React は変更された DOM ノードしか更新しないとはいえ、再レンダリングには時間がかかります。多少の時間がかかっても多くの場合は問題にはなりませんが、遅延が目立つ場合、再レンダリングプロセスが開始される前にトリガーされるライフサイクル関数 `shouldComponentUpdate` をオーバーライドすることで、スピードを全面的に向上できます。この関数のデフォルトの実装は `true`を返し、React にそのまま更新処理を実行させます。 + ```javascript shouldComponentUpdate(nextProps, nextState) { return true; @@ -343,46 +375,44 @@ shouldComponentUpdate(nextProps, nextState) { If you know that in some situations your component doesn't need to update, you can return `false` from `shouldComponentUpdate` instead, to skip the whole rendering process, including calling `render()` on this component and below. -いくつかの状況においてコンポーネントが更新される必要がないと分かっているなら、shouldComponentUpdate から代わりに false を返すことにより、該当コンポーネントおよび配下への render() 呼び出しを含む、レンダリング処理の全体をスキップすることができます。 +ある状況においてコンポーネントが更新される必要がないと分かっているなら、`shouldComponentUpdate` から代わりに `false` を返すことにより、該当コンポーネントおよび配下への `render()` 呼び出しを含む、レンダリング処理の全体をスキップすることができます。 In most cases, instead of writing `shouldComponentUpdate()` by hand, you can inherit from [`React.PureComponent`](/docs/react-api.html#reactpurecomponent). It is equivalent to implementing `shouldComponentUpdate()` with a shallow comparison of current and previous props and state. -ほとんどの場合、手で shouldComponentUpdate() を書く代わりに、 React.PureComponent から継承できます。 現在と直前のプロパティや状態の浅い比較と一緒に、shouldComponentUpdate() を実装することと同じです。 + +ほとんどの場合、手で `shouldComponentUpdate()` を書く代わりに、[`React.PureComponent`](/docs/react-api.html#reactpurecomponent)から継承できます。 これは現在と直前の props と state に対する浅い比較(Shallow Comparison)を行うような `shouldComponentUpdate()` を実装することと同じです。 ## shouldComponentUpdate In Action ## shouldComponentUpdate の実際の動作 Here's a subtree of components. For each one, `SCU` indicates what `shouldComponentUpdate` returned, and `vDOMEq` indicates whether the rendered React elements were equivalent. Finally, the circle's color indicates whether the component had to be reconciled or not. -以下のようなコンポーネントのサブツリーがあるとします。 -それぞれ、SCU は shouldComponentUpdate が返したものを示し、vDOMEq はレンダリングされた React 要素が等しかったかどうかを示します。 -最後に、円の色はコンポーネントに対してツリーを比較して合わせ込むための「突き合わせ」処理が(本来)必要だったのかどうかを示します。 +以下のようなコンポーネントのサブツリーがあるとします。それぞれ、`SCU` は `shouldComponentUpdate` が返したもの(訳注: 緑はtrue、赤は false)を示し、`vDOMEq` はレンダリングされた React 要素が等しかったかどうか(訳注: 緑は等しい、赤は等しくない)を示します。 +最後に、円の色はコンポーネントに対してツリーを比較して合わせ込むためのリコンシリエーション処理が(本来)必要だったのかどうか(訳注: 緑は不要、赤は必要)を示します。
Since `shouldComponentUpdate` returned `false` for the subtree rooted at C2, React did not attempt to render C2, and thus didn't even have to invoke `shouldComponentUpdate` on C4 and C5. -C2 をルートとするサブツリーでは shouldComponentUpdate が false を返したので、React は C2 をレンダリングしようとしませんでした。したがって C4 と C5 については shouldComponentUpdate を実行する必要すらなかったわけです。 +C2 をルートとするサブツリーでは `shouldComponentUpdate` が `false` を返したので、React は C2 をレンダリングしようとしませんでした。したがって C4 と C5 については `shouldComponentUpdate` を実行する必要すらなかったわけです。 For C1 and C3, `shouldComponentUpdate` returned `true`, so React had to go down to the leaves and check them. For C6 `shouldComponentUpdate` returned `true`, and since the rendered elements weren't equivalent React had to update the DOM. -C1 と C3 では、shouldComponentUpdate が true を返したので、React は葉ノードにも移動してチェックする必要がありました。 -C6 では shouldComponentUpdate が true を返し、レンダリングされた要素は等しくなかったので、React は DOM を更新する必要がありました。 +C1 と C3 では、`shouldComponentUpdate` が `true` を返したので、React は葉ノードにも移動してチェックする必要がありました。C6 では `shouldComponentUpdate` が `true` を返し、レンダリングされた要素は等しくなかったので、React は DOM を更新する必要がありました。 The last interesting case is C8. React had to render this component, but since the React elements it returned were equal to the previously rendered ones, it didn't have to update the DOM. -最後に、興味深いケースが C8 です。React はこのコンポーネントをレンダリングする必要がありましたが、返された React 要素は以前にレンダリングされたものと一緒なので、DOM の更新は必要ありませんでした。 +最後の興味深いケースが C8 です。React はこのコンポーネントをレンダリングする必要がありましたが、返された React 要素は前回レンダリングされたときものと同じだったので、DOM の更新は必要ありませんでした。 Note that React only had to do DOM mutations for C6, which was inevitable. For C8, it bailed out by comparing the rendered React elements, and for C2's subtree and C7, it didn't even have to compare the elements as we bailed out on `shouldComponentUpdate`, and `render` was not called. -React が DOM を更新しなければならなかったのは、C6 だけだったことに注目してください。C6 の更新は避けられないものでした。 -C8 では、レンダリングされた React 要素の比較を実行してから処理が終わったのですが、C2 のサブツリーと C7 では shouldComponentUpdate のところで処理が終わって render メソッドが呼ばれなかったため、要素の比較は実行する必要すらありませんでした。 +React が DOM を更新しなければならなかったのは、C6 だけだったことに注目してください。C6 の更新は避けられないものでした。C8 では、レンダリングされた React 要素の比較を実行してから処理が終わったのですが、C2 のサブツリーと C7 では `shouldComponentUpdate` のところで処理が終わって render メソッドが呼ばれなかったため、要素の比較は実行する必要すらありませんでした。 ## Examples ## 例 If the only way your component ever changes is when the `props.color` or the `state.count` variable changes, you could have `shouldComponentUpdate` check that: -コンポーネントが変更される唯一の方法が props.color または state.count 変数が変更される時のみだとしたら、shouldComponentUpdate では以下のようなチェックを行えます: +コンポーネントが変更される唯一の方法が `props.color` または `state.count` 変数が変化した時のみだとしたら、`shouldComponentUpdate` では以下のようなチェックを行えます。 ```javascript class CounterButton extends React.Component { @@ -415,11 +445,7 @@ class CounterButton extends React.Component { In this code, `shouldComponentUpdate` is just checking if there is any change in `props.color` or `state.count`. If those values don't change, the component doesn't update. If your component got more complex, you could use a similar pattern of doing a "shallow comparison" between all the fields of `props` and `state` to determine if the component should update. This pattern is common enough that React provides a helper to use this logic - just inherit from `React.PureComponent`. So this code is a simpler way to achieve the same thing: -このコードでは、shouldComponentUpdate は単に props.color もしくは state.count に変更があったかチェックしているだけです。 -これらの値に変更がなければ、コンポーネントは更新されません。 -コンポーネントがより複雑な場合は、同じようなパターンで、props と state のすべてのフィールドの間で "浅い比較 (shallow comparison)" を行うことで、コンポーネントを更新するべきかを決定できます。 -このパターンはあまりに一般的なものなので、React はこのロジックを使用するためのヘルパーを提供しています ― React.PureComponent から継承するだけです。 -そのため以下のコードで前述のコードと同じことをよりシンプルに実装できます: +このコードは、`shouldComponentUpdate` は単に `props.color` もしくは `state.count` が変化しているかをチェックしているだけです。これらの値に変化がなければ、コンポーネントは更新されません。コンポーネントがもっと複雑な場合は、`props` と `state` のすべてのフィールドに対して "浅い比較(Shallow Comparison)" をするという同種のパターンでコンポーネントを更新するべきかを決定できます。このパターンはあまりに一般的なので、React はこのロジックのためのヘルパーを用意しており、`React.PureComponent` から継承するだけで使用できます。だから以下のコードで前述のコードと同じことをよりシンプルに実装できます。 ```js class CounterButton extends React.PureComponent { @@ -442,14 +468,12 @@ class CounterButton extends React.PureComponent { Most of the time, you can use `React.PureComponent` instead of writing your own `shouldComponentUpdate`. It only does a shallow comparison, so you can't use it if the props or state may have been mutated in a way that a shallow comparison would miss. -ほとんどの場合、自身で shouldComponentUpdate を記述する代わりに React.PureComponent を使うことができます。 -浅い (shallow) 比較を行うだけですので、浅く比較した場合に見失うような形で props や state が変更されてしまっている可能性がある場合には使えません。 -この事はもっと複雑なデータ構造を持つ場合には問題となります。 +ほとんどの場合、自分で `shouldComponentUpdate` を記述する代わりに `React.PureComponent` を使うことができます。浅い(shallow)比較を行うだけですので、浅い比較では検出できない形で props や state が変更されている可能性がある場合には使えません。 This can be a problem with more complex data structures. For example, let's say you want a `ListOfWords` component to render a comma-separated list of words, with a parent `WordAdder` component that lets you click a button to add a word to the list. This code does *not* work correctly: -例えば、 カンマ区切りで単語をレンダリングする ListOfWords コンポーネントと、ボタンをクリックしてリストに単語を追加できる親コンポーネント WordAdder とが必要だとしましょう。 -以下のコードは正しく動作しません: + +この事はもっと複雑なデータ構造を持つ場合には問題となります。例えば、 カンマ区切りで単語をレンダリングする `ListOfWords` コンポーネントと、ボタンをクリックしてリストに単語を追加できる親コンポーネント `WordAdder` が必要だとしましょう。以下のコードは正しく動作しません。 ```javascript class ListOfWords extends React.PureComponent { @@ -487,9 +511,9 @@ class WordAdder extends React.Component { The problem is that `PureComponent` will do a simple comparison between the old and new values of `this.props.words`. Since this code mutates the `words` array in the `handleClick` method of `WordAdder`, the old and new values of `this.props.words` will compare as equal, even though the actual words in the array have changed. The `ListOfWords` will thus not update even though it has new words that should be rendered. -問題は PureComponent が this.props.words の古い値と新しい値を単純に比較することにあります。 -上記のコードでは WordAdder の handleClick メソッド内で words 配列の内容を変更するので、this.props.words の新旧の値は、たとえ配列内の実際の単語が変更されていたとしても、比較の結果同じだとみなしてしまうのです。 -そのため ListOfWords はレンダリングすべき新しい単語が追加されているにも関わらず、更新されません。 +問題は `PureComponent` が `this.props.words` の古い値と新しい値を単純に比較することにあります。 +上記のコードでは `WordAdder` の handleClick メソッド内で `words` 配列の内容を変更するので、`this.props.words` の新旧の値は、たとえ配列内の実際の単語が変更されていたとしても、比較の結果同じだとみなしてしまうのです。 +そのため `ListOfWords` はレンダリングすべき新しい単語が追加されているにも関わらず、更新されません。 ## The Power Of Not Mutating Data ## データを変更しないことの効果 @@ -497,7 +521,7 @@ The problem is that `PureComponent` will do a simple comparison between the old The simplest way to avoid this problem is to avoid mutating values that you are using as props or state. For example, the `handleClick` method above could be rewritten using `concat` as: この問題を避ける最も単純な方法は、props や state として使用している値の変更を避けることです。 -例えば、上記の handleClick メソッドは concat を使って以下のように書き換えることができます: +例えば、上記の `handleClick` メソッドは `concat` を使って以下のように書き換えることができます: ```javascript handleClick() { @@ -509,7 +533,7 @@ handleClick() { ES6 supports a [spread syntax](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Spread_operator) for arrays which can make this easier. If you're using Create React App, this syntax is available by default. -ES6 はこれをより簡単に実装できる配列用のスプレッド構文をサポートしています。 +ES6 はこれをより簡単に実装できる配列用の[スプレッド構文](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Spread_operator)をサポートしています。 Create React App を使用していれば、この構文はデフォルトで利用できます。 ```js @@ -523,7 +547,7 @@ handleClick() { You can also rewrite code that mutates objects to avoid mutation, in a similar way. For example, let's say we have an object named `colormap` and we want to write a function that changes `colormap.right` to be `'blue'`. We could write: 同様に、オブジェクトを変更するコードを変更が起きないものに書き換えることができます。 -例えば、colormap というオブジェクトがあり、colormap.right を 'blue' に変更する関数が必要だとしましょう。 +例えば、`colormap` というオブジェクトがあり、`colormap.right` を `'blue'` に変更する関数が必要だとしましょう。 以下のように書くことも可能ですが… ```js @@ -547,8 +571,9 @@ function updateColorMap(colormap) { There is a JavaScript proposal to add [object spread properties](https://github.com/sebmarkbage/ecmascript-rest-spread) to make it easier to update objects without mutation as well: -これで、updateColorMap は古いオブジェクトを変更するのではなく新しいオブジェクトを返すようになります。Object.assign は ES6 からの機能であり、ポリフィルが必要です。 -オブジェクトでも変更を伴わない更新を容易にするオブジェクトのスプレッドプロパティを JavaScript に追加することが提案されています: +これで、`updateColorMap` は古いオブジェクトを変更するのではなく新しいオブジェクトを返すようになります。`Object.assign` は ES6 からの機能であり、ポリフィルが必要です。 + +オブジェクトでも変更を伴わない更新を容易にする[オブジェクトのスプレッドプロパティ](https://github.com/sebmarkbage/ecmascript-rest-spread)を JavaScript に追加することが提案されています: ```js @@ -559,26 +584,25 @@ function updateColorMap(colormap) { If you're using Create React App, both `Object.assign` and the object spread syntax are available by default. -Create React App を使用しているなら、Object.assign とオブジェクトのスプレッド構文の両方がデフォルトで利用できます。 +Create React App を使用しているなら、`Object.assign` とオブジェクトのスプレッド構文の両方がデフォルトで利用できます。 ## Using Immutable Data Structures ## イミュータブルなデータ構造の使用 [Immutable.js](https://github.com/facebook/immutable-js) is another way to solve this problem. It provides immutable, persistent collections that work via structural sharing: -Immutable.js はこの問題を解決する別の方法です。Immutable.js は構造の共有により動作する不変で永続的なデータのコレクションを提供します: +[Immutable.js](https://github.com/facebook/immutable-js) はこの問題を解決する別の方法であり、構造の共有により動作する不変で永続的なデータのコレクションを提供します。 * *Immutable*: once created, a collection cannot be altered at another point in time. -* イミュータブル(不変性): 一度作成されたら、データのコレクションは他の時点で変更することはできない。 +* *不変(イミュータブル*: 一度作成されたら、データのコレクションはその後で変更することはできない。 * *Persistent*: new collections can be created from a previous collection and a mutation such as set. The original collection is still valid after the new collection is created. -* 永続性: 新しいデータのコレクションは以前のコレクションか setメソッドなどによる変更で作成できる。元のデータのコレクションは新しいデータのコレクションが作成された後も有効である。 +* *永続性*: 既存のコレクションに set などの変更操作を行うことで新しいデータのコレクションを作成できる。元のコレクションは新しいデータのコレクションが作成された後も有効である。 * *Structural Sharing*: new collections are created using as much of the same structure as the original collection as possible, reducing copying to a minimum to improve performance. -* 構造の共有: 新しいデータのコレクションを、可能な限り元のコレクションと同じ構造を利用して作ることで、データのコピー量を減らしてパフォーマンスを改善する。 +* *構造の共有*: 新しいデータのコレクションは、元のコレクションが含む同じ構造を可能な限り共有されて作られるので、データのコピー量が減りパフォーマンスが向上する。 Immutability makes tracking changes cheap. A change will always result in a new object so we only need to check if the reference to the object has changed. For example, in this regular JavaScript code: -不変性により変更を追跡することのコストが下がります。 -データの変更は常に新しいオブジェクトを作成することになるので、オブジェクトへの参照が変更されたかのみをチェックすればよくなるのです。 -例えば、以下の標準のJavaScriptコードで: + +不変性により変更を追跡することのコストが下がります。データを変更した結果は常に新しいオブジェクトになるので、オブジェクトの参照が変化したかどうかのみをチェックすればよくなるのです。例えば、以下の標準のJavaScriptコードで: ```javascript const x = { foo: 'bar' }; @@ -588,7 +612,8 @@ x === y; // true ``` Although `y` was edited, since it's a reference to the same object as `x`, this comparison returns `true`. You can write similar code with immutable.js: -y は編集されたにも関わらず、x と同じオブジェクトを参照しているため、上記の比較は true を返します。これと同様のコードは immutable.js でも書くことができますが: + +`y` は編集されたにも関わらず、`x` と同じオブジェクトを参照しているため、上記の比較は `true` を返します。これと同様のコードを immutable.js でも書くことができますが: ```javascript @@ -602,13 +627,12 @@ x === z; // true In this case, since a new reference is returned when mutating `x`, we can use a reference equality check `(x === y)` to verify that the new value stored in `y` is different than the original value stored in `x`. -このケースでは、x に変更を加える際に新しい参照が返されるので、参照が同じであるかを比較する (x === y) ことで、y に保存されている新しい値が x に保存されていた値とは違うものだ、と確かめられます。 +この場合、`x` に対する変更の結果、新しい参照が返されるので、参照の比較`(x === y)`だけで、`y` に保存されている新しい値が `x` に保存されていた値とは違うものだ、と確かめられます。 Two other libraries that can help use immutable data are [seamless-immutable](https://github.com/rtfeldman/seamless-immutable) and [immutability-helper](https://github.com/kolodny/immutability-helper). -その他には、seamless-immutable や immutability-helper の2つのライブラリがイミュータブルなデータの使用に役立ちます。 +その他には、[seamless-immutable](https://github.com/rtfeldman/seamless-immutable) や [immutability-helper](https://github.com/kolodny/immutability-helper) などのライブラリが不変データの使用に役立ちます。 Immutable data structures provide you with a cheap way to track changes on objects, which is all we need to implement `shouldComponentUpdate`. This can often provide you with a nice performance boost. -イミュータブルなデータ構造はオブジェクトにおける変更の追跡を容易にし、shouldComponentUpdate を実装する際にはこれを使うだけでよくなるのです。 -これによりパフォーマンスを大幅に向上できることがしばしばあります。 +イミュータブルなデータ構造はオブジェクトにおける変更の追跡を容易にし、`shouldComponentUpdate` を実装する際にはこれを使うだけでよくなるのです。これによりパフォーマンスを大幅に向上できることがしばしばあります。 From 14654259c4f4d421e04d0afdc7dea19b86af8ca3 Mon Sep 17 00:00:00 2001 From: "UEHARA, Junji" <59012+uehaj@users.noreply.github.com> Date: Sun, 10 Feb 2019 18:28:05 +0900 Subject: [PATCH 03/31] remove english part --- content/docs/optimizing-performance.md | 311 +++++-------------------- 1 file changed, 54 insertions(+), 257 deletions(-) diff --git a/content/docs/optimizing-performance.md b/content/docs/optimizing-performance.md index 7ce0f4b0e..43f7d1028 100644 --- a/content/docs/optimizing-performance.md +++ b/content/docs/optimizing-performance.md @@ -1,74 +1,46 @@ --- id: optimizing-performance -title: Optimizing Performance +title: パフォーマンス最適化 permalink: docs/optimizing-performance.html redirect_from: - "docs/advanced-performance.html" --- -Internally, React uses several clever techniques to minimize the number of costly DOM operations required to update the UI. For many applications, using React will lead to a fast user interface without doing much work to specifically optimize for performance. Nevertheless, there are several ways you can speed up your React application. - React は UI の更新時に必要となる高コストな DOM 操作の回数を最小化するために、内部的にいくつかの賢いテクニックを使用しています。多くのアプリケーションでは React を使用するだけで、パフォーマンス向上のための特別な最適化で苦労しなくても、反応速度の速いユーザーインターフェースを実現できます。それでもなお、React アプリケーションを高速化するための方法はいくつか存在します。 -## Use the Production Build ## 本番用ビルドを使用する -If you're benchmarking or experiencing performance problems in your React apps, make sure you're testing with the minified production build. - React アプリケーションでベンチマークを行う場合やパフォーマンスの問題が発生している場合には、ミニファイされた本番用ビルドでテストしていることを確認して下さい。 -By default, React includes many helpful warnings. These warnings are very useful in development. However, they make React larger and slower so you should make sure to use the production version when you deploy the app. - デフォルトで React は多くの有用な警告チェックを行いますが、これは開発時にはとても有用です。でもそもために React アプリケーションのサイズは肥大化し、速度が低下してしまうので、アプリケーションのデプロイ時には本番バージョンを使用していることを確認してください。 -If you aren't sure whether your build process is set up correctly, you can check it by installing [React Developer Tools for Chrome](https://chrome.google.com/webstore/detail/react-developer-tools/fmkadmapgofadopljbjfkapdkoienihi). If you visit a site with React in production mode, the icon will have a dark background: - - ビルドプロセスが正しく設定されているか分からない場合、[React Developer Tools for Chrome](https://chrome.google.com/webstore/detail/react-developer-tools/fmkadmapgofadopljbjfkapdkoienihi) をインストールして確認できます。 本番用モードの React のサイトを訪れた場合、アイコンは暗い背景となっています。 React DevTools on a website with production version of React -If you visit a site with React in development mode, the icon will have a red background: - 開発モードの React のサイトを訪れた場合、アイコンは赤い背景となっています。 React DevTools on a website with development version of React -It is expected that you use the development mode when working on your app, and the production mode when deploying your app to the users. - アプリケーションに対して作業をしているときは開発モードを使用し、利用者に配布する場合には本番用モードを使用することをお勧めします。 -You can find instructions for building your app for production below. - -本番用にアプリを構築するための手順は以下のとおりです。 +本番用にアプリを構築するためのそれぞれのツールにおける手順を以下に示します。 ### Create React App -### Reactアプリを作成する - -If your project is built with [Create React App](https://github.com/facebookincubator/create-react-app), run: - -プロジェクトが [Create React App](https://github.com/facebookincubator/create-react-app) で構築されているなら、以下のコードを実行して下さい: +プロジェクトが [Create React App](https://github.com/facebookincubator/create-react-app) で構築されているなら、以下のコードを実行して下さい。 ``` npm run build ``` -This will create a production build of your app in the `build/` folder of your project. - これによりアプリケーションの本番用ビルドがプロジェクト内の `build/` フォルダに作成されます。 +これが必要なのは本番用ビルドだけであることに留意してください。通常の開発作業では、`npm start` を使用してください。 -Remember that this is only necessary before deploying to production. For normal development, use `npm start`. - -これは本番バージョンをデプロイする前のみ必要な作業であることに留意してください。通常の開発作業では、`npm start` を使用してください。 - -### Single-File Builds ### 単一ファイル版ビルド -We offer production-ready versions of React and React DOM as single files: - React と ReactDOM をそれぞれ単一ファイル化した本番環境用のバージョンを提供しています。 ```html @@ -76,14 +48,10 @@ React と ReactDOM をそれぞれ単一ファイル化した本番環境用の ``` -Remember that only React files ending with `.production.min.js` are suitable for production. - 本番用に適しているのは、React ファイル名の末尾が `.production.min.js` であるもののみであることに留意ください。 ### Brunch -For the most efficient Brunch production build, install the [`uglify-js-brunch`](https://github.com/brunch/uglify-js-brunch) plugin: - Brunch で最も効率のよい本番用ビルドを行うためには、[`uglify-js-brunch`](https://github.com/brunch/uglify-js-brunch) をインストールしてください: ``` @@ -94,23 +62,16 @@ npm install --save-dev uglify-js-brunch yarn add --dev uglify-js-brunch ``` -Then, to create a production build, add the `-p` flag to the `build` command: - そして、本番用ビルドを作成するために、`build` コマンドに`-p` オプションを指定して実行します。 ``` brunch build -p ``` -Remember that you only need to do this for production builds. You shouldn't pass the `-p` flag or apply this plugin in development, because it will hide useful React warnings and make the builds much slower. - - これが必要なのは本番用ビルドだけであることに留意してください。React の有用な警告表示が隠されたり、ビルド速度が大幅に遅くなったりしますので、開発用では `-p` フラグを指定したり、`uglify-js-brunch` プラグインを適用したりしないでください。 ### Browserify -For the most efficient Browserify production build, install a few plugins: - Browserify で最も効率の良い本番用ビルドを行うため、いくつかのプラグインをインストールしてください。 ``` @@ -121,22 +82,12 @@ npm install --save-dev envify uglify-js uglifyify yarn add --dev envify uglify-js uglifyify ``` -To create a production build, make sure that you add these transforms **(the order matters)**: - 本番用ビルドを作成するには、以下の変換(transform)を追加してください(**順番は重要です**)。 -* The [`envify`](https://github.com/hughsk/envify) transform ensures the right build environment is set. Make it global (`-g`). - * [`envify`](https://github.com/hughsk/envify) 変換は正しいビルド環境が確実に設定されるようにします。グローバルに設定してください (`-g`)。 - -* The [`uglifyify`](https://github.com/hughsk/uglifyify) transform removes development imports. Make it global too (`-g`). * [`uglifyify`](https://github.com/hughsk/uglifyify) 変換は開発用にインポートしたライブラリを削除します。これもグローバルに設定してください (`-g`)。 - -* Finally, the resulting bundle is piped to [`uglify-js`](https://github.com/mishoo/UglifyJS2) for mangling ([read why](https://github.com/hughsk/uglifyify#motivationusage)). * 最後に結果として出力されたものを、名前の圧縮のために [`uglify-js`](https://github.com/mishoo/UglifyJS2) にパイプします([理由を読む](https://github.com/hughsk/uglifyify#motivationusage))。 -For example: - 以下に例を示します。 ``` @@ -148,20 +99,13 @@ browserify ./index.js \ >**Note:** > ->The package name is `uglify-js`, but the binary it provides is called `uglifyjs`.
->This is not a typo. -> ->パッケージ名は `uglify-js` ですが、パッケージが提供するバイナリ名は `uglifyjs` です。タイプミスではありません。 - -Remember that you only need to do this for production builds. You shouldn't apply these plugins in development because they will hide useful React warnings, and make the builds much slower. +>パッケージ名は `uglify-js` ですが、パッケージが提供するバイナリ名は `uglifyjs` です。
+>タイプミスではありません。 これが必要なのは本番用ビルドだけであることに留意してください。React の有用な警告文が隠されたり、ビルド速度が大幅に遅くなったりしますので、開発用ではこれらのプラグインを適用しないで下さい。 - ### Rollup -For the most efficient Rollup production build, install a few plugins: - Rollup で最も効率のよい本番用ビルドを行うためには、いくつかのプラグインを以下のようにインストールします。 ``` @@ -172,17 +116,10 @@ npm install --save-dev rollup-plugin-commonjs rollup-plugin-replace rollup-plugi yarn add --dev rollup-plugin-commonjs rollup-plugin-replace rollup-plugin-uglify ``` -To create a production build, make sure that you add these plugins **(the order matters)**: +本番用ビルドを作成するには、以下のプラグインを追加してください(**順番は重要**です)。 -本番用ビルドを作成するには、以下のプラグインを追加してください(**順番は重要です**)。 - -* The [`replace`](https://github.com/rollup/rollup-plugin-replace) plugin ensures the right build environment is set. * [`replace`](https://github.com/rollup/rollup-plugin-replace) プラグインは正しいビルド環境が確実に設定されるようにします。 - -* The [`commonjs`](https://github.com/rollup/rollup-plugin-commonjs) plugin provides support for CommonJS in Rollup. * [`commonjs`](https://github.com/rollup/rollup-plugin-commonjs) プラグインは Rollup で CommonJS をサポートできるようにします。 - -* The [`uglify`](https://github.com/TrySound/rollup-plugin-uglify) plugin compresses and mangles the final bundle. * [`uglify`](https://github.com/TrySound/rollup-plugin-uglify) プラグインは出力された最終的なバンドルを圧縮し、mangle(訳注: 変数名や識別子を短縮)します。 ```js @@ -197,26 +134,15 @@ plugins: [ ] ``` -For a complete setup example [see this gist](https://gist.github.com/Rich-Harris/cb14f4bc0670c47d00d191565be36bf0). - 設定例の全体はこの [gist を参照](https://gist.github.com/Rich-Harris/cb14f4bc0670c47d00d191565be36bf0)してください。 - -Remember that you only need to do this for production builds. You shouldn't apply the `uglify` plugin or the `replace` plugin with `'production'` value in development because they will hide useful React warnings, and make the builds much slower. - -これが必要なのは本番用ビルドだけであることに留意してください。React の有用な警告表示が隠されたり、ビルド速度が大幅に遅くなったりしますので、開発用では `uglify` プラグインもしくは `replace` プラグインを`'production'` という値で適用しないでください。 +これらが必要なのは本番用ビルドだけであることに留意してください。React の有用な警告表示が隠されたり、ビルド速度が大幅に遅くなったりしますので、開発用では `uglify` プラグインもしくは `replace` プラグインを`'production'` という値で適用しないでください。 ### webpack >**Note:** > ->If you're using Create React App, please follow [the instructions above](#create-react-app).
->This section is only relevant if you configure webpack directly. -> -> Create React App を利用している場合は、[上記のガイド](#create-react-app)に従ってください。 ->このセクションは直接 webpack の設定を行いたい人向けです。 - -For the most efficient webpack production build, make sure to include these plugins in your production configuration: +> Create React App を利用している場合は、[Create React Appについての前述の説明](#create-react-app)に従ってください。
このセクションは直接 webpack の設定を行いたい人向けです。 webpack で最も効率のよい本番用ビルドを行うためには、本番ビルドの設定中に必ず以下のプラグインを含めるようにしてください。 @@ -227,69 +153,35 @@ new webpack.DefinePlugin({ new webpack.optimize.UglifyJsPlugin() ``` -You can learn more about this in [webpack documentation](https://webpack.js.org/guides/production-build/). - より詳細な説明については [webpack のドキュメント](https://webpack.js.org/guides/production-build/)を参照ください。 -Remember that you only need to do this for production builds. You shouldn't apply `UglifyJsPlugin` or `DefinePlugin` with `'production'` value in development because they will hide useful React warnings, and make the builds much slower. +これらが必要なのは本番用ビルドだけであることに留意してください。React の有用な警告文が隠されたり、ビルド速度が大幅に遅くなったりしますので、開発用では `UglifyJsPlugin` もしくは `DefinePlugin` を`'production'` という値で適用しないでください。 -これが必要なのは本番用ビルドだけであることに留意してください。React の有用な警告文が隠されたり、ビルド速度が大幅に遅くなったりしますので、開発用では `UglifyJsPlugin` もしくは `DefinePlugin` を`'production'` という値で適用しないでください。 - -## Profiling Components with the Chrome Performance Tab ## Chrome のパフォーマンスタブでコンポーネントをプロファイルする -In the **development** mode, you can visualize how components mount, update, and unmount, using the performance tools in supported browsers. For example: - -**開発** モードでは、対応ブラウザのパフォーマンス分析ツールでコンポーネントのマウント・更新・アンマウントの様子を視覚化することができます。例えば以下のとおり。 +**開発**モードでは、対応するブラウザのパフォーマンス分析ツールで、コンポーネントのマウント・更新・アンマウントの様子を以下のように視覚化することができます。 +

React components in Chrome timeline
-To do this in Chrome: - -Chrome でこれを行うには以下を行います。 +Chrome での操作は以下の通り。 -1. Temporarily **disable all Chrome extensions, especially React DevTools**. They can significantly skew the results! 1. 一時的に **React DevTools を含むすべての Chrome 拡張機能を無効にする**。無効にしないと、結果が正確でなくなる可能性があります。 - -2. Make sure you're running the application in the development mode. 2. アプリケーションが開発モードで動作していることを確認する。 - -3. Open the Chrome DevTools **[Performance](https://developers.google.com/web/tools/chrome-devtools/evaluate-performance/timeline-tool)** tab and press **Record**. 3. Chrome DevTools の**[パフォーマンス](https://developers.google.com/web/tools/chrome-devtools/evaluate-performance/timeline-tool)タブ**を開いて **Record(記録)** ボタンを押す。 - -4. Perform the actions you want to profile. Don't record more than 20 seconds or Chrome might hang. 4. プロファイル対象のアクションを実行する。なお、20秒以上は記録しないでください。さもないと Chrome がハングアップすることがあります。 +5. 記録を停止する。 +6. React イベントが **User Timing** ラベルの下にグループ化される。 -5. Stop recording. -5. 記録を停止する。 - -6. React events will be grouped under the **User Timing** label. -6. React イベントが **User Timing** ラベルの下にグループ化される。 - -For a more detailed walkthrough, check out [this article by Ben Schwarz](https://calibreapp.com/blog/2017-11-28-debugging-react/). -Reactイベントが User Timing ラベルの下にグループ化される。 +さらなる詳細については、[Ben Schwarz によるこの記事](https://calibreapp.com/blog/2017-11-28-debugging-react/)を参照ください。 -Note that **the numbers are relative so components will render faster in production**. Still, this should help you realize when unrelated UI gets updated by mistake, and how deep and how often your UI updates occur. - -**プロファイル結果の数値は相対的なものであり、コンポーネントは本番環境ではより速くレンダリングされる**ことに注意してください。 -それでも、関係のない UI が誤って更新されているのを見つけたり、どの程度の頻度と深さで UI の更新が発生するのかを知る手助けになるはずです。 - -Currently Chrome, Edge, and IE are the only browsers supporting this feature, but we use the standard [User Timing API](https://developer.mozilla.org/en-US/docs/Web/API/User_Timing_API) so we expect more browsers to add support for it. +**プロファイル結果の数値は相対的なものであり、コンポーネントは本番環境ではより速くレンダリングされる**ことに注意してください。それでも、関係のない UI が誤って更新されているのを見つけたり、どの程度の頻度と深さで UI の更新が発生するのかを知る手助けになるはずです。 現時点では、Chrome、Edge、そして IE のみがこの機能をサポートするブラウザですが、私達は標準の [User Timing API](https://developer.mozilla.org/en-US/docs/Web/API/User_Timing_API) を採用しているので、より多くのブラウザがサポートしてくれることを期待しています。 -## Profiling Components with the DevTools Profiler ## DevToolsプロファイラを使用したコンポーネントのプロファイリング -`react-dom` 16.5+ and `react-native` 0.57+ provide enhanced profiling capabilities in DEV mode with the React DevTools Profiler. -An overview of the Profiler can be found in the blog post ["Introducing the React Profiler"](/blog/2018/09/10/introducing-the-react-profiler.html). -A video walkthrough of the profiler is also [available on YouTube](https://www.youtube.com/watch?v=nySib7ipZdk). - - -`react-dom` 16.5 以降と`react-native` 0.57 以降では、DEV モードにおける強化されたプロファイリング機能を React DevTools プロファイラにて提供しています。このプロファイラの概要がブログ記事「[Introduction the React Profiler](/blog/2018/09/10/introducing-the-react-profiler.html)」で説明されています。チュートリアル動画も[YouTubeで入手できます](https://www.youtube.com/watch?v=nySib7ipZdk)。 - - -If you haven't yet installed the React DevTools, you can find them here: +`react-dom` 16.5 以降と`react-native` 0.57 以降では、開発モードにおける強化されたプロファイリング機能を React DevTools プロファイラにて提供しています。このプロファイラの概要がブログ記事「[React プロファイラの紹介(Introduction the React Profiler)](/blog/2018/09/10/introducing-the-react-profiler.html)」で説明されています。チュートリアル動画も [YouTube で入手できます](https://www.youtube.com/watch?v=nySib7ipZdk)。 React DevToolsをまだインストールしていない場合は、以下で見つけることができます。 @@ -297,75 +189,43 @@ React DevToolsをまだインストールしていない場合は、以下で見 - [Firefoxブラウザ拡張](https://addons.mozilla.org/en-GB/firefox/addon/react-devtools/) - [スタンドアロンのNodeパッケージ](https://www.npmjs.com/package/react-devtools) -> Note +> Note: > -> A production profiling bundle of `react-dom` is also available as `react-dom/profiling`. -> Read more about how to use this bundle at [fb.me/react-profiling](https://fb.me/react-profiling) -> -> 注意 -> -> 本番ビルド版 `react-dom` のプロファイリング可能なバンドルは `react-dom/profiling` として利用可能です。このバンドルの使い方の詳細については、[fb.me/react-profiling](https://fb.me/react-profiling) を参照してください。 +> 本番ビルド版 `react-dom` のプロファイリング可能なバンドルとして `react-dom/profiling` が利用可能です。このバンドルの使い方の詳細については、[fb.me/react-profiling](https://fb.me/react-profiling) を参照してください。 -## Virtualize Long Lists ## 長いリストの仮想化 -If your application renders long lists of data (hundreds or thousands of rows), we recommended using a technique known as "windowing". This technique only renders a small subset of your rows at any given time, and can dramatically reduce the time it takes to re-render the components as well as the number of DOM nodes created. - -アプリケーションがデータの長いリスト(数百〜数千行)を描画する場合は、「ウィンドウイング」として知られるテクニックを使うことをおすすめします。このテクニックでは、ある瞬間においてリストの小さな部分集合のみを描画することで、作成する DOM ノードの数およびコンポーネントの再描画にかかる時間を大幅に削減することができます。 +アプリケーションが長いデータのリスト(数百〜数千行)をレンダリングする場合は、「ウィンドウイング」として知られるテクニックを使うことをおすすめします。このテクニックでは、ある瞬間ごとにはリストの小さな部分集合のみを描画することで、作成する DOM ノードの数およびコンポーネントの再描画にかかる時間を大幅に削減することができます。 -[react-window](https://react-window.now.sh/) and [react-virtualized](https://bvaughn.github.io/react-virtualized/) are popular windowing libraries. They provide several reusable components for displaying lists, grids, and tabular data. You can also create your own windowing component, like [Twitter did](https://medium.com/@paularmstrong/twitter-lite-and-high-performance-react-progressive-web-apps-at-scale-d28a00e780a3), if you want something more tailored to your application's specific use case. +[react-window](https://react-window.now.sh/)と[react-virtualized](https://bvaughn.github.io/react-virtualized/)は人気があるウィンドウイング処理のライブラリです。これらはリスト、グリッド、および表形式のデータを表示するための、いくつかの再利用可能コンポーネントを提供しています。[Twitter](https://medium.com/@paularmstrong/twitter-lite-and-high-performance-react-progressive-web-apps-at-scale-d28a00e780a3) が行なっているように、アプリケーションの特定のユースケースに合わせた追加的な処理をする場合は、独自のウィンドウイング処理のコンポーネントを作成することもできます。 -[react-window](https://react-window.now.sh/)と[react-virtualized](https://bvaughn.github.io/react-virtualized/)はウィンドウイング処理のための人気があるライブラリです。これらはリスト、グリッド、および表形式のデータを表示するための、いくつかの再利用可能コンポーネントを提供しています。[Twitter did](https://medium.com/@paularmstrong/twitter-lite-and-high-performance-react-progressive-web-apps-at-scale-d28a00e780a3)が行なっているように、アプリケーションの特定のユースケースに合わせてより多くの何かをしたい場合は、独自のウィンドウイング処理のコンポーネントを作成することもできます。 - - -## Avoid Reconciliation ## リコンシリエーション(差分検出、突き合せ処理)を避ける -React builds and maintains an internal representation of the rendered UI. It includes the React elements you return from your components. This representation lets React avoid creating DOM nodes and accessing existing ones beyond necessity, as that can be slower than operations on JavaScript objects. Sometimes it is referred to as a "virtual DOM", but it works the same way on React Native. - React はレンダリングされた UI の内部表現を構築し、維持します。それにはコンポーネントが返した React 要素も含まれています。 -この内部表現を使うことで React は、JavaScript オブジェクトの操作よりも遅くなりうる DOM ノードの作成やアクセスを必要以上に行うことを回避します。しばしばこの内部表現は "仮想DOM (virtual DOM)" と呼ばれますが、React Native でも同様に動作します。 +React は、この内部表現を使うことによってJavaScript オブジェクトの操作より遅くなりうる不要な DOM ノードの作成やアクセスを回避します。この内部表現はしばしば「仮想DOM 」と呼ばれますが、React Native 上でも同様に動くものです。 -When a component's props or state change, React decides whether an actual DOM update is necessary by comparing the newly returned element with the previously rendered one. When they are not equal, React will update the DOM. - -コンポーネントの props か state が変更された場合、React は新しく返された要素を以前にレンダリングされたものと比較することで、本物の DOM の更新が必要かを判断します。それらが等しくない場合、React は DOM を更新します。 - -You can now visualize these re-renders of the virtual DOM with React DevTools: -React DevToolsを使用して仮想DOMのこれらの再レンダリングを視覚化できるようになりました。 - -- [Chrome Browser Extension](https://chrome.google.com/webstore/detail/react-developer-tools/fmkadmapgofadopljbjfkapdkoienihi?hl=en) -- [Firefox Browser Extension](https://addons.mozilla.org/en-GB/firefox/addon/react-devtools/) -- [Standalone Node Package](https://www.npmjs.com/package/react-devtools) +コンポーネントの props や state が変更された場合、React は新しく返された要素と以前にレンダリングされたものとを比較することで、実 DOM の更新が必要かを判断します。それらが等しくない場合、React は DOM を更新します。 +以下のReact DevToolsを使用することで、仮想DOMのこれらの再レンダリングを視覚化できるようになりました。 - [Chromeブラウザ拡張](https://chrome.google.com/webstore/detail/react-developer-tools/fmkadmapgofadopljbjfkapdkoienihi?hl=en) - [Firefoxブラウザ拡張](https://addons.mozilla.org/en-GB/firefox/addon/react-devtools/) - [スタンドアロンNodeパッケージ](https://www.npmjs.com/package/react-devtools) -In the developer console select the **Highlight Updates** option in the **React** tab: 開発者コンソールの **React** タブで **Highlight Updates** オプションを選択します:
How to enable highlight updates
-Interact with your page and you should see colored borders momentarily appear around any components that have re-rendered. This lets you spot re-renders that were not necessary. You can learn more about this React DevTools feature from this [blog post](https://blog.logrocket.com/make-react-fast-again-part-3-highlighting-component-updates-6119e45e6833) from [Ben Edelstein](https://blog.logrocket.com/@edelstein). - ページを操作すると、再レンダリングされたコンポーネントの周囲に色付きの枠線が一定時間表示されます。これにより、不要な再レンダリングを見つけることができます。この React DevTools 機能の詳細については、[Ben Edelstein](https://blog.logrocket.com/@edelstein)による[このブログ投稿](https://blog.logrocket.com/make-react-fast-again-part-3-highlighting-component-updates-6119e45e6833)から学ぶことができます。 -Consider this example: - -以下の例を考えてください。 +以下の例を考えて見ましょう。
React DevTools Highlight Updates example
-Note that when we're entering a second todo, the first todo also flashes on the screen on every keystroke. This means it is being re-rendered by React together with the input. This is sometimes called a "wasted" render. We know it is unnecessary because the first todo content has not changed, but React doesn't know this. - -2つ目の TODO を入力しているとき、1つ目の TODO もキーストロークの度に画面上で点滅することに注意してください。これは、React が入力によって一緒に再レンダリングしていることを意味します。 これは「無駄な」レンダリングと呼ばれることがあります。最初の TODO の内 -容は変更されておらず、再レンダリングの必要がないことを我々は知っていますが、React はそれを知りません。 +2つ目の TODO 項目を入力しているとき、1つ目の TODO 項目もキーストロークの度に画面上で点滅することに注意してください。これは、React が入力によって一緒に再レンダリングしていることを意味します。 これは「無駄な」レンダリングと呼ばれることがあります。最初の TODO 項目の内容は変更されておらず、再レンダリングの必要がないことを我々は知っていますが、React はそれを知りません。 -Even though React only updates the changed DOM nodes, re-rendering still takes some time. In many cases it's not a problem, but if the slowdown is noticeable, you can speed all of this up by overriding the lifecycle function `shouldComponentUpdate`, which is triggered before the re-rendering process starts. The default implementation of this function returns `true`, leaving React to perform the update: - -React は変更された DOM ノードしか更新しないとはいえ、再レンダリングには時間がかかります。多少の時間がかかっても多くの場合は問題にはなりませんが、遅延が目立つ場合、再レンダリングプロセスが開始される前にトリガーされるライフサイクル関数 `shouldComponentUpdate` をオーバーライドすることで、スピードを全面的に向上できます。この関数のデフォルトの実装は `true`を返し、React にそのまま更新処理を実行させます。 +React は変更された DOM ノードだけを更新するとはいえ、再レンダリングには時間がかかります。多少の時間がかかっても多くの場合は問題にはなりませんが、遅延が目立つ場合、再レンダリングプロセスが開始される前にトリガーされるライフサイクル関数 `shouldComponentUpdate` をオーバーライドすることで、スピードを抜本的に向上できます。この関数のデフォルトの実装は `true`を返し、React にそのまま更新処理を実行させます: ```javascript shouldComponentUpdate(nextProps, nextState) { @@ -373,46 +233,29 @@ shouldComponentUpdate(nextProps, nextState) { } ``` -If you know that in some situations your component doesn't need to update, you can return `false` from `shouldComponentUpdate` instead, to skip the whole rendering process, including calling `render()` on this component and below. - -ある状況においてコンポーネントが更新される必要がないと分かっているなら、`shouldComponentUpdate` から代わりに `false` を返すことにより、該当コンポーネントおよび配下への `render()` 呼び出しを含む、レンダリング処理の全体をスキップすることができます。 - -In most cases, instead of writing `shouldComponentUpdate()` by hand, you can inherit from [`React.PureComponent`](/docs/react-api.html#reactpurecomponent). It is equivalent to implementing `shouldComponentUpdate()` with a shallow comparison of current and previous props and state. +ある状況においてコンポーネントを更新する必要がないと分かっているなら、`shouldComponentUpdate` から `false` を返すことにより、該当コンポーネントおよび配下への `render()` 呼び出しを含む、レンダリング処理の全体をスキップすることができます。 -ほとんどの場合、手で `shouldComponentUpdate()` を書く代わりに、[`React.PureComponent`](/docs/react-api.html#reactpurecomponent)から継承できます。 これは現在と直前の props と state に対する浅い比較(Shallow Comparison)を行うような `shouldComponentUpdate()` を実装することと同じです。 +ほとんどの場合には、手書きの `shouldComponentUpdate()` を定義する代わりに[`React.PureComponent`](/docs/react-api.html#reactpurecomponent)を継承できます。 これは現在と直前の props と state に対する浅い比較(Shallow Comparison)を行う `shouldComponentUpdate()` を実装することと同じです。 -## shouldComponentUpdate In Action ## shouldComponentUpdate の実際の動作 -Here's a subtree of components. For each one, `SCU` indicates what `shouldComponentUpdate` returned, and `vDOMEq` indicates whether the rendered React elements were equivalent. Finally, the circle's color indicates whether the component had to be reconciled or not. - -以下のようなコンポーネントのサブツリーがあるとします。それぞれ、`SCU` は `shouldComponentUpdate` が返したもの(訳注: 緑はtrue、赤は false)を示し、`vDOMEq` はレンダリングされた React 要素が等しかったかどうか(訳注: 緑は等しい、赤は等しくない)を示します。 -最後に、円の色はコンポーネントに対してツリーを比較して合わせ込むためのリコンシリエーション処理が(本来)必要だったのかどうか(訳注: 緑は不要、赤は必要)を示します。 +以下のようなコンポーネントのサブツリーがあるとします。それぞれ、`SCU` は `shouldComponentUpdate` が返した値(訳注:緑はtrue、赤は false)を示し、`vDOMEq` はレンダリングされた React 要素が等しかったかどうか(訳注:緑は等しい、赤は等しくない)を示します。 +最後に、円の色はコンポーネントに対してツリーを比較して合わせ込むためのリコンシリエーション処理が本来は必要だったのかどうか(訳注:緑は不要、赤は必要)を示します。 +

-Since `shouldComponentUpdate` returned `false` for the subtree rooted at C2, React did not attempt to render C2, and thus didn't even have to invoke `shouldComponentUpdate` on C4 and C5. - C2 をルートとするサブツリーでは `shouldComponentUpdate` が `false` を返したので、React は C2 をレンダリングしようとしませんでした。したがって C4 と C5 については `shouldComponentUpdate` を実行する必要すらなかったわけです。 -For C1 and C3, `shouldComponentUpdate` returned `true`, so React had to go down to the leaves and check them. For C6 `shouldComponentUpdate` returned `true`, and since the rendered elements weren't equivalent React had to update the DOM. - -C1 と C3 では、`shouldComponentUpdate` が `true` を返したので、React は葉ノードにも移動してチェックする必要がありました。C6 では `shouldComponentUpdate` が `true` を返し、レンダリングされた要素は等しくなかったので、React は DOM を更新する必要がありました。 - -The last interesting case is C8. React had to render this component, but since the React elements it returned were equal to the previously rendered ones, it didn't have to update the DOM. +C1 と C3 では、`shouldComponentUpdate` が `true` を返したので、React は葉ノードにも移動してチェックする必要がありました。C6 では `shouldComponentUpdate` が `true` を返し、そしてレンダリングされた React 要素も等しくなかったので、React は DOM を更新する必要がありました。 最後の興味深いケースが C8 です。React はこのコンポーネントをレンダリングする必要がありましたが、返された React 要素は前回レンダリングされたときものと同じだったので、DOM の更新は必要ありませんでした。 -Note that React only had to do DOM mutations for C6, which was inevitable. For C8, it bailed out by comparing the rendered React elements, and for C2's subtree and C7, it didn't even have to compare the elements as we bailed out on `shouldComponentUpdate`, and `render` was not called. - -React が DOM を更新しなければならなかったのは、C6 だけだったことに注目してください。C6 の更新は避けられないものでした。C8 では、レンダリングされた React 要素の比較を実行してから処理が終わったのですが、C2 のサブツリーと C7 では `shouldComponentUpdate` のところで処理が終わって render メソッドが呼ばれなかったため、要素の比較は実行する必要すらありませんでした。 +React が実 DOM を更新しなければならなかったのは、C6 だけだったことに注目してください。C6 の更新は避けられないものでした。C8 では、レンダリングされた React 要素の比較のおかげで実 DOM を修正せずに済みました。C2 のサブツリーと C7 のケースでは `shouldComponentUpdate` のおかげで、render メソッドの呼び出しや React 要素の比較処理すらスキップすることができました。 -## Examples ## 例 -If the only way your component ever changes is when the `props.color` or the `state.count` variable changes, you could have `shouldComponentUpdate` check that: - -コンポーネントが変更される唯一の方法が `props.color` または `state.count` 変数が変化した時のみだとしたら、`shouldComponentUpdate` では以下のようなチェックを行えます。 +コンポーネントが変化するのが `props.color` または `state.count` 変数が変化した時だけだとしたら、`shouldComponentUpdate` では以下のようなチェックを行えます。 ```javascript class CounterButton extends React.Component { @@ -443,9 +286,7 @@ class CounterButton extends React.Component { } ``` -In this code, `shouldComponentUpdate` is just checking if there is any change in `props.color` or `state.count`. If those values don't change, the component doesn't update. If your component got more complex, you could use a similar pattern of doing a "shallow comparison" between all the fields of `props` and `state` to determine if the component should update. This pattern is common enough that React provides a helper to use this logic - just inherit from `React.PureComponent`. So this code is a simpler way to achieve the same thing: - -このコードは、`shouldComponentUpdate` は単に `props.color` もしくは `state.count` が変化しているかをチェックしているだけです。これらの値に変化がなければ、コンポーネントは更新されません。コンポーネントがもっと複雑な場合は、`props` と `state` のすべてのフィールドに対して "浅い比較(Shallow Comparison)" をするという同種のパターンでコンポーネントを更新するべきかを決定できます。このパターンはあまりに一般的なので、React はこのロジックのためのヘルパーを用意しており、`React.PureComponent` から継承するだけで使用できます。だから以下のコードで前述のコードと同じことをよりシンプルに実装できます。 +このコードは、`shouldComponentUpdate` は `props.color` と `state.count` のいずれかの変化を単にチェックしているだけです。これらの値が変化していなければコンポーネントは更新されません。コンポーネントがもっと複雑な場合は、`props` と `state` のすべてのフィールドに対して「浅い(Shallow)比較」をするという同種のパターンでコンポーネント更新の必要性を決定できます。このパターンはあまりに一般的なので、React はこのロジックのためのヘルパーを用意しており、`React.PureComponent` から継承するだけで使用できます。なので以下のコードで前述のコードと同じことをよりシンプルに実装できます。 ```js class CounterButton extends React.PureComponent { @@ -466,14 +307,9 @@ class CounterButton extends React.PureComponent { } ``` -Most of the time, you can use `React.PureComponent` instead of writing your own `shouldComponentUpdate`. It only does a shallow comparison, so you can't use it if the props or state may have been mutated in a way that a shallow comparison would miss. - -ほとんどの場合、自分で `shouldComponentUpdate` を記述する代わりに `React.PureComponent` を使うことができます。浅い(shallow)比較を行うだけですので、浅い比較では検出できない形で props や state が変更されている可能性がある場合には使えません。 +ほとんどの場合、自分で `shouldComponentUpdate` を記述する代わりに `React.PureComponent` を使うことができます。もっとも、浅い(shallow)比較を行うだけですので、浅い比較では検出できない形で props や state が変更されている可能性がある場合には使えません。 -This can be a problem with more complex data structures. For example, let's say you want a `ListOfWords` component to render a comma-separated list of words, with a parent `WordAdder` component that lets you click a button to add a word to the list. This code does *not* work correctly: - - -この事はもっと複雑なデータ構造を持つ場合には問題となります。例えば、 カンマ区切りで単語をレンダリングする `ListOfWords` コンポーネントと、ボタンをクリックしてリストに単語を追加できる親コンポーネント `WordAdder` が必要だとしましょう。以下のコードは正しく動作しません。 +この事はより複雑なデータ構造の場合には問題となります。例えば、カンマ区切りで単語をレンダリングする `ListOfWords` コンポーネントと、ボタンをクリックしてリストに単語を追加できる親コンポーネント `WordAdder` が必要だとしましょう。以下のコードは正しく動作しません。 ```javascript class ListOfWords extends React.PureComponent { @@ -509,19 +345,11 @@ class WordAdder extends React.Component { } ``` -The problem is that `PureComponent` will do a simple comparison between the old and new values of `this.props.words`. Since this code mutates the `words` array in the `handleClick` method of `WordAdder`, the old and new values of `this.props.words` will compare as equal, even though the actual words in the array have changed. The `ListOfWords` will thus not update even though it has new words that should be rendered. - -問題は `PureComponent` が `this.props.words` の古い値と新しい値を単純に比較することにあります。 -上記のコードでは `WordAdder` の handleClick メソッド内で `words` 配列の内容を変更するので、`this.props.words` の新旧の値は、たとえ配列内の実際の単語が変更されていたとしても、比較の結果同じだとみなしてしまうのです。 -そのため `ListOfWords` はレンダリングすべき新しい単語が追加されているにも関わらず、更新されません。 +問題は `PureComponent` が `this.props.words` の古い値と新しい値を単純に比較していることにあります。上記のコードでは `WordAdder` の handleClick メソッド内で `words` 配列の内容を直接変更してしまうので、`this.props.words` の新旧の値は、たとえ配列内の実際の単語が変更されていたとしても、比較の結果同じだとみなしてしまうのです。そのため `ListOfWords` はレンダリングすべき新しい単語が追加されているにも関わらず、更新されません。 -## The Power Of Not Mutating Data ## データを変更しないことの効果 -The simplest way to avoid this problem is to avoid mutating values that you are using as props or state. For example, the `handleClick` method above could be rewritten using `concat` as: - -この問題を避ける最も単純な方法は、props や state として使用している値の変更を避けることです。 -例えば、上記の `handleClick` メソッドは `concat` を使って以下のように書き換えることができます: +この問題を避ける最も単純な方法は、props や state として使用する値の(破壊的)変更を避けることです。例えば、上記の `handleClick` メソッドは `concat` を使って以下のように書き換えることができます: ```javascript handleClick() { @@ -531,9 +359,7 @@ handleClick() { } ``` -ES6 supports a [spread syntax](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Spread_operator) for arrays which can make this easier. If you're using Create React App, this syntax is available by default. - -ES6 はこれをより簡単に実装できる配列用の[スプレッド構文](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Spread_operator)をサポートしています。 +ES6 はこれをより簡潔に実装できる配列の[スプレッド構文](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Spread_operator)をサポートしています。 Create React App を使用していれば、この構文はデフォルトで利用できます。 ```js @@ -544,11 +370,7 @@ handleClick() { }; ``` -You can also rewrite code that mutates objects to avoid mutation, in a similar way. For example, let's say we have an object named `colormap` and we want to write a function that changes `colormap.right` to be `'blue'`. We could write: - -同様に、オブジェクトを変更するコードを変更が起きないものに書き換えることができます。 -例えば、`colormap` というオブジェクトがあり、`colormap.right` を `'blue'` に変更する関数が必要だとしましょう。 -以下のように書くことも可能ですが… +同様に、オブジェクトについても破壊的変更をするコードを破壊的変更をしないように書き換えることができます。例えば、`colormap` というオブジェクトがあり、`colormap.right` を `'blue'` に変更する関数が必要だとしましょう。以下のように書くことも可能ですが、 ```js function updateColorMap(colormap) { @@ -556,9 +378,7 @@ function updateColorMap(colormap) { } ``` -To write this without mutating the original object, we can use [Object.assign](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/assign) method: - -元のオブジェクトを変更することなく実装するのには、Object.assign が使用できます: +この処理を、元オブジェクトを破壊的変更をせずに実装するために、[Object.assign](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/assign) を使用できます。 ```js function updateColorMap(colormap) { @@ -566,15 +386,9 @@ function updateColorMap(colormap) { } ``` -`updateColorMap` now returns a new object, rather than mutating the old one. `Object.assign` is in ES6 and requires a polyfill. - -There is a JavaScript proposal to add [object spread properties](https://github.com/sebmarkbage/ecmascript-rest-spread) to make it easier to update objects without mutation as well: - - -これで、`updateColorMap` は古いオブジェクトを変更するのではなく新しいオブジェクトを返すようになります。`Object.assign` は ES6 からの機能であり、ポリフィルが必要です。 - -オブジェクトでも変更を伴わない更新を容易にする[オブジェクトのスプレッドプロパティ](https://github.com/sebmarkbage/ecmascript-rest-spread)を JavaScript に追加することが提案されています: +これで、`updateColorMap` は古いオブジェクトを破壊的に変更するのではなく新しいオブジェクトを返すようになります。`Object.assign` は ES6 からの機能であり、ポリフィルが必要です(訳注:ブラウザや処理系がES6に未対応の場合)。 +オブジェクトに対して同様に破壊的変更を伴わない更新を容易にする[オブジェクトのスプレッドプロパティ構文](https://github.com/sebmarkbage/ecmascript-rest-spread)を JavaScript に追加することが提案されています: ```js function updateColorMap(colormap) { @@ -582,27 +396,17 @@ function updateColorMap(colormap) { } ``` -If you're using Create React App, both `Object.assign` and the object spread syntax are available by default. - -Create React App を使用しているなら、`Object.assign` とオブジェクトのスプレッド構文の両方がデフォルトで利用できます。 +Create React App を使用しているなら、`Object.assign` およびオブジェクトのスプレッド構文の両方がデフォルトで利用できます。 -## Using Immutable Data Structures ## イミュータブルなデータ構造の使用 -[Immutable.js](https://github.com/facebook/immutable-js) is another way to solve this problem. It provides immutable, persistent collections that work via structural sharing: +[Immutable.js](https://github.com/facebook/immutable-js) はこの問題を解決する別の方法であり、構造の共有を元にした、不変で永続的なデータのコレクションを提供します。 -[Immutable.js](https://github.com/facebook/immutable-js) はこの問題を解決する別の方法であり、構造の共有により動作する不変で永続的なデータのコレクションを提供します。 - -* *Immutable*: once created, a collection cannot be altered at another point in time. -* *不変(イミュータブル*: 一度作成されたら、データのコレクションはその後で変更することはできない。 -* *Persistent*: new collections can be created from a previous collection and a mutation such as set. The original collection is still valid after the new collection is created. +* *不変(イミュータブル)*: 一度作成されたら、データのコレクションはその後で変更することはできない。 * *永続性*: 既存のコレクションに set などの変更操作を行うことで新しいデータのコレクションを作成できる。元のコレクションは新しいデータのコレクションが作成された後も有効である。 -* *Structural Sharing*: new collections are created using as much of the same structure as the original collection as possible, reducing copying to a minimum to improve performance. * *構造の共有*: 新しいデータのコレクションは、元のコレクションが含む同じ構造を可能な限り共有されて作られるので、データのコピー量が減りパフォーマンスが向上する。 -Immutability makes tracking changes cheap. A change will always result in a new object so we only need to check if the reference to the object has changed. For example, in this regular JavaScript code: - -不変性により変更を追跡することのコストが下がります。データを変更した結果は常に新しいオブジェクトになるので、オブジェクトの参照が変化したかどうかのみをチェックすればよくなるのです。例えば、以下の標準のJavaScriptコードで: +不変性により、変化を検出するためのコストが下がります。変化したデータは常に新しいオブジェクトになるので、オブジェクトの参照が違うかをどうかをチェックすればよくなるのです。例えば、以下の通常の JavaScript コード: ```javascript const x = { foo: 'bar' }; @@ -611,9 +415,7 @@ y.foo = 'baz'; x === y; // true ``` -Although `y` was edited, since it's a reference to the same object as `x`, this comparison returns `true`. You can write similar code with immutable.js: - -`y` は編集されたにも関わらず、`x` と同じオブジェクトを参照しているため、上記の比較は `true` を返します。これと同様のコードを immutable.js でも書くことができますが: +`y` は編集されたにも関わらず、`x` と同じオブジェクトを参照しているため、上記の比較は `true` を返します。これと似たコードを immutable.js で書くここうなります: ```javascript @@ -625,14 +427,9 @@ x === y; // false x === z; // true ``` -In this case, since a new reference is returned when mutating `x`, we can use a reference equality check `(x === y)` to verify that the new value stored in `y` is different than the original value stored in `x`. - -この場合、`x` に対する変更の結果、新しい参照が返されるので、参照の比較`(x === y)`だけで、`y` に保存されている新しい値が `x` に保存されていた値とは違うものだ、と確かめられます。 - -Two other libraries that can help use immutable data are [seamless-immutable](https://github.com/rtfeldman/seamless-immutable) and [immutability-helper](https://github.com/kolodny/immutability-helper). +この場合、`x` を変更すると新しい参照が返されるので、参照の比較`(x === y)`をするだけで、`y` に保存されている新しい値は `x` に保存されていた値とは違うことが確認できます。 -その他には、[seamless-immutable](https://github.com/rtfeldman/seamless-immutable) や [immutability-helper](https://github.com/kolodny/immutability-helper) などのライブラリが不変データの使用に役立ちます。 +他の2つのライブラリ、[seamless-immutable](https://github.com/rtfeldman/seamless-immutable) や [immutability-helper](https://github.com/kolodny/immutability-helper) なども不変データの使用に役立ちます。 -Immutable data structures provide you with a cheap way to track changes on objects, which is all we need to implement `shouldComponentUpdate`. This can often provide you with a nice performance boost. -イミュータブルなデータ構造はオブジェクトにおける変更の追跡を容易にし、`shouldComponentUpdate` を実装する際にはこれを使うだけでよくなるのです。これによりパフォーマンスを大幅に向上できることがしばしばあります。 +不変データ構造はオブジェクトの変化の検出を容易にします。そのために必要なのは、`shouldComponentUpdate` の実装で使用することだけであり、パフォーマンスを大幅に向上できる場合があります。 From 401ec0328fd58c8710e48dc2869f10268e174968 Mon Sep 17 00:00:00 2001 From: "UEHARA, Junji" <59012+uehaj@users.noreply.github.com> Date: Fri, 15 Feb 2019 09:22:46 +0900 Subject: [PATCH 04/31] textlint checked --- content/docs/optimizing-performance.md | 108 +++++++++++++++---------- 1 file changed, 65 insertions(+), 43 deletions(-) diff --git a/content/docs/optimizing-performance.md b/content/docs/optimizing-performance.md index 43f7d1028..dd610c2c3 100644 --- a/content/docs/optimizing-performance.md +++ b/content/docs/optimizing-performance.md @@ -6,13 +6,13 @@ redirect_from: - "docs/advanced-performance.html" --- -React は UI の更新時に必要となる高コストな DOM 操作の回数を最小化するために、内部的にいくつかの賢いテクニックを使用しています。多くのアプリケーションでは React を使用するだけで、パフォーマンス向上のための特別な最適化で苦労しなくても、反応速度の速いユーザーインターフェースを実現できます。それでもなお、React アプリケーションを高速化するための方法はいくつか存在します。 +React は UI の更新時に必要となる高コストな DOM 操作の回数を最小化するために、内部的にいくつかの賢いテクニックを使用しています。多くのアプリケーションでは React を使用するだけで、パフォーマンス向上のための特別な最適化を苦労して行わなくても、レスポンスの良いユーザーインターフェースを実現できますが、それでもなお、React アプリケーションを高速化するための方法はいくつか存在します。 ## 本番用ビルドを使用する React アプリケーションでベンチマークを行う場合やパフォーマンスの問題が発生している場合には、ミニファイされた本番用ビルドでテストしていることを確認して下さい。 -デフォルトで React は多くの有用な警告チェックを行いますが、これは開発時にはとても有用です。でもそもために React アプリケーションのサイズは肥大化し、速度が低下してしまうので、アプリケーションのデプロイ時には本番バージョンを使用していることを確認してください。 +デフォルトで React は多くの有用な警告チェックを行い、開発時にはとても有用なのですが、それによって React アプリケーションのサイズは肥大化し、速度が低下してしまうので、アプリケーションのデプロイ時には本番バージョンを使用していることを確認してください。 ビルドプロセスが正しく設定されているか分からない場合、[React Developer Tools for Chrome](https://chrome.google.com/webstore/detail/react-developer-tools/fmkadmapgofadopljbjfkapdkoienihi) をインストールして確認できます。 本番用モードの React のサイトを訪れた場合、アイコンは暗い背景となっています。 @@ -35,7 +35,7 @@ React アプリケーションでベンチマークを行う場合やパフォ npm run build ``` -これによりアプリケーションの本番用ビルドがプロジェクト内の `build/` フォルダに作成されます。 +これでアプリケーションの本番用ビルドがプロジェクト内の `build/` フォルダに作成されます。 これが必要なのは本番用ビルドだけであることに留意してください。通常の開発作業では、`npm start` を使用してください。 @@ -52,7 +52,7 @@ React と ReactDOM をそれぞれ単一ファイル化した本番環境用の ### Brunch -Brunch で最も効率のよい本番用ビルドを行うためには、[`uglify-js-brunch`](https://github.com/brunch/uglify-js-brunch) をインストールしてください: +Brunch で最も効率のよい本番用ビルドを行うには、[`uglify-js-brunch`](https://github.com/brunch/uglify-js-brunch) をインストールしてください: ``` # If you use npm @@ -72,7 +72,7 @@ brunch build -p ### Browserify -Browserify で最も効率の良い本番用ビルドを行うため、いくつかのプラグインをインストールしてください。 +Browserify で最も効率の良い本番用ビルドを行うには、いくつかのプラグインをインストールしてください。 ``` # If you use npm @@ -106,7 +106,7 @@ browserify ./index.js \ ### Rollup -Rollup で最も効率のよい本番用ビルドを行うためには、いくつかのプラグインを以下のようにインストールします。 +Rollup で最も効率のよい本番用ビルドを行うには、いくつかのプラグインを以下のようにインストールします。 ``` # If you use npm @@ -142,9 +142,9 @@ plugins: [ >**Note:** > -> Create React App を利用している場合は、[Create React Appについての前述の説明](#create-react-app)に従ってください。
このセクションは直接 webpack の設定を行いたい人向けです。 +> Create React App を利用している場合は、[Create React App についての前述の説明](#create-react-app)に従ってください。
このセクションは直接 webpack の設定を行いたい人向けです。 -webpack で最も効率のよい本番用ビルドを行うためには、本番ビルドの設定中に必ず以下のプラグインを含めるようにしてください。 +webpack で最も効率のよい本番用ビルドを行うには、本番ビルドの設定中に必ず以下のプラグインを含めるようにしてください。 ```js new webpack.DefinePlugin({ @@ -168,26 +168,34 @@ Chrome での操作は以下の通り。 1. 一時的に **React DevTools を含むすべての Chrome 拡張機能を無効にする**。無効にしないと、結果が正確でなくなる可能性があります。 2. アプリケーションが開発モードで動作していることを確認する。 +<<<<<<< HEAD 3. Chrome DevTools の**[パフォーマンス](https://developers.google.com/web/tools/chrome-devtools/evaluate-performance/timeline-tool)タブ**を開いて **Record(記録)** ボタンを押す。 4. プロファイル対象のアクションを実行する。なお、20秒以上は記録しないでください。さもないと Chrome がハングアップすることがあります。 +||||||| parent of 257bc669... textlint checked +3. Chrome DevTools の**[パフォーマンス](https://developers.google.com/web/tools/chrome-devtools/evaluate-performance/timeline-tool)タブ**を開いて **Record(記録)** ボタンを押す。 +4. プロファイル対象のアクションを実行する。なお、20秒以上は記録しないでください。さもないと Chrome がハングアップすることがあります。 +======= +3. Chrome DevTools の[**パフォーマンス**](https://developers.google.com/web/tools/chrome-devtools/evaluate-performance/timeline-tool)タブを開いて **Record(記録)** ボタンを押す。 +4. プロファイル対象のアクションを実行する。なお、20 秒以上は記録しないでください。さもないと Chrome がハングアップすることがあります。 +>>>>>>> 257bc669... textlint checked 5. 記録を停止する。 6. React イベントが **User Timing** ラベルの下にグループ化される。 さらなる詳細については、[Ben Schwarz によるこの記事](https://calibreapp.com/blog/2017-11-28-debugging-react/)を参照ください。 -**プロファイル結果の数値は相対的なものであり、コンポーネントは本番環境ではより速くレンダリングされる**ことに注意してください。それでも、関係のない UI が誤って更新されているのを見つけたり、どの程度の頻度と深さで UI の更新が発生するのかを知る手助けになるはずです。 +**プロファイル結果の数値は相対的なものであり、コンポーネントは本番環境ではより速くレンダリングされる**ことに注意してください。それでも、無関係な UI 部分が誤って更新されているのを見つけたり、どの程度の頻度と深さで UI の更新が発生するのかを知る手助けになるはずです。 現時点では、Chrome、Edge、そして IE のみがこの機能をサポートするブラウザですが、私達は標準の [User Timing API](https://developer.mozilla.org/en-US/docs/Web/API/User_Timing_API) を採用しているので、より多くのブラウザがサポートしてくれることを期待しています。 ## DevToolsプロファイラを使用したコンポーネントのプロファイリング -`react-dom` 16.5 以降と`react-native` 0.57 以降では、開発モードにおける強化されたプロファイリング機能を React DevTools プロファイラにて提供しています。このプロファイラの概要がブログ記事「[React プロファイラの紹介(Introduction the React Profiler)](/blog/2018/09/10/introducing-the-react-profiler.html)」で説明されています。チュートリアル動画も [YouTube で入手できます](https://www.youtube.com/watch?v=nySib7ipZdk)。 +`react-dom` 16.5 以降と `react-native` 0.57 以降では、開発モードにおける強化されたプロファイリング機能を React DevTools プロファイラにて提供しています。このプロファイラの概要がブログ記事「[React プロファイラの紹介(Introduction the React Profiler)](/blog/2018/09/10/introducing-the-react-profiler.html)」で説明されています。チュートリアル動画も [YouTube で入手できます](https://www.youtube.com/watch?v=nySib7ipZdk)。 -React DevToolsをまだインストールしていない場合は、以下で見つけることができます。 +React DevTools をまだインストールしていない場合は、以下で見つけることができます。 -- [Chromeブラウザ拡張](https://chrome.google.com/webstore/detail/react-developer-tools/fmkadmapgofadopljbjfkapdkoienihi?hl=en) -- [Firefoxブラウザ拡張](https://addons.mozilla.org/en-GB/firefox/addon/react-devtools/) -- [スタンドアロンのNodeパッケージ](https://www.npmjs.com/package/react-devtools) +- [Chrome ブラウザ拡張](https://chrome.google.com/webstore/detail/react-developer-tools/fmkadmapgofadopljbjfkapdkoienihi?hl=en) +- [Firefox ブラウザ拡張](https://addons.mozilla.org/en-GB/firefox/addon/react-devtools/) +- [スタンドアロンの Node パッケージ](https://www.npmjs.com/package/react-devtools) > Note: > @@ -195,37 +203,51 @@ React DevToolsをまだインストールしていない場合は、以下で見 ## 長いリストの仮想化 -アプリケーションが長いデータのリスト(数百〜数千行)をレンダリングする場合は、「ウィンドウイング」として知られるテクニックを使うことをおすすめします。このテクニックでは、ある瞬間ごとにはリストの小さな部分集合のみを描画することで、作成する DOM ノードの数およびコンポーネントの再描画にかかる時間を大幅に削減することができます。 +アプリケーションが長いデータのリスト(数百〜数千行)をレンダリングする場合は、「ウィンドウイング」として知られるテクニックを使うことをおすすめします。このテクニックでは、ある瞬間ごとにはリストの小さな部分集合のみを描画することで、生成する DOM ノードの数およびコンポーネントの再描画にかかる時間を大幅に削減することができます。 -[react-window](https://react-window.now.sh/)と[react-virtualized](https://bvaughn.github.io/react-virtualized/)は人気があるウィンドウイング処理のライブラリです。これらはリスト、グリッド、および表形式のデータを表示するための、いくつかの再利用可能コンポーネントを提供しています。[Twitter](https://medium.com/@paularmstrong/twitter-lite-and-high-performance-react-progressive-web-apps-at-scale-d28a00e780a3) が行なっているように、アプリケーションの特定のユースケースに合わせた追加的な処理をする場合は、独自のウィンドウイング処理のコンポーネントを作成することもできます。 +[react-window](https://react-window.now.sh/) と [react-virtualized](https://bvaughn.github.io/react-virtualized/) は人気があるウィンドウイング処理のライブラリです。これらはリスト、グリッド、および表形式のデータを表示するための、いくつかの再利用可能コンポーネントを提供しています。[Twitter](https://medium.com/@paularmstrong/twitter-lite-and-high-performance-react-progressive-web-apps-at-scale-d28a00e780a3) が行なっているような、アプリケーションの特定のユースケースに合わせた追加的な処理をする場合は、独自のウィンドウイング処理のコンポーネントを作成することもできます。 +<<<<<<< HEAD ## リコンシリエーション(差分検出、突き合せ処理)を避ける +||||||| parent of 257bc669... textlint checked +## リコンシリエーション(差分検出、突き合せ処理)を避ける {#avoid-reconciliation} +======= +## リコンシリエーション(差分検出処理)を避ける {#avoid-reconciliation} +>>>>>>> 257bc669... textlint checked +<<<<<<< HEAD React はレンダリングされた UI の内部表現を構築し、維持します。それにはコンポーネントが返した React 要素も含まれています。 React は、この内部表現を使うことによってJavaScript オブジェクトの操作より遅くなりうる不要な DOM ノードの作成やアクセスを回避します。この内部表現はしばしば「仮想DOM 」と呼ばれますが、React Native 上でも同様に動くものです。 +||||||| parent of 257bc669... textlint checked +React はレンダリングされた UI の内部表現を構築し、維持します。それにはコンポーネントが返した React 要素も含まれています。 +React は、この内部表現を使うことによってJavaScript オブジェクトの操作より遅くなりうる不要な DOM ノードの作成やアクセスを回避します。この内部表現はしばしば「仮想DOM」と呼ばれますが、React Native 上でも同様に動くものです。 +======= +React はレンダリングされた UI の内部表現を構築し、維持します。その内部表現にはコンポーネントが返した React 要素も含まれています。 +React はこの内部表現を使うことによって、JavaScript オブジェクトの操作よりも操作が遅くなるかもしれない DOM ノードの不要な作成やアクセスを回避します。この内部表現はしばしば「仮想 DOM」と呼ばれますが、React Native 上でも同様に動くものです。 +>>>>>>> 257bc669... textlint checked -コンポーネントの props や state が変更された場合、React は新しく返された要素と以前にレンダリングされたものとを比較することで、実 DOM の更新が必要かを判断します。それらが等しくない場合、React は DOM を更新します。 +コンポーネントの props や state が変更された場合、React は新しく返された要素と以前にレンダリングされたものとを比較することで、実際の DOM の更新が必要かを判断します。それらが等しくない場合、React は DOM を更新します。 -以下のReact DevToolsを使用することで、仮想DOMのこれらの再レンダリングを視覚化できるようになりました。 +以下の React DevTools を使用することで、仮想 DOM のこれらの再レンダリングを視覚化できるようになりました。 -- [Chromeブラウザ拡張](https://chrome.google.com/webstore/detail/react-developer-tools/fmkadmapgofadopljbjfkapdkoienihi?hl=en) -- [Firefoxブラウザ拡張](https://addons.mozilla.org/en-GB/firefox/addon/react-devtools/) -- [スタンドアロンNodeパッケージ](https://www.npmjs.com/package/react-devtools) +- [Chrome ブラウザ拡張](https://chrome.google.com/webstore/detail/react-developer-tools/fmkadmapgofadopljbjfkapdkoienihi?hl=en) +- [Firefox ブラウザ拡張](https://addons.mozilla.org/en-GB/firefox/addon/react-devtools/) +- [スタンドアロン Node パッケージ](https://www.npmjs.com/package/react-devtools) 開発者コンソールの **React** タブで **Highlight Updates** オプションを選択します:
How to enable highlight updates
-ページを操作すると、再レンダリングされたコンポーネントの周囲に色付きの枠線が一定時間表示されます。これにより、不要な再レンダリングを見つけることができます。この React DevTools 機能の詳細については、[Ben Edelstein](https://blog.logrocket.com/@edelstein)による[このブログ投稿](https://blog.logrocket.com/make-react-fast-again-part-3-highlighting-component-updates-6119e45e6833)から学ぶことができます。 +ページを操作すると、再レンダリングされたコンポーネントの周囲に色付きの枠線が一定時間表示されます。これにより、不要な再レンダリングを見つけることができます。React DevTools のこの機能の詳細については、[Ben Edelstein](https://blog.logrocket.com/@edelstein) による[ブログ投稿](https://blog.logrocket.com/make-react-fast-again-part-3-highlighting-component-updates-6119e45e6833)から学ぶことができます。 以下の例を考えて見ましょう。
React DevTools Highlight Updates example
-2つ目の TODO 項目を入力しているとき、1つ目の TODO 項目もキーストロークの度に画面上で点滅することに注意してください。これは、React が入力によって一緒に再レンダリングしていることを意味します。 これは「無駄な」レンダリングと呼ばれることがあります。最初の TODO 項目の内容は変更されておらず、再レンダリングの必要がないことを我々は知っていますが、React はそれを知りません。 +2 つ目の TODO 項目を入力しているとき、1 つ目の TODO 項目もキーストロークの度に画面上で点滅することに注意してください。これは、入力によって React が一緒に再レンダリングしていることを意味します。これは「無駄な」レンダリングと呼ばれることがあります。最初の TODO 項目の内容は変更されていないので、再レンダリングの必要がないことを我々は知っていますが、React はそれを知りません。 -React は変更された DOM ノードだけを更新するとはいえ、再レンダリングには時間がかかります。多少の時間がかかっても多くの場合は問題にはなりませんが、遅延が目立つ場合、再レンダリングプロセスが開始される前にトリガーされるライフサイクル関数 `shouldComponentUpdate` をオーバーライドすることで、スピードを抜本的に向上できます。この関数のデフォルトの実装は `true`を返し、React にそのまま更新処理を実行させます: +React は変更された DOM ノードだけを更新するとはいえ、再レンダリングには時間がかかります。多少の時間がかかっても多くの場合は問題にはなりませんが、遅延が目立つ場合、再レンダリングプロセスが開始される前にトリガーされるライフサイクル関数 `shouldComponentUpdate` をオーバーライド定義することで、スピードを抜本的に向上できます。この関数のデフォルトの実装は `true` を返し、React に更新処理をそのまま実行させます: ```javascript shouldComponentUpdate(nextProps, nextState) { @@ -235,12 +257,12 @@ shouldComponentUpdate(nextProps, nextState) { ある状況においてコンポーネントを更新する必要がないと分かっているなら、`shouldComponentUpdate` から `false` を返すことにより、該当コンポーネントおよび配下への `render()` 呼び出しを含む、レンダリング処理の全体をスキップすることができます。 -ほとんどの場合には、手書きの `shouldComponentUpdate()` を定義する代わりに[`React.PureComponent`](/docs/react-api.html#reactpurecomponent)を継承できます。 これは現在と直前の props と state に対する浅い比較(Shallow Comparison)を行う `shouldComponentUpdate()` を実装することと同じです。 +ほとんどの場合には、手書きの `shouldComponentUpdate()` を定義する代わりに [`React.PureComponent`](/docs/react-api.html#reactpurecomponent) を継承できます。これは現在と直前の props と state に対する浅い(Shallow)比較を行う `shouldComponentUpdate()` を実装することと同じです。 ## shouldComponentUpdate の実際の動作 -以下のようなコンポーネントのサブツリーがあるとします。それぞれ、`SCU` は `shouldComponentUpdate` が返した値(訳注:緑はtrue、赤は false)を示し、`vDOMEq` はレンダリングされた React 要素が等しかったかどうか(訳注:緑は等しい、赤は等しくない)を示します。 -最後に、円の色はコンポーネントに対してツリーを比較して合わせ込むためのリコンシリエーション処理が本来は必要だったのかどうか(訳注:緑は不要、赤は必要)を示します。 +以下のようなコンポーネントのサブツリーがあるとします。それぞれ、`SCU` は `shouldComponentUpdate` が返した値(訳注:緑は true、赤は false)を示し、`vDOMEq` はレンダリングされた React 要素が等しかったかどうか(訳注:緑は等しい、赤は等しくない)を示します。 +最後に、円の色はコンポーネントに対してツリーの差分を検出するリコンシリエーション処理を必要としたのかどうか(訳注:緑は不要、赤は必要)を示します。

@@ -286,7 +308,7 @@ class CounterButton extends React.Component { } ``` -このコードは、`shouldComponentUpdate` は `props.color` と `state.count` のいずれかの変化を単にチェックしているだけです。これらの値が変化していなければコンポーネントは更新されません。コンポーネントがもっと複雑な場合は、`props` と `state` のすべてのフィールドに対して「浅い(Shallow)比較」をするという同種のパターンでコンポーネント更新の必要性を決定できます。このパターンはあまりに一般的なので、React はこのロジックのためのヘルパーを用意しており、`React.PureComponent` から継承するだけで使用できます。なので以下のコードで前述のコードと同じことをよりシンプルに実装できます。 +このコードは、`shouldComponentUpdate` は `props.color` または `state.count` の変化の有無を単にチェックしているだけです。これらの値が変化していなければコンポーネントは更新されません。コンポーネントがもっと複雑な場合は、`props` と `state` のすべてのフィールドに対して「浅い(Shallow)比較」をするという同種のパターンでコンポーネント更新の必要性を決定できます。このパターンはあまりに一般的なので、React はこのロジックのためのヘルパーを用意しており、`React.PureComponent` から継承するだけで使用できます。なので以下のコードで前述のコードと同じことをよりシンプルに実装できます。 ```js class CounterButton extends React.PureComponent { @@ -307,9 +329,9 @@ class CounterButton extends React.PureComponent { } ``` -ほとんどの場合、自分で `shouldComponentUpdate` を記述する代わりに `React.PureComponent` を使うことができます。もっとも、浅い(shallow)比較を行うだけですので、浅い比較では検出できない形で props や state が変更されている可能性がある場合には使えません。 +ほとんどの場合、自分で `shouldComponentUpdate` を記述する代わりに `React.PureComponent` を使うことができます。もっとも、浅い比較を行うだけですので、浅い比較では検出できない形で props や state が変更されている可能性がある場合には使えません。 -この事はより複雑なデータ構造の場合には問題となります。例えば、カンマ区切りで単語をレンダリングする `ListOfWords` コンポーネントと、ボタンをクリックしてリストに単語を追加できる親コンポーネント `WordAdder` が必要だとしましょう。以下のコードは正しく動作しません。 +この事はより複雑なデータ構造の場合には問題となります。例えば、カンマ区切りで単語をレンダリングする `ListOfWords` コンポーネントと、ボタンをクリックしてリストに単語を追加できる親コンポーネント `WordAdder` が必要だとして、以下のコードは正しく動作しません。 ```javascript class ListOfWords extends React.PureComponent { @@ -345,11 +367,11 @@ class WordAdder extends React.Component { } ``` -問題は `PureComponent` が `this.props.words` の古い値と新しい値を単純に比較していることにあります。上記のコードでは `WordAdder` の handleClick メソッド内で `words` 配列の内容を直接変更してしまうので、`this.props.words` の新旧の値は、たとえ配列内の実際の単語が変更されていたとしても、比較の結果同じだとみなしてしまうのです。そのため `ListOfWords` はレンダリングすべき新しい単語が追加されているにも関わらず、更新されません。 +問題は `PureComponent` が `this.props.words` の古い値と新しい値を単純に比較していることにあります。上記のコードでは `WordAdder` の handleClick メソッド内で `words` 配列の内容を破壊的に変更してしまうので、`this.props.words` の新旧の値は、たとえ配列内の実際の単語が変更されていたとしても、比較の結果同じだとみなしてしまうのです。そのため `ListOfWords` はレンダリングすべき新しい単語が追加されているにも関わらず、更新されません。 ## データを変更しないことの効果 -この問題を避ける最も単純な方法は、props や state として使用する値の(破壊的)変更を避けることです。例えば、上記の `handleClick` メソッドは `concat` を使って以下のように書き換えることができます: +この問題を避ける最も単純な方法は、props や state として使用する値の破壊的変更を避けることです。例えば、上記の `handleClick` メソッドは `concat` を使って以下のように書き換えることができます: ```javascript handleClick() { @@ -370,7 +392,7 @@ handleClick() { }; ``` -同様に、オブジェクトについても破壊的変更をするコードを破壊的変更をしないように書き換えることができます。例えば、`colormap` というオブジェクトがあり、`colormap.right` を `'blue'` に変更する関数が必要だとしましょう。以下のように書くことも可能ですが、 +同様に、オブジェクトについても破壊的変更をするコードをしないように書き換えることができます。例えば、`colormap` というオブジェクトがあり、`colormap.right` を `'blue'` に更新する関数が必要だとしましょう。以下のように書くことも可能ですが、 ```js function updateColorMap(colormap) { @@ -386,9 +408,9 @@ function updateColorMap(colormap) { } ``` -これで、`updateColorMap` は古いオブジェクトを破壊的に変更するのではなく新しいオブジェクトを返すようになります。`Object.assign` は ES6 からの機能であり、ポリフィルが必要です(訳注:ブラウザや処理系がES6に未対応の場合)。 +これで、`updateColorMap` は古いオブジェクトを破壊的変更するのではなく新しいオブジェクトを返すようになります。`Object.assign` は ES6 からの機能であり、ポリフィルが必要です(訳注:ブラウザや処理系が ES6 に未対応の場合)。 -オブジェクトに対して同様に破壊的変更を伴わない更新を容易にする[オブジェクトのスプレッドプロパティ構文](https://github.com/sebmarkbage/ecmascript-rest-spread)を JavaScript に追加することが提案されています: +同様に、オブジェクトに対しても破壊的変更をしない更新を容易に記述できるようにする[オブジェクトのスプレッドプロパティ構文](https://github.com/sebmarkbage/ecmascript-rest-spread)を JavaScript に追加することが提案されています(訳注:[ECMAScript 2018](https://developer.mozilla.org/ja/docs/Web/JavaScript/Reference/Operators/Spread_syntax) で正式採用されました): ```js function updateColorMap(colormap) { @@ -398,15 +420,15 @@ function updateColorMap(colormap) { Create React App を使用しているなら、`Object.assign` およびオブジェクトのスプレッド構文の両方がデフォルトで利用できます。 -## イミュータブルなデータ構造の使用 +## 不変(イミュータブル)なデータ構造の使用 {#using-immutable-data-structures} [Immutable.js](https://github.com/facebook/immutable-js) はこの問題を解決する別の方法であり、構造の共有を元にした、不変で永続的なデータのコレクションを提供します。 -* *不変(イミュータブル)*: 一度作成されたら、データのコレクションはその後で変更することはできない。 -* *永続性*: 既存のコレクションに set などの変更操作を行うことで新しいデータのコレクションを作成できる。元のコレクションは新しいデータのコレクションが作成された後も有効である。 -* *構造の共有*: 新しいデータのコレクションは、元のコレクションが含む同じ構造を可能な限り共有されて作られるので、データのコピー量が減りパフォーマンスが向上する。 +* *不変性*: 一度作成されたら、データのコレクションはその後で変更されることはない。 +* *永続性*: 既存のコレクションから、あるいはそれに set などの変更操作を行うことで新しいデータのコレクションを作成することができる。元のコレクションは新しいデータのコレクションが作成された後も有効である。 +* *構造の共有*: 新しいデータのコレクションは、元のコレクションが含む同じ構造を可能な限り共有して作られるので、データのコピー量が減りパフォーマンスが向上する。 -不変性により、変化を検出するためのコストが下がります。変化したデータは常に新しいオブジェクトになるので、オブジェクトの参照が違うかをどうかをチェックすればよくなるのです。例えば、以下の通常の JavaScript コード: +不変性により、変化を検出するためのコストが下がります。変化したデータは常に新しいオブジェクトになるので、オブジェクトの参照が違うかをどうかをチェックすればよくなるのです。例えば、以下の通常の JavaScript コードにおいて、 ```javascript const x = { foo: 'bar' }; @@ -415,7 +437,7 @@ y.foo = 'baz'; x === y; // true ``` -`y` は編集されたにも関わらず、`x` と同じオブジェクトを参照しているため、上記の比較は `true` を返します。これと似たコードを immutable.js で書くここうなります: +ここで `y` は編集されたにも関わらず、`x` と同じオブジェクトを参照しているため、上記の比較は `true` を返します。これと似たコードを immutable.js で書くとこうなります: ```javascript @@ -429,7 +451,7 @@ x === z; // true この場合、`x` を変更すると新しい参照が返されるので、参照の比較`(x === y)`をするだけで、`y` に保存されている新しい値は `x` に保存されていた値とは違うことが確認できます。 -他の2つのライブラリ、[seamless-immutable](https://github.com/rtfeldman/seamless-immutable) や [immutability-helper](https://github.com/kolodny/immutability-helper) なども不変データの使用に役立ちます。 +他にも 2 つのライブラリ、[seamless-immutable](https://github.com/rtfeldman/seamless-immutable) や [immutability-helper](https://github.com/kolodny/immutability-helper) なども不変データの使用を助けてくれます。 -不変データ構造はオブジェクトの変化の検出を容易にします。そのために必要なのは、`shouldComponentUpdate` の実装で使用することだけであり、パフォーマンスを大幅に向上できる場合があります。 +不変データ構造はオブジェクトの変化の検出を容易にします。そのために必要なのは、それを使用して `shouldComponentUpdate` を実装することだけです。これによってパフォーマンスを大幅に向上できる場合があります。 From fb7932019e179a26985c3a5af76413d5bce055b8 Mon Sep 17 00:00:00 2001 From: "UEHARA, Junji" <59012+uehaj@users.noreply.github.com> Date: Sat, 16 Feb 2019 17:59:59 +0900 Subject: [PATCH 05/31] fix conflict --- content/docs/optimizing-performance.md | 24 +----------------------- 1 file changed, 1 insertion(+), 23 deletions(-) diff --git a/content/docs/optimizing-performance.md b/content/docs/optimizing-performance.md index dd610c2c3..4b669914d 100644 --- a/content/docs/optimizing-performance.md +++ b/content/docs/optimizing-performance.md @@ -168,16 +168,8 @@ Chrome での操作は以下の通り。 1. 一時的に **React DevTools を含むすべての Chrome 拡張機能を無効にする**。無効にしないと、結果が正確でなくなる可能性があります。 2. アプリケーションが開発モードで動作していることを確認する。 -<<<<<<< HEAD -3. Chrome DevTools の**[パフォーマンス](https://developers.google.com/web/tools/chrome-devtools/evaluate-performance/timeline-tool)タブ**を開いて **Record(記録)** ボタンを押す。 -4. プロファイル対象のアクションを実行する。なお、20秒以上は記録しないでください。さもないと Chrome がハングアップすることがあります。 -||||||| parent of 257bc669... textlint checked -3. Chrome DevTools の**[パフォーマンス](https://developers.google.com/web/tools/chrome-devtools/evaluate-performance/timeline-tool)タブ**を開いて **Record(記録)** ボタンを押す。 -4. プロファイル対象のアクションを実行する。なお、20秒以上は記録しないでください。さもないと Chrome がハングアップすることがあります。 -======= 3. Chrome DevTools の[**パフォーマンス**](https://developers.google.com/web/tools/chrome-devtools/evaluate-performance/timeline-tool)タブを開いて **Record(記録)** ボタンを押す。 4. プロファイル対象のアクションを実行する。なお、20 秒以上は記録しないでください。さもないと Chrome がハングアップすることがあります。 ->>>>>>> 257bc669... textlint checked 5. 記録を停止する。 6. React イベントが **User Timing** ラベルの下にグループ化される。 @@ -207,24 +199,10 @@ React DevTools をまだインストールしていない場合は、以下で [react-window](https://react-window.now.sh/) と [react-virtualized](https://bvaughn.github.io/react-virtualized/) は人気があるウィンドウイング処理のライブラリです。これらはリスト、グリッド、および表形式のデータを表示するための、いくつかの再利用可能コンポーネントを提供しています。[Twitter](https://medium.com/@paularmstrong/twitter-lite-and-high-performance-react-progressive-web-apps-at-scale-d28a00e780a3) が行なっているような、アプリケーションの特定のユースケースに合わせた追加的な処理をする場合は、独自のウィンドウイング処理のコンポーネントを作成することもできます。 -<<<<<<< HEAD -## リコンシリエーション(差分検出、突き合せ処理)を避ける -||||||| parent of 257bc669... textlint checked -## リコンシリエーション(差分検出、突き合せ処理)を避ける {#avoid-reconciliation} -======= ## リコンシリエーション(差分検出処理)を避ける {#avoid-reconciliation} ->>>>>>> 257bc669... textlint checked - -<<<<<<< HEAD -React はレンダリングされた UI の内部表現を構築し、維持します。それにはコンポーネントが返した React 要素も含まれています。 -React は、この内部表現を使うことによってJavaScript オブジェクトの操作より遅くなりうる不要な DOM ノードの作成やアクセスを回避します。この内部表現はしばしば「仮想DOM 」と呼ばれますが、React Native 上でも同様に動くものです。 -||||||| parent of 257bc669... textlint checked -React はレンダリングされた UI の内部表現を構築し、維持します。それにはコンポーネントが返した React 要素も含まれています。 -React は、この内部表現を使うことによってJavaScript オブジェクトの操作より遅くなりうる不要な DOM ノードの作成やアクセスを回避します。この内部表現はしばしば「仮想DOM」と呼ばれますが、React Native 上でも同様に動くものです。 -======= + React はレンダリングされた UI の内部表現を構築し、維持します。その内部表現にはコンポーネントが返した React 要素も含まれています。 React はこの内部表現を使うことによって、JavaScript オブジェクトの操作よりも操作が遅くなるかもしれない DOM ノードの不要な作成やアクセスを回避します。この内部表現はしばしば「仮想 DOM」と呼ばれますが、React Native 上でも同様に動くものです。 ->>>>>>> 257bc669... textlint checked コンポーネントの props や state が変更された場合、React は新しく返された要素と以前にレンダリングされたものとを比較することで、実際の DOM の更新が必要かを判断します。それらが等しくない場合、React は DOM を更新します。 From ddf71009de7278243fa75405919724d4cba16d0e Mon Sep 17 00:00:00 2001 From: Soichiro Miki Date: Sat, 2 Mar 2019 19:09:46 +0900 Subject: [PATCH 06/31] Update content/docs/optimizing-performance.md Co-Authored-By: uehaj <59012+uehaj@users.noreply.github.com> --- content/docs/optimizing-performance.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/content/docs/optimizing-performance.md b/content/docs/optimizing-performance.md index 4b669914d..5fcaf6a07 100644 --- a/content/docs/optimizing-performance.md +++ b/content/docs/optimizing-performance.md @@ -82,7 +82,7 @@ npm install --save-dev envify uglify-js uglifyify yarn add --dev envify uglify-js uglifyify ``` -本番用ビルドを作成するには、以下の変換(transform)を追加してください(**順番は重要です**)。 +本番用ビルドを作成するには、以下の変換 (transform) を追加してください(**順番は重要です**)。 * [`envify`](https://github.com/hughsk/envify) 変換は正しいビルド環境が確実に設定されるようにします。グローバルに設定してください (`-g`)。 * [`uglifyify`](https://github.com/hughsk/uglifyify) 変換は開発用にインポートしたライブラリを削除します。これもグローバルに設定してください (`-g`)。 From 59bbfaa00bde0a18247b74a3ccc72bcd7b4ded42 Mon Sep 17 00:00:00 2001 From: Soichiro Miki Date: Sat, 2 Mar 2019 19:12:37 +0900 Subject: [PATCH 07/31] Update content/docs/optimizing-performance.md Co-Authored-By: uehaj <59012+uehaj@users.noreply.github.com> --- content/docs/optimizing-performance.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/content/docs/optimizing-performance.md b/content/docs/optimizing-performance.md index 5fcaf6a07..b8b670aad 100644 --- a/content/docs/optimizing-performance.md +++ b/content/docs/optimizing-performance.md @@ -84,7 +84,7 @@ yarn add --dev envify uglify-js uglifyify 本番用ビルドを作成するには、以下の変換 (transform) を追加してください(**順番は重要です**)。 -* [`envify`](https://github.com/hughsk/envify) 変換は正しいビルド環境が確実に設定されるようにします。グローバルに設定してください (`-g`)。 +* [`envify`](https://github.com/hughsk/envify) 変換は正しいビルド用の環境変数が確実に設定されるようにします。グローバルに設定してください (`-g`)。 * [`uglifyify`](https://github.com/hughsk/uglifyify) 変換は開発用にインポートしたライブラリを削除します。これもグローバルに設定してください (`-g`)。 * 最後に結果として出力されたものを、名前の圧縮のために [`uglify-js`](https://github.com/mishoo/UglifyJS2) にパイプします([理由を読む](https://github.com/hughsk/uglifyify#motivationusage))。 From 5ab1f9d3b5610e5d0f836ff2ca17947ee844ccb9 Mon Sep 17 00:00:00 2001 From: Soichiro Miki Date: Sat, 2 Mar 2019 19:12:53 +0900 Subject: [PATCH 08/31] Update content/docs/optimizing-performance.md Co-Authored-By: uehaj <59012+uehaj@users.noreply.github.com> --- content/docs/optimizing-performance.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/content/docs/optimizing-performance.md b/content/docs/optimizing-performance.md index b8b670aad..9961cdf81 100644 --- a/content/docs/optimizing-performance.md +++ b/content/docs/optimizing-performance.md @@ -118,7 +118,7 @@ yarn add --dev rollup-plugin-commonjs rollup-plugin-replace rollup-plugin-uglify 本番用ビルドを作成するには、以下のプラグインを追加してください(**順番は重要**です)。 -* [`replace`](https://github.com/rollup/rollup-plugin-replace) プラグインは正しいビルド環境が確実に設定されるようにします。 +* [`replace`](https://github.com/rollup/rollup-plugin-replace) プラグインは正しいビルド用の環境変数が確実に設定されるようにします。 * [`commonjs`](https://github.com/rollup/rollup-plugin-commonjs) プラグインは Rollup で CommonJS をサポートできるようにします。 * [`uglify`](https://github.com/TrySound/rollup-plugin-uglify) プラグインは出力された最終的なバンドルを圧縮し、mangle(訳注: 変数名や識別子を短縮)します。 From 05ff20c5d0cb07bea30480142654c8ff2b0d719e Mon Sep 17 00:00:00 2001 From: Soichiro Miki Date: Sat, 2 Mar 2019 19:13:10 +0900 Subject: [PATCH 09/31] Update content/docs/optimizing-performance.md Co-Authored-By: uehaj <59012+uehaj@users.noreply.github.com> --- content/docs/optimizing-performance.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/content/docs/optimizing-performance.md b/content/docs/optimizing-performance.md index 9961cdf81..dcabda150 100644 --- a/content/docs/optimizing-performance.md +++ b/content/docs/optimizing-performance.md @@ -136,7 +136,7 @@ plugins: [ 設定例の全体はこの [gist を参照](https://gist.github.com/Rich-Harris/cb14f4bc0670c47d00d191565be36bf0)してください。 -これらが必要なのは本番用ビルドだけであることに留意してください。React の有用な警告表示が隠されたり、ビルド速度が大幅に遅くなったりしますので、開発用では `uglify` プラグインもしくは `replace` プラグインを`'production'` という値で適用しないでください。 +これらが必要なのは本番用ビルドだけであることに留意してください。React の有用な警告表示が隠されたり、ビルド速度が大幅に遅くなったりしますので、開発用では `uglify` プラグインもしくは `replace` プラグインを `'production'` という値で適用しないでください。 ### webpack From 2876b740a9e82a3a1d43ce72e56046abc0c564bd Mon Sep 17 00:00:00 2001 From: Soichiro Miki Date: Sat, 2 Mar 2019 19:13:27 +0900 Subject: [PATCH 10/31] Update content/docs/optimizing-performance.md Co-Authored-By: uehaj <59012+uehaj@users.noreply.github.com> --- content/docs/optimizing-performance.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/content/docs/optimizing-performance.md b/content/docs/optimizing-performance.md index dcabda150..ee0893b95 100644 --- a/content/docs/optimizing-performance.md +++ b/content/docs/optimizing-performance.md @@ -140,7 +140,7 @@ plugins: [ ### webpack ->**Note:** +>**補足:** > > Create React App を利用している場合は、[Create React App についての前述の説明](#create-react-app)に従ってください。
このセクションは直接 webpack の設定を行いたい人向けです。 From ef9ad18ea907cc2e5ab0efc3d276f84d65b4e69c Mon Sep 17 00:00:00 2001 From: Soichiro Miki Date: Sat, 2 Mar 2019 19:14:41 +0900 Subject: [PATCH 11/31] Update content/docs/optimizing-performance.md Co-Authored-By: uehaj <59012+uehaj@users.noreply.github.com> --- content/docs/optimizing-performance.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/content/docs/optimizing-performance.md b/content/docs/optimizing-performance.md index ee0893b95..f575042d0 100644 --- a/content/docs/optimizing-performance.md +++ b/content/docs/optimizing-performance.md @@ -170,7 +170,7 @@ Chrome での操作は以下の通り。 2. アプリケーションが開発モードで動作していることを確認する。 3. Chrome DevTools の[**パフォーマンス**](https://developers.google.com/web/tools/chrome-devtools/evaluate-performance/timeline-tool)タブを開いて **Record(記録)** ボタンを押す。 4. プロファイル対象のアクションを実行する。なお、20 秒以上は記録しないでください。さもないと Chrome がハングアップすることがあります。 -5. 記録を停止する。 +5. 記録を停止する。 6. React イベントが **User Timing** ラベルの下にグループ化される。 さらなる詳細については、[Ben Schwarz によるこの記事](https://calibreapp.com/blog/2017-11-28-debugging-react/)を参照ください。 From 26401756244bc815e920293d1b01e5cf53aa1203 Mon Sep 17 00:00:00 2001 From: Soichiro Miki Date: Sat, 2 Mar 2019 19:15:08 +0900 Subject: [PATCH 12/31] Update content/docs/optimizing-performance.md Co-Authored-By: uehaj <59012+uehaj@users.noreply.github.com> --- content/docs/optimizing-performance.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/content/docs/optimizing-performance.md b/content/docs/optimizing-performance.md index f575042d0..e79e3415b 100644 --- a/content/docs/optimizing-performance.md +++ b/content/docs/optimizing-performance.md @@ -171,7 +171,7 @@ Chrome での操作は以下の通り。 3. Chrome DevTools の[**パフォーマンス**](https://developers.google.com/web/tools/chrome-devtools/evaluate-performance/timeline-tool)タブを開いて **Record(記録)** ボタンを押す。 4. プロファイル対象のアクションを実行する。なお、20 秒以上は記録しないでください。さもないと Chrome がハングアップすることがあります。 5. 記録を停止する。 -6. React イベントが **User Timing** ラベルの下にグループ化される。 +6. React イベントが **User Timing** ラベルの下にグループ化される。 さらなる詳細については、[Ben Schwarz によるこの記事](https://calibreapp.com/blog/2017-11-28-debugging-react/)を参照ください。 From 22a08257243b2e07d337174e5c335f223d2d2765 Mon Sep 17 00:00:00 2001 From: Soichiro Miki Date: Sat, 2 Mar 2019 19:15:43 +0900 Subject: [PATCH 13/31] Update content/docs/optimizing-performance.md Co-Authored-By: uehaj <59012+uehaj@users.noreply.github.com> --- content/docs/optimizing-performance.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/content/docs/optimizing-performance.md b/content/docs/optimizing-performance.md index e79e3415b..f604f4351 100644 --- a/content/docs/optimizing-performance.md +++ b/content/docs/optimizing-performance.md @@ -181,7 +181,7 @@ Chrome での操作は以下の通り。 ## DevToolsプロファイラを使用したコンポーネントのプロファイリング -`react-dom` 16.5 以降と `react-native` 0.57 以降では、開発モードにおける強化されたプロファイリング機能を React DevTools プロファイラにて提供しています。このプロファイラの概要がブログ記事「[React プロファイラの紹介(Introduction the React Profiler)](/blog/2018/09/10/introducing-the-react-profiler.html)」で説明されています。チュートリアル動画も [YouTube で入手できます](https://www.youtube.com/watch?v=nySib7ipZdk)。 +`react-dom` 16.5 以降と `react-native` 0.57 以降では、開発モードにおける強化されたプロファイリング機能を React DevTools プロファイラにて提供しています。このプロファイラの概要はブログ記事 ["Introducing the React Profiler"](/blog/2018/09/10/introducing-the-react-profiler.html) で説明されています。チュートリアル動画も [YouTube で閲覧できます](https://www.youtube.com/watch?v=nySib7ipZdk)。 React DevTools をまだインストールしていない場合は、以下で見つけることができます。 From 4e95d059c9dc5e2011e35ac5123cf53fcbd5dcef Mon Sep 17 00:00:00 2001 From: Soichiro Miki Date: Sat, 2 Mar 2019 19:16:24 +0900 Subject: [PATCH 14/31] Update content/docs/optimizing-performance.md Co-Authored-By: uehaj <59012+uehaj@users.noreply.github.com> --- content/docs/optimizing-performance.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/content/docs/optimizing-performance.md b/content/docs/optimizing-performance.md index f604f4351..0fe348cfe 100644 --- a/content/docs/optimizing-performance.md +++ b/content/docs/optimizing-performance.md @@ -286,7 +286,7 @@ class CounterButton extends React.Component { } ``` -このコードは、`shouldComponentUpdate` は `props.color` または `state.count` の変化の有無を単にチェックしているだけです。これらの値が変化していなければコンポーネントは更新されません。コンポーネントがもっと複雑な場合は、`props` と `state` のすべてのフィールドに対して「浅い(Shallow)比較」をするという同種のパターンでコンポーネント更新の必要性を決定できます。このパターンはあまりに一般的なので、React はこのロジックのためのヘルパーを用意しており、`React.PureComponent` から継承するだけで使用できます。なので以下のコードで前述のコードと同じことをよりシンプルに実装できます。 +このコードは、`shouldComponentUpdate` は `props.color` または `state.count` の変化の有無を単にチェックしているだけです。これらの値が変化していなければコンポーネントは更新されません。コンポーネントがもっと複雑な場合は、`props` と `state` のすべてのフィールドに対して「浅い比較」をするという同種のパターンでコンポーネント更新の必要性を決定できます。このパターンはとても一般的なので、React はこのロジックのためのヘルパーを用意しており、`React.PureComponent` から継承するだけで使用できます。なので以下のコードで前述のコードと同じことをよりシンプルに実装できます。 ```js class CounterButton extends React.PureComponent { From 1790fa9e7bb655492b7058a1076786e64d01bd92 Mon Sep 17 00:00:00 2001 From: Soichiro Miki Date: Sat, 2 Mar 2019 19:17:38 +0900 Subject: [PATCH 15/31] Update content/docs/optimizing-performance.md Co-Authored-By: uehaj <59012+uehaj@users.noreply.github.com> --- content/docs/optimizing-performance.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/content/docs/optimizing-performance.md b/content/docs/optimizing-performance.md index 0fe348cfe..b748bbb8a 100644 --- a/content/docs/optimizing-performance.md +++ b/content/docs/optimizing-performance.md @@ -427,7 +427,7 @@ x === y; // false x === z; // true ``` -この場合、`x` を変更すると新しい参照が返されるので、参照の比較`(x === y)`をするだけで、`y` に保存されている新しい値は `x` に保存されていた値とは違うことが確認できます。 +この場合、`x` を変更すると新しい参照が返されるので、参照の比較 `(x === y)` をするだけで、`y` に保存されている新しい値は `x` に保存されていた値とは違うことが確認できます。 他にも 2 つのライブラリ、[seamless-immutable](https://github.com/rtfeldman/seamless-immutable) や [immutability-helper](https://github.com/kolodny/immutability-helper) なども不変データの使用を助けてくれます。 From 244a46f6b9d8c2c48b6c6e2fd3ca06a94b0c2206 Mon Sep 17 00:00:00 2001 From: Soichiro Miki Date: Sat, 2 Mar 2019 19:20:10 +0900 Subject: [PATCH 16/31] Update content/docs/optimizing-performance.md Co-Authored-By: uehaj <59012+uehaj@users.noreply.github.com> --- content/docs/optimizing-performance.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/content/docs/optimizing-performance.md b/content/docs/optimizing-performance.md index b748bbb8a..3066fffea 100644 --- a/content/docs/optimizing-performance.md +++ b/content/docs/optimizing-performance.md @@ -429,7 +429,7 @@ x === z; // true この場合、`x` を変更すると新しい参照が返されるので、参照の比較 `(x === y)` をするだけで、`y` に保存されている新しい値は `x` に保存されていた値とは違うことが確認できます。 -他にも 2 つのライブラリ、[seamless-immutable](https://github.com/rtfeldman/seamless-immutable) や [immutability-helper](https://github.com/kolodny/immutability-helper) なども不変データの使用を助けてくれます。 +不変データの使用を助けてくる他のライブラリとして [seamless-immutable](https://github.com/rtfeldman/seamless-immutable) や [immutability-helper](https://github.com/kolodny/immutability-helper) の 2 つが挙がります。 不変データ構造はオブジェクトの変化の検出を容易にします。そのために必要なのは、それを使用して `shouldComponentUpdate` を実装することだけです。これによってパフォーマンスを大幅に向上できる場合があります。 From 1a61aa12cd4f12be84e49bc64b96ee1f15d372e9 Mon Sep 17 00:00:00 2001 From: "UEHARA, Junji" <59012+uehaj@users.noreply.github.com> Date: Sat, 2 Mar 2019 19:20:59 +0900 Subject: [PATCH 17/31] fix review commened points --- content/docs/optimizing-performance.md | 30 +++++++++++++++----------- 1 file changed, 17 insertions(+), 13 deletions(-) diff --git a/content/docs/optimizing-performance.md b/content/docs/optimizing-performance.md index 4b669914d..f9a8720bd 100644 --- a/content/docs/optimizing-performance.md +++ b/content/docs/optimizing-performance.md @@ -14,8 +14,7 @@ React アプリケーションでベンチマークを行う場合やパフォ デフォルトで React は多くの有用な警告チェックを行い、開発時にはとても有用なのですが、それによって React アプリケーションのサイズは肥大化し、速度が低下してしまうので、アプリケーションのデプロイ時には本番バージョンを使用していることを確認してください。 -ビルドプロセスが正しく設定されているか分からない場合、[React Developer Tools for Chrome](https://chrome.google.com/webstore/detail/react-developer-tools/fmkadmapgofadopljbjfkapdkoienihi) をインストールして確認できます。 -本番用モードの React のサイトを訪れた場合、アイコンは暗い背景となっています。 +ビルドプロセスが正しく設定されているか分からない場合、[React Developer Tools for Chrome](https://chrome.google.com/webstore/detail/react-developer-tools/fmkadmapgofadopljbjfkapdkoienihi) をインストールして確認できます。本番用モードの React のサイトを訪れた場合、アイコンは暗い背景となっています。 React DevTools on a website with production version of React @@ -142,7 +141,8 @@ plugins: [ >**Note:** > -> Create React App を利用している場合は、[Create React App についての前述の説明](#create-react-app)に従ってください。
このセクションは直接 webpack の設定を行いたい人向けです。 +> Create React App を利用している場合は、[Create React App についての前述の説明](#create-react-app)に従ってください。
+> このセクションは直接 webpack の設定を行いたい人向けです。 webpack で最も効率のよい本番用ビルドを行うには、本番ビルドの設定中に必ず以下のプラグインを含めるようにしてください。 @@ -167,10 +167,15 @@ new webpack.optimize.UglifyJsPlugin() Chrome での操作は以下の通り。 1. 一時的に **React DevTools を含むすべての Chrome 拡張機能を無効にする**。無効にしないと、結果が正確でなくなる可能性があります。 + 2. アプリケーションが開発モードで動作していることを確認する。 + 3. Chrome DevTools の[**パフォーマンス**](https://developers.google.com/web/tools/chrome-devtools/evaluate-performance/timeline-tool)タブを開いて **Record(記録)** ボタンを押す。 + 4. プロファイル対象のアクションを実行する。なお、20 秒以上は記録しないでください。さもないと Chrome がハングアップすることがあります。 + 5. 記録を停止する。 + 6. React イベントが **User Timing** ラベルの下にグループ化される。 さらなる詳細については、[Ben Schwarz によるこの記事](https://calibreapp.com/blog/2017-11-28-debugging-react/)を参照ください。 @@ -181,7 +186,9 @@ Chrome での操作は以下の通り。 ## DevToolsプロファイラを使用したコンポーネントのプロファイリング -`react-dom` 16.5 以降と `react-native` 0.57 以降では、開発モードにおける強化されたプロファイリング機能を React DevTools プロファイラにて提供しています。このプロファイラの概要がブログ記事「[React プロファイラの紹介(Introduction the React Profiler)](/blog/2018/09/10/introducing-the-react-profiler.html)」で説明されています。チュートリアル動画も [YouTube で入手できます](https://www.youtube.com/watch?v=nySib7ipZdk)。 +`react-dom` 16.5 以降と `react-native` 0.57 以降では、開発モードにおける強化されたプロファイリング機能を React DevTools プロファイラにて提供しています。 +このプロファイラの概要がブログ記事「[React プロファイラの紹介(Introduction the React Profiler)](/blog/2018/09/10/introducing-the-react-profiler.html)」で説明されています。 +チュートリアル動画も [YouTube で入手できます](https://www.youtube.com/watch?v=nySib7ipZdk)。 React DevTools をまだインストールしていない場合は、以下で見つけることができます。 @@ -189,9 +196,10 @@ React DevTools をまだインストールしていない場合は、以下で - [Firefox ブラウザ拡張](https://addons.mozilla.org/en-GB/firefox/addon/react-devtools/) - [スタンドアロンの Node パッケージ](https://www.npmjs.com/package/react-devtools) -> Note: +> Note > -> 本番ビルド版 `react-dom` のプロファイリング可能なバンドルとして `react-dom/profiling` が利用可能です。このバンドルの使い方の詳細については、[fb.me/react-profiling](https://fb.me/react-profiling) を参照してください。 +> 本番ビルド版 `react-dom` のプロファイリング可能なバンドルとして `react-dom/profiling` が利用可能です。 +> このバンドルの使い方の詳細については、[fb.me/react-profiling](https://fb.me/react-profiling) を参照してください。 ## 長いリストの仮想化 @@ -201,8 +209,7 @@ React DevTools をまだインストールしていない場合は、以下で ## リコンシリエーション(差分検出処理)を避ける {#avoid-reconciliation} -React はレンダリングされた UI の内部表現を構築し、維持します。その内部表現にはコンポーネントが返した React 要素も含まれています。 -React はこの内部表現を使うことによって、JavaScript オブジェクトの操作よりも操作が遅くなるかもしれない DOM ノードの不要な作成やアクセスを回避します。この内部表現はしばしば「仮想 DOM」と呼ばれますが、React Native 上でも同様に動くものです。 +React はレンダリングされた UI の内部表現を構築し、維持します。その内部表現にはコンポーネントが返した React 要素も含まれています。React はこの内部表現を使うことによって、JavaScript オブジェクトの操作よりも操作が遅くなるかもしれない DOM ノードの不要な作成やアクセスを回避します。この内部表現はしばしば「仮想 DOM」と呼ばれますが、React Native 上でも同様に動くものです。 コンポーネントの props や state が変更された場合、React は新しく返された要素と以前にレンダリングされたものとを比較することで、実際の DOM の更新が必要かを判断します。それらが等しくない場合、React は DOM を更新します。 @@ -239,9 +246,7 @@ shouldComponentUpdate(nextProps, nextState) { ## shouldComponentUpdate の実際の動作 -以下のようなコンポーネントのサブツリーがあるとします。それぞれ、`SCU` は `shouldComponentUpdate` が返した値(訳注:緑は true、赤は false)を示し、`vDOMEq` はレンダリングされた React 要素が等しかったかどうか(訳注:緑は等しい、赤は等しくない)を示します。 -最後に、円の色はコンポーネントに対してツリーの差分を検出するリコンシリエーション処理を必要としたのかどうか(訳注:緑は不要、赤は必要)を示します。 -

+以下のようなコンポーネントのサブツリーがあるとします。それぞれ、`SCU` は `shouldComponentUpdate` が返した値(訳注:緑は true、赤は false)を示し、`vDOMEq` はレンダリングされた React 要素が等しかったかどうか(訳注:緑は等しい、赤は等しくない)を示します。最後に、円の色はコンポーネントに対してツリーの差分を検出するリコンシリエーション処理を必要としたのかどうか(訳注:緑は不要、赤は必要)を示します。
@@ -359,8 +364,7 @@ handleClick() { } ``` -ES6 はこれをより簡潔に実装できる配列の[スプレッド構文](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Spread_operator)をサポートしています。 -Create React App を使用していれば、この構文はデフォルトで利用できます。 +ES6 はこれをより簡潔に実装できる配列の[スプレッド構文](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Spread_operator)をサポートしています。Create React App を使用していれば、この構文はデフォルトで利用できます。 ```js handleClick() { From e67fe3d0f4fadb83fce979badae5e3ca735f83fb Mon Sep 17 00:00:00 2001 From: Soichiro Miki Date: Sat, 2 Mar 2019 19:44:06 +0900 Subject: [PATCH 18/31] Update content/docs/optimizing-performance.md Co-Authored-By: uehaj <59012+uehaj@users.noreply.github.com> --- content/docs/optimizing-performance.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/content/docs/optimizing-performance.md b/content/docs/optimizing-performance.md index e9f762aa5..5bdb6f665 100644 --- a/content/docs/optimizing-performance.md +++ b/content/docs/optimizing-performance.md @@ -436,4 +436,4 @@ x === z; // true 不変データの使用を助けてくる他のライブラリとして [seamless-immutable](https://github.com/rtfeldman/seamless-immutable) や [immutability-helper](https://github.com/kolodny/immutability-helper) の 2 つが挙がります。 -不変データ構造はオブジェクトの変化の検出を容易にします。そのために必要なのは、それを使用して `shouldComponentUpdate` を実装することだけです。これによってパフォーマンスを大幅に向上できる場合があります。 +不変データ構造はオブジェクトの変化の検出を容易にします。まさにそれが `shouldComponentUpdate` の実装に必要なことのすべてです。これによってパフォーマンスを大幅に向上できる場合があります。 From c3d9555e98a2f44b1d2d9115121f7d9ee9d5ea38 Mon Sep 17 00:00:00 2001 From: Soichiro Miki Date: Sat, 2 Mar 2019 20:21:53 +0900 Subject: [PATCH 19/31] Update content/docs/optimizing-performance.md Co-Authored-By: uehaj <59012+uehaj@users.noreply.github.com> --- content/docs/optimizing-performance.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/content/docs/optimizing-performance.md b/content/docs/optimizing-performance.md index 5bdb6f665..581700c2e 100644 --- a/content/docs/optimizing-performance.md +++ b/content/docs/optimizing-performance.md @@ -205,7 +205,7 @@ React DevTools をまだインストールしていない場合は、以下で アプリケーションが長いデータのリスト(数百〜数千行)をレンダーする場合は、「ウィンドウイング」として知られるテクニックを使うことをおすすめします。このテクニックでは、ある瞬間ごとにはリストの小さな部分集合のみを描画することで、生成する DOM ノードの数およびコンポーネントの再描画にかかる時間を大幅に削減することができます。 -[react-window](https://react-window.now.sh/) と [react-virtualized](https://bvaughn.github.io/react-virtualized/) は人気があるウィンドウイング処理のライブラリです。これらはリスト、グリッド、および表形式のデータを表示するための、いくつかの再利用可能コンポーネントを提供しています。[Twitter](https://medium.com/@paularmstrong/twitter-lite-and-high-performance-react-progressive-web-apps-at-scale-d28a00e780a3) が行なっているような、アプリケーションの特定のユースケースに合わせた追加的な処理をする場合は、独自のウィンドウイング処理のコンポーネントを作成することもできます。 +[react-window](https://react-window.now.sh/) と [react-virtualized](https://bvaughn.github.io/react-virtualized/) は人気があるウィンドウイング処理のライブラリです。これらはリスト、グリッド、および表形式のデータを表示するための、いくつかの再利用可能コンポーネントを提供しています。アプリケーションの特定のユースケースに合わせた追加的な処理をする場合は、[Twitter](https://medium.com/@paularmstrong/twitter-lite-and-high-performance-react-progressive-web-apps-at-scale-d28a00e780a3) が行なっているように、独自のウィンドウイング処理のコンポーネントを作成することもできます。 ## リコンシリエーション(差分検出処理)を避ける {#avoid-reconciliation} From d58eee4031f9c713b2b34e8311c418451aad4ab7 Mon Sep 17 00:00:00 2001 From: Soichiro Miki Date: Sat, 2 Mar 2019 20:26:36 +0900 Subject: [PATCH 20/31] Update content/docs/optimizing-performance.md Co-Authored-By: uehaj <59012+uehaj@users.noreply.github.com> --- content/docs/optimizing-performance.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/content/docs/optimizing-performance.md b/content/docs/optimizing-performance.md index 581700c2e..3d6e95da4 100644 --- a/content/docs/optimizing-performance.md +++ b/content/docs/optimizing-performance.md @@ -242,7 +242,7 @@ shouldComponentUpdate(nextProps, nextState) { ある状況においてコンポーネントを更新する必要がないと分かっているなら、`shouldComponentUpdate` から `false` を返すことにより、該当コンポーネントおよび配下への `render()` 呼び出しを含む、レンダー処理の全体をスキップすることができます。 -ほとんどの場合には、手書きの `shouldComponentUpdate()` を定義する代わりに [`React.PureComponent`](/docs/react-api.html#reactpurecomponent) を継承できます。これは現在と直前の props と state に対する浅い(Shallow)比較を行う `shouldComponentUpdate()` を実装することと同じです。 +ほとんどの場合には、手書きの `shouldComponentUpdate()` を定義する代わりに [`React.PureComponent`](/docs/react-api.html#reactpurecomponent) を継承できます。これは現在と直前の props と state に対する浅い (shallow) 比較を行う `shouldComponentUpdate()` を実装することと同じです。 ## shouldComponentUpdate の実際の動作 From 98520f7156163a256835e29fa7d484ac8790052e Mon Sep 17 00:00:00 2001 From: Soichiro Miki Date: Sat, 2 Mar 2019 20:26:52 +0900 Subject: [PATCH 21/31] Update content/docs/optimizing-performance.md Co-Authored-By: uehaj <59012+uehaj@users.noreply.github.com> --- content/docs/optimizing-performance.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/content/docs/optimizing-performance.md b/content/docs/optimizing-performance.md index 3d6e95da4..c06d24185 100644 --- a/content/docs/optimizing-performance.md +++ b/content/docs/optimizing-performance.md @@ -226,7 +226,7 @@ React はレンダーされた UI の内部表現を構築し、維持します ページを操作すると、再レンダーされたコンポーネントの周囲に色付きの枠線が一定時間表示されます。これにより、不要な再レンダーを見つけることができます。React DevTools のこの機能の詳細については、[Ben Edelstein](https://blog.logrocket.com/@edelstein) による[ブログ投稿](https://blog.logrocket.com/make-react-fast-again-part-3-highlighting-component-updates-6119e45e6833)から学ぶことができます。 -以下の例を考えて見ましょう。 +以下の例を考えてみましょう。
React DevTools Highlight Updates example
From 673eee187c5c52afdd631c87a82747acf3c05c7e Mon Sep 17 00:00:00 2001 From: "UEHARA, Junji" <59012+uehaj@users.noreply.github.com> Date: Sat, 2 Mar 2019 20:36:01 +0900 Subject: [PATCH 22/31] all review comment are resolved --- content/docs/optimizing-performance.md | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/content/docs/optimizing-performance.md b/content/docs/optimizing-performance.md index e9f762aa5..b0c5fff0a 100644 --- a/content/docs/optimizing-performance.md +++ b/content/docs/optimizing-performance.md @@ -209,7 +209,7 @@ React DevTools をまだインストールしていない場合は、以下で ## リコンシリエーション(差分検出処理)を避ける {#avoid-reconciliation} -React はレンダーされた UI の内部表現を構築し、維持します。その内部表現にはコンポーネントが返した React 要素も含まれています。React はこの内部表現を使うことによって、JavaScript オブジェクトの操作よりも操作が遅くなるかもしれない DOM ノードの不要な作成やアクセスを回避します。この内部表現はしばしば「仮想 DOM」と呼ばれますが、React Native 上でも同様に動くものです。 +React はレンダーされた UI の内部表現を構築し、維持します。その内部表現にはコンポーネントが返した React 要素も含まれています。React はこの内部表現を使うことによって、JavaScript オブジェクトの操作よりも操作が遅くなるかもしれない DOM ノードの不要な作成やアクセスを回避します。この内部表現はしばしば "仮想 DOM" と呼ばれますが、React Native 上でも同様に動くものです。 コンポーネントの props や state が変更された場合、React は新しく返された要素と以前にレンダーされたものとを比較することで、実際の DOM の更新が必要かを判断します。それらが等しくない場合、React は DOM を更新します。 @@ -256,7 +256,7 @@ C1 と C3 では、`shouldComponentUpdate` が `true` を返したので、React 最後の興味深いケースが C8 です。React はこのコンポーネントをレンダーする必要がありましたが、返された React 要素は前回レンダーされたときものと同じだったので、DOM の更新は必要ありませんでした。 -React が実 DOM を更新しなければならなかったのは、C6 だけだったことに注目してください。C6 の更新は避けられないものでした。C8 では、レンダーされた React 要素の比較のおかげで実 DOM を修正せずに済みました。C2 のサブツリーと C7 のケースでは `shouldComponentUpdate` のおかげで、render メソッドの呼び出しや React 要素の比較処理すらスキップすることができました。 +React が実 DOM を更新しなければならなかったのは、C6 だけだったことに注目してください。C6 の更新は避けられないものでした。C8 では、レンダーされた React 要素の比較のおかげで実 DOM を修正せずに済みました。C2 のサブツリーと C7 のケースでは `shouldComponentUpdate` のおかげで、`render` メソッドの呼び出しや React 要素の比較処理すらスキップすることができました。 ## 例 @@ -312,7 +312,7 @@ class CounterButton extends React.PureComponent { } ``` -ほとんどの場合、自分で `shouldComponentUpdate` を記述する代わりに `React.PureComponent` を使うことができます。もっとも、浅い比較を行うだけですので、浅い比較では検出できない形で props や state が変更されている可能性がある場合には使えません。 +ほとんどの場合、自分で `shouldComponentUpdate` を記述する代わりに `React.PureComponent` を使うことができます。もっとも、浅い比較を行うだけですので、浅い比較では検出できない形で props や state が破壊的変更されている可能性がある場合には使えません。 この事はより複雑なデータ構造の場合には問題となります。例えば、カンマ区切りで単語をレンダーする `ListOfWords` コンポーネントと、ボタンをクリックしてリストに単語を追加できる親コンポーネント `WordAdder` が必要だとして、以下のコードは正しく動作しません。 From 80442d43a5836fe6848658bfb3fd679365c15bf2 Mon Sep 17 00:00:00 2001 From: Toru Kobayashi Date: Wed, 6 Mar 2019 12:50:23 +0900 Subject: [PATCH 23/31] Update content/docs/optimizing-performance.md Co-Authored-By: uehaj <59012+uehaj@users.noreply.github.com> --- content/docs/optimizing-performance.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/content/docs/optimizing-performance.md b/content/docs/optimizing-performance.md index df8eecd97..14ca34684 100644 --- a/content/docs/optimizing-performance.md +++ b/content/docs/optimizing-performance.md @@ -312,7 +312,7 @@ class CounterButton extends React.PureComponent { } ``` -ほとんどの場合、自分で `shouldComponentUpdate` を記述する代わりに `React.PureComponent` を使うことができます。もっとも、浅い比較を行うだけですので、浅い比較では検出できない形で props や state が破壊的変更されている可能性がある場合には使えません。 +ほとんどの場合、自分で `shouldComponentUpdate` を記述する代わりに `React.PureComponent` を使うことができます。もっとも、浅い比較を行うだけですので、浅い比較では検出できない形で props や state がミューテート(mutate; 書き換え)されている可能性がある場合には使えません。 この事はより複雑なデータ構造の場合には問題となります。例えば、カンマ区切りで単語をレンダーする `ListOfWords` コンポーネントと、ボタンをクリックしてリストに単語を追加できる親コンポーネント `WordAdder` が必要だとして、以下のコードは正しく動作しません。 From d0f09a81d5cb8863e6b610cc81f35892a20207a8 Mon Sep 17 00:00:00 2001 From: Toru Kobayashi Date: Wed, 6 Mar 2019 12:51:12 +0900 Subject: [PATCH 24/31] Update content/docs/optimizing-performance.md Co-Authored-By: uehaj <59012+uehaj@users.noreply.github.com> --- content/docs/optimizing-performance.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/content/docs/optimizing-performance.md b/content/docs/optimizing-performance.md index 14ca34684..a96873fb8 100644 --- a/content/docs/optimizing-performance.md +++ b/content/docs/optimizing-performance.md @@ -350,7 +350,7 @@ class WordAdder extends React.Component { } ``` -問題は `PureComponent` が `this.props.words` の古い値と新しい値を単純に比較していることにあります。上記のコードでは `WordAdder` の handleClick メソッド内で `words` 配列の内容を破壊的に変更してしまうので、`this.props.words` の新旧の値は、たとえ配列内の実際の単語が変更されていたとしても、比較の結果同じだとみなしてしまうのです。そのため `ListOfWords` はレンダーすべき新しい単語が追加されているにも関わらず、更新されません。 +問題は `PureComponent` が `this.props.words` の古い値と新しい値を単純に比較していることにあります。上記のコードでは `WordAdder` の handleClick メソッド内で `words` 配列の内容をミューテートしてしまうので、`this.props.words` の新旧の値は、たとえ配列内の実際の単語が変更されていたとしても、比較の結果同じだとみなしてしまうのです。そのため `ListOfWords` はレンダーすべき新しい単語が追加されているにも関わらず、更新されません。 ## データを変更しないことの効果 {#the-power-of-not-mutating-data} From 25030da6fe0d1468f88e76ddfaf7c7b796a18cf4 Mon Sep 17 00:00:00 2001 From: Toru Kobayashi Date: Wed, 6 Mar 2019 12:51:26 +0900 Subject: [PATCH 25/31] Update content/docs/optimizing-performance.md Co-Authored-By: uehaj <59012+uehaj@users.noreply.github.com> --- content/docs/optimizing-performance.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/content/docs/optimizing-performance.md b/content/docs/optimizing-performance.md index a96873fb8..b21126dc0 100644 --- a/content/docs/optimizing-performance.md +++ b/content/docs/optimizing-performance.md @@ -354,7 +354,7 @@ class WordAdder extends React.Component { ## データを変更しないことの効果 {#the-power-of-not-mutating-data} -この問題を避ける最も単純な方法は、props や state として使用する値の破壊的変更を避けることです。例えば、上記の `handleClick` メソッドは `concat` を使って以下のように書き換えることができます: +この問題を避ける最も単純な方法は、props や state として使用する値のミューテートを避けることです。例えば、上記の `handleClick` メソッドは `concat` を使って以下のように書き換えることができます: ```javascript handleClick() { From 169de093039da850e1eef3b2fb5830684be2695d Mon Sep 17 00:00:00 2001 From: Toru Kobayashi Date: Wed, 6 Mar 2019 12:51:35 +0900 Subject: [PATCH 26/31] Update content/docs/optimizing-performance.md Co-Authored-By: uehaj <59012+uehaj@users.noreply.github.com> --- content/docs/optimizing-performance.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/content/docs/optimizing-performance.md b/content/docs/optimizing-performance.md index b21126dc0..115f5cee7 100644 --- a/content/docs/optimizing-performance.md +++ b/content/docs/optimizing-performance.md @@ -382,7 +382,7 @@ function updateColorMap(colormap) { } ``` -この処理を、元オブジェクトを破壊的変更をせずに実装するために、[Object.assign](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/assign) を使用できます。 +この処理を、元オブジェクトをミューテートせずに実装するために、[Object.assign](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/assign) を使用できます。 ```js function updateColorMap(colormap) { From 5b208cc2623b5c7a01c21af46e41d503f2ec6f19 Mon Sep 17 00:00:00 2001 From: Toru Kobayashi Date: Wed, 6 Mar 2019 12:51:42 +0900 Subject: [PATCH 27/31] Update content/docs/optimizing-performance.md Co-Authored-By: uehaj <59012+uehaj@users.noreply.github.com> --- content/docs/optimizing-performance.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/content/docs/optimizing-performance.md b/content/docs/optimizing-performance.md index 115f5cee7..94985a3ef 100644 --- a/content/docs/optimizing-performance.md +++ b/content/docs/optimizing-performance.md @@ -392,7 +392,7 @@ function updateColorMap(colormap) { これで、`updateColorMap` は古いオブジェクトを破壊的変更するのではなく新しいオブジェクトを返すようになります。`Object.assign` は ES6 からの機能であり、ポリフィルが必要です(訳注:ブラウザや処理系が ES6 に未対応の場合)。 -同様に、オブジェクトに対しても破壊的変更をしない更新を容易に記述できるようにする[オブジェクトのスプレッドプロパティ構文](https://github.com/sebmarkbage/ecmascript-rest-spread)を JavaScript に追加することが提案されています(訳注:[ECMAScript 2018](https://developer.mozilla.org/ja/docs/Web/JavaScript/Reference/Operators/Spread_syntax) で正式採用されました): +同様に、オブジェクトに対してもミューテートをしない更新を容易に記述できるようにする[オブジェクトのスプレッドプロパティ構文](https://github.com/sebmarkbage/ecmascript-rest-spread)を JavaScript に追加することが提案されています(訳注:[ECMAScript 2018](https://developer.mozilla.org/ja/docs/Web/JavaScript/Reference/Operators/Spread_syntax) で正式採用されました): ```js function updateColorMap(colormap) { From 498d55858877e5b89be36dce8987effe8f0bca02 Mon Sep 17 00:00:00 2001 From: Toru Kobayashi Date: Wed, 6 Mar 2019 12:51:52 +0900 Subject: [PATCH 28/31] Update content/docs/optimizing-performance.md Co-Authored-By: uehaj <59012+uehaj@users.noreply.github.com> --- content/docs/optimizing-performance.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/content/docs/optimizing-performance.md b/content/docs/optimizing-performance.md index 94985a3ef..bf56bea0d 100644 --- a/content/docs/optimizing-performance.md +++ b/content/docs/optimizing-performance.md @@ -390,7 +390,7 @@ function updateColorMap(colormap) { } ``` -これで、`updateColorMap` は古いオブジェクトを破壊的変更するのではなく新しいオブジェクトを返すようになります。`Object.assign` は ES6 からの機能であり、ポリフィルが必要です(訳注:ブラウザや処理系が ES6 に未対応の場合)。 +これで、`updateColorMap` は古いオブジェクトをミューテートするのではなく新しいオブジェクトを返すようになります。`Object.assign` は ES6 からの機能であり、ポリフィルが必要です(訳注:ブラウザや処理系が ES6 に未対応の場合)。 同様に、オブジェクトに対してもミューテートをしない更新を容易に記述できるようにする[オブジェクトのスプレッドプロパティ構文](https://github.com/sebmarkbage/ecmascript-rest-spread)を JavaScript に追加することが提案されています(訳注:[ECMAScript 2018](https://developer.mozilla.org/ja/docs/Web/JavaScript/Reference/Operators/Spread_syntax) で正式採用されました): From 6e97c0207d6a7bdebdf02b6f37d1b182cee28c3d Mon Sep 17 00:00:00 2001 From: Toru Kobayashi Date: Wed, 6 Mar 2019 12:52:02 +0900 Subject: [PATCH 29/31] Update content/docs/optimizing-performance.md Co-Authored-By: uehaj <59012+uehaj@users.noreply.github.com> --- content/docs/optimizing-performance.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/content/docs/optimizing-performance.md b/content/docs/optimizing-performance.md index bf56bea0d..b3bf55167 100644 --- a/content/docs/optimizing-performance.md +++ b/content/docs/optimizing-performance.md @@ -374,7 +374,7 @@ handleClick() { }; ``` -同様に、オブジェクトについても破壊的変更をするコードをしないように書き換えることができます。例えば、`colormap` というオブジェクトがあり、`colormap.right` を `'blue'` に更新する関数が必要だとしましょう。以下のように書くことも可能ですが、 +同様に、オブジェクトについてもミューテートするコードをしないように書き換えることができます。例えば、`colormap` というオブジェクトがあり、`colormap.right` を `'blue'` に更新する関数が必要だとしましょう。以下のように書くことも可能ですが、 ```js function updateColorMap(colormap) { From a3d3ae27b65afe2721225027a65546b159fb1a74 Mon Sep 17 00:00:00 2001 From: "UEHARA, Junji" <59012+uehaj@users.noreply.github.com> Date: Wed, 6 Mar 2019 15:11:47 +0900 Subject: [PATCH 30/31] resolve commentend point at 2nd review --- content/docs/optimizing-performance.md | 3 --- 1 file changed, 3 deletions(-) diff --git a/content/docs/optimizing-performance.md b/content/docs/optimizing-performance.md index b3bf55167..c793e0339 100644 --- a/content/docs/optimizing-performance.md +++ b/content/docs/optimizing-performance.md @@ -160,7 +160,6 @@ new webpack.optimize.UglifyJsPlugin() ## Chrome のパフォーマンスタブでコンポーネントをプロファイルする {#profiling-components-with-the-chrome-performance-tab} **開発**モードでは、対応するブラウザのパフォーマンス分析ツールで、コンポーネントのマウント・更新・アンマウントの様子を以下のように視覚化することができます。 -

React components in Chrome timeline
@@ -219,7 +218,6 @@ React はレンダーされた UI の内部表現を構築し、維持します - [Firefox ブラウザ拡張](https://addons.mozilla.org/en-GB/firefox/addon/react-devtools/) - [スタンドアロン Node パッケージ](https://www.npmjs.com/package/react-devtools) - 開発者コンソールの **React** タブで **Highlight Updates** オプションを選択します:
How to enable highlight updates
@@ -421,7 +419,6 @@ x === y; // true ここで `y` は編集されたにも関わらず、`x` と同じオブジェクトを参照しているため、上記の比較は `true` を返します。これと似たコードを immutable.js で書くとこうなります: - ```javascript const SomeRecord = Immutable.Record({ foo: null }); const x = new SomeRecord({ foo: 'bar' }); From e5e854de89c58d32a1cc2b5fcc618c1028e7cb36 Mon Sep 17 00:00:00 2001 From: "UEHARA, Junji" <59012+uehaj@users.noreply.github.com> Date: Wed, 6 Mar 2019 15:51:06 +0900 Subject: [PATCH 31/31] resolve rest of commentend point at 2nd review --- content/docs/optimizing-performance.md | 1 - 1 file changed, 1 deletion(-) diff --git a/content/docs/optimizing-performance.md b/content/docs/optimizing-performance.md index c793e0339..d293b2c5f 100644 --- a/content/docs/optimizing-performance.md +++ b/content/docs/optimizing-performance.md @@ -432,5 +432,4 @@ x === z; // true 不変データの使用を助けてくる他のライブラリとして [seamless-immutable](https://github.com/rtfeldman/seamless-immutable) や [immutability-helper](https://github.com/kolodny/immutability-helper) の 2 つが挙がります。 - 不変データ構造はオブジェクトの変化の検出を容易にします。まさにそれが `shouldComponentUpdate` の実装に必要なことのすべてです。これによってパフォーマンスを大幅に向上できる場合があります。