{"componentChunkName":"component---src-templates-docs-js","path":"/docs/optimizing-performance.html","result":{"data":{"markdownRemark":{"html":"<p>React использует несколько умных подходов для минимизации количества дорогостоящих DOM-операций, необходимых для обновления пользовательского интерфейса. Для многих приложений, использование React приведёт к быстрому пользовательскому интерфейсу без особых усилий по оптимизации производительности. Тем не менее, существует несколько способов ускорить React-приложение.</p>\n<h2 id=\"use-the-production-build\"><a href=\"#use-the-production-build\" aria-hidden class=\"anchor\"><svg aria-hidden=\"true\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>Использование продакшен-сборки </h2>\n<p>Если вы испытываете проблемы с производительностью в React-приложении, убедитесь в том, что вы проводите тесты с настройками минифицированной продакшен-сборки.</p>\n<p>По умолчанию в React есть много вспомогательных предупреждений, очень полезных при разработке. Тем не менее, они делают React больше и медленнее, поэтому вам обязательно следует использовать продакшен-версию при деплое приложения.</p>\n<p>Если вы не уверены в том, что процесс сборки настроен правильно, вы можете проверить это, установив <a href=\"https://chrome.google.com/webstore/detail/react-developer-tools/fmkadmapgofadopljbjfkapdkoienihi\" target=\"_blank\" rel=\"nofollow noopener noreferrer\">React Developer Tools for Chrome</a>. Если вы посетите сайт, работающий на React в продакшен-режиме, иконка будет с чёрным фоном:</p>\n\n  <a class=\"gatsby-resp-image-link\" href=\"/static/d0f767f80866431ccdec18f200ca58f1/0a47e/devtools-prod.png\" style=\"display: block\" target=\"_blank\" rel=\"noopener\">\n  \n  <span class=\"gatsby-resp-image-wrapper\" style=\"position: relative; display: block;  max-width: 600px; margin-left: auto; margin-right: auto;\">\n    <span class=\"gatsby-resp-image-background-image\" style=\"padding-bottom: 20.952380952380953%; position: relative; bottom: 0; left: 0; background-image: url(&apos;data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAAECAIAAAABPYjBAAAACXBIWXMAABYlAAAWJQFJUiTwAAAAtElEQVQI142ISwqDMABEvf+Fumyh4C5p1ChtoUZj/EUEG/MxUbHppus+GObNBPu+O+fWP9jc5qzTxkghTpcriJOg73uttZJSKy2l7x/zN/OslBTvt/dpmayzq1utXVo+vHIShGGYJBhC+Lg/bxAlcYxxmqYYAID9D2CWZRFCKEJnehFGWLMopY7joJQGpCCM1U3TMMZITmqvrafzs++6qmL+4cNQVbTICee8bdqyLLU24zh+AGg72y61QftkAAAAAElFTkSuQmCC&apos;); background-size: cover; display: block;\">\n      <img class=\"gatsby-resp-image-image\" style=\"width: 100%; height: 100%; margin: 0; vertical-align: middle; position: absolute; top: 0; left: 0; box-shadow: inset 0px 0px 0px 400px white;\" alt=\"React DevTools on a website with production version of React\" title src=\"/static/d0f767f80866431ccdec18f200ca58f1/0a47e/devtools-prod.png\" srcset=\"/static/d0f767f80866431ccdec18f200ca58f1/65ed1/devtools-prod.png 210w,\n/static/d0f767f80866431ccdec18f200ca58f1/d10fb/devtools-prod.png 420w,\n/static/d0f767f80866431ccdec18f200ca58f1/0a47e/devtools-prod.png 600w\" sizes=\"(max-width: 600px) 100vw, 600px\">\n    </span>\n  </span>\n  \n  </a>\n    \n<p>Если вы посетите сайт с React в режиме разработки, у иконки будет красный фон:</p>\n\n  <a class=\"gatsby-resp-image-link\" href=\"/static/e434ce2f7e64f63e597edf03f4465694/0a47e/devtools-dev.png\" style=\"display: block\" target=\"_blank\" rel=\"noopener\">\n  \n  <span class=\"gatsby-resp-image-wrapper\" style=\"position: relative; display: block;  max-width: 600px; margin-left: auto; margin-right: auto;\">\n    <span class=\"gatsby-resp-image-background-image\" style=\"padding-bottom: 33.33333333333333%; position: relative; bottom: 0; left: 0; background-image: url(&apos;data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAAHCAIAAACHqfpvAAAACXBIWXMAABYlAAAWJQFJUiTwAAABI0lEQVQY04WQ3XKCMBCFef+X6k2tkAIGRa1Ox5kOGiCAkt81gtINM73uudicTTaz324w/qfnn9Bi6u739nr9eX8rDvvAzLLWAlitNXqttFJq9to/WOsLAB7OPMfHNE3DOJqm7rsuSJKURITSLM/zMAw3m3WWZXEcRxFZpWmSovxJSPx9WHXNBcBJIWeQMbgwxmteMnY+nxl63vCm5byu8bKsGCs5523TFkXBWFVzXlXV6XQCgGEYAqSaCT2b0lIpibTaeGYAP5EUAiP4RAsh0HjyYXDOBYvFB11RhM2zr3BB42hN413yucvpcUOPOFG4XOJoOAAhZLfdK6mmWb7zvBvci9ES5A1kb2+duXVa9La/GiwFa6XE9gIB8cPr9cLo1+7cL+jygk7PcoV8AAAAAElFTkSuQmCC&apos;); background-size: cover; display: block;\">\n      <img class=\"gatsby-resp-image-image\" style=\"width: 100%; height: 100%; margin: 0; vertical-align: middle; position: absolute; top: 0; left: 0; box-shadow: inset 0px 0px 0px 400px white;\" alt=\"React DevTools on a website with development version of React\" title src=\"/static/e434ce2f7e64f63e597edf03f4465694/0a47e/devtools-dev.png\" srcset=\"/static/e434ce2f7e64f63e597edf03f4465694/65ed1/devtools-dev.png 210w,\n/static/e434ce2f7e64f63e597edf03f4465694/d10fb/devtools-dev.png 420w,\n/static/e434ce2f7e64f63e597edf03f4465694/0a47e/devtools-dev.png 600w\" sizes=\"(max-width: 600px) 100vw, 600px\">\n    </span>\n  </span>\n  \n  </a>\n    \n<p>Как правило, режим разработки используется во время работы над приложением, а продакшен-режим при деплое приложения для пользователей.</p>\n<p>Ниже вы можете найти инструкцию по сборке своего приложения для продакшена.</p>\n<h3 id=\"create-react-app\"><a href=\"#create-react-app\" aria-hidden class=\"anchor\"><svg aria-hidden=\"true\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>Create React App </h3>\n<p>Если ваш проект сделан с помощью <a href=\"https://github.com/facebookincubator/create-react-app\" target=\"_blank\" rel=\"nofollow noopener noreferrer\">Create React App</a>, выполните:</p>\n<div class=\"gatsby-highlight\" data-language=\"text\"><pre class=\"gatsby-code-text\"><code class=\"gatsby-code-text\">npm run build</code></pre></div>\n<p>Эта команда создаст продакшен-сборку вашего приложения в папке <code class=\"gatsby-code-text\">build/</code> вашего проекта.</p>\n<p>Помните, что это необходимо только перед деплоем на продакшен. Для обычной разработки используйте <code class=\"gatsby-code-text\">npm start</code>.</p>\n<h3 id=\"single-file-builds\"><a href=\"#single-file-builds\" aria-hidden class=\"anchor\"><svg aria-hidden=\"true\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>Однофайловые сборки </h3>\n<p>Мы предлагаем готовые для продакшена версии React и React DOM в виде отдельных файлов:</p>\n<div class=\"gatsby-highlight\" data-language=\"html\"><pre class=\"gatsby-code-html\"><code class=\"gatsby-code-html\"><span class=\"token tag\"><span class=\"token tag\"><span class=\"token punctuation\">&lt;</span>script</span> <span class=\"token attr-name\">src</span><span class=\"token attr-value\"><span class=\"token punctuation attr-equals\">=</span><span class=\"token punctuation\">\"</span>https://unpkg.com/react@16/umd/react.production.min.js<span class=\"token punctuation\">\"</span></span><span class=\"token punctuation\">></span></span><span class=\"token script\"></span><span class=\"token tag\"><span class=\"token tag\"><span class=\"token punctuation\">&lt;/</span>script</span><span class=\"token punctuation\">></span></span>\n<span class=\"token tag\"><span class=\"token tag\"><span class=\"token punctuation\">&lt;</span>script</span> <span class=\"token attr-name\">src</span><span class=\"token attr-value\"><span class=\"token punctuation attr-equals\">=</span><span class=\"token punctuation\">\"</span>https://unpkg.com/react-dom@16/umd/react-dom.production.min.js<span class=\"token punctuation\">\"</span></span><span class=\"token punctuation\">></span></span><span class=\"token script\"></span><span class=\"token tag\"><span class=\"token tag\"><span class=\"token punctuation\">&lt;/</span>script</span><span class=\"token punctuation\">></span></span></code></pre></div>\n<p>Помните, что для продакшена подходят только те файлы, которые заканчиваются на <code class=\"gatsby-code-text\">.production.min.js</code>.</p>\n<h3 id=\"brunch\"><a href=\"#brunch\" aria-hidden class=\"anchor\"><svg aria-hidden=\"true\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>Brunch </h3>\n<p>Для наиболее эффективной продакшен-сборки с Brunch, установите плагин <a href=\"https://github.com/brunch/terser-brunch\" target=\"_blank\" rel=\"nofollow noopener noreferrer\"><code class=\"gatsby-code-text\">terser-brunch</code></a>.</p>\n<div class=\"gatsby-highlight\" data-language=\"text\"><pre class=\"gatsby-code-text\"><code class=\"gatsby-code-text\"># В случае использования npm\nnpm install --save-dev terser-brunch\n\n# В случае использования Yarn\nyarn add --dev terser-brunch</code></pre></div>\n<p>Затем, для создания продакшен сборки, добавьте флаг <code class=\"gatsby-code-text\">-p</code> к команде <code class=\"gatsby-code-text\">build</code>:</p>\n<div class=\"gatsby-highlight\" data-language=\"text\"><pre class=\"gatsby-code-text\"><code class=\"gatsby-code-text\">brunch build -p</code></pre></div>\n<p>Помните, что это нужно делать только для продакшен-сборки. Вам не нужно использовать флаг <code class=\"gatsby-code-text\">-p</code> или применять этот плагин во время разработки, потому что это скроет вспомогательные предупреждения React и замедлит процесс сборки.</p>\n<h3 id=\"browserify\"><a href=\"#browserify\" aria-hidden class=\"anchor\"><svg aria-hidden=\"true\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>Browserify </h3>\n<p>Для наиболее эффективной продакшен-сборки с Browserify, установите несколько плагинов:</p>\n<div class=\"gatsby-highlight\" data-language=\"text\"><pre class=\"gatsby-code-text\"><code class=\"gatsby-code-text\"># В случае использования npm\nnpm install --save-dev envify terser uglifyify \n\n# В случае использования Yarn\nyarn add --dev envify terser uglifyify</code></pre></div>\n<p>При создании продакшен-сборки, убедитесь, что вы добавили эти пакеты для преобразования <strong>(порядок имеет значение)</strong>:</p>\n<ul>\n<li>Плагин <a href=\"https://github.com/hughsk/envify\" target=\"_blank\" rel=\"nofollow noopener noreferrer\"><code class=\"gatsby-code-text\">envify</code></a> обеспечивает правильную среду для сборки. Сделайте его глобальным (<code class=\"gatsby-code-text\">-g</code>).</li>\n<li>Плагин <a href=\"https://github.com/hughsk/uglifyify\" target=\"_blank\" rel=\"nofollow noopener noreferrer\"><code class=\"gatsby-code-text\">uglifyify</code></a> удаляет импорты, добавленные при разработке. Сделайте его глобальным (<code class=\"gatsby-code-text\">-g</code>).</li>\n<li>Наконец, полученная сборка отправляется к <a href=\"https://github.com/terser-js/terser\" target=\"_blank\" rel=\"nofollow noopener noreferrer\"><code class=\"gatsby-code-text\">terser</code></a> для минификации (<a href=\"https://github.com/hughsk/uglifyify#motivationusage\" target=\"_blank\" rel=\"nofollow noopener noreferrer\">прочитайте, зачем это нужно</a>).</li>\n</ul>\n<p>К примеру:</p>\n<div class=\"gatsby-highlight\" data-language=\"text\"><pre class=\"gatsby-code-text\"><code class=\"gatsby-code-text\">browserify ./index.js \\\n  -g [ envify --NODE_ENV production ] \\\n  -g uglifyify \\\n  | terser --compress --mangle &gt; ./bundle.js</code></pre></div>\n<p>Помните, что это нужно делать только для продакшен-сборки. Вам не следует использовать эти плагины в процессе разработки, потому что это скроет вспомогательные предупреждения React и замедлит процесс сборки.</p>\n<h3 id=\"rollup\"><a href=\"#rollup\" aria-hidden class=\"anchor\"><svg aria-hidden=\"true\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>Rollup </h3>\n<p>Для наиболее эффективной продакшен-сборки с Rollup, установите несколько плагинов:</p>\n<div class=\"gatsby-highlight\" data-language=\"bash\"><pre class=\"gatsby-code-bash\"><code class=\"gatsby-code-bash\"><span class=\"token comment\"># В случае использования npm</span>\n<span class=\"token function\">npm</span> <span class=\"token function\">install</span> --save-dev rollup-plugin-commonjs rollup-plugin-replace rollup-plugin-terser\n\n<span class=\"token comment\"># В случае использования Yarn</span>\n<span class=\"token function\">yarn</span> <span class=\"token function\">add</span> --dev rollup-plugin-commonjs rollup-plugin-replace rollup-plugin-terser</code></pre></div>\n<p>При создании продакшен-сборки, убедитесь, что вы добавили эти плагины <strong>(порядок имеет значение)</strong>:</p>\n<ul>\n<li>Плагин <a href=\"https://github.com/rollup/rollup-plugin-replace\" target=\"_blank\" rel=\"nofollow noopener noreferrer\"><code class=\"gatsby-code-text\">replace</code></a> обеспечивает правильную среду для сборки.</li>\n<li>Плагин <a href=\"https://github.com/rollup/rollup-plugin-commonjs\" target=\"_blank\" rel=\"nofollow noopener noreferrer\"><code class=\"gatsby-code-text\">commonjs</code></a> обеспечивает поддержку CommonJS в Rollup.</li>\n<li>Плагин <a href=\"https://github.com/TrySound/rollup-plugin-terser\" target=\"_blank\" rel=\"nofollow noopener noreferrer\"><code class=\"gatsby-code-text\">terser</code></a> сжимает и оптимизирует финальную сборку.</li>\n</ul>\n<div class=\"gatsby-highlight\" data-language=\"jsx\"><pre class=\"gatsby-code-jsx\"><code class=\"gatsby-code-jsx\">plugins<span class=\"token operator\">:</span> <span class=\"token punctuation\">[</span>\n  <span class=\"token comment\">// ...</span>\n  <span class=\"token function\">require</span><span class=\"token punctuation\">(</span><span class=\"token string\">'rollup-plugin-replace'</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">{</span>\n    <span class=\"token string\">'process.env.NODE_ENV'</span><span class=\"token operator\">:</span> <span class=\"token constant\">JSON</span><span class=\"token punctuation\">.</span><span class=\"token function\">stringify</span><span class=\"token punctuation\">(</span><span class=\"token string\">'production'</span><span class=\"token punctuation\">)</span>\n  <span class=\"token punctuation\">}</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">,</span>\n  <span class=\"token function\">require</span><span class=\"token punctuation\">(</span><span class=\"token string\">'rollup-plugin-commonjs'</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">,</span>\n  <span class=\"token function\">require</span><span class=\"token punctuation\">(</span><span class=\"token string\">'rollup-plugin-terser'</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">,</span>\n  <span class=\"token comment\">// ...</span>\n<span class=\"token punctuation\">]</span></code></pre></div>\n<p>Полный пример настройки можно <a href=\"https://gist.github.com/Rich-Harris/cb14f4bc0670c47d00d191565be36bf0\" target=\"_blank\" rel=\"nofollow noopener noreferrer\">посмотреть здесь</a>.</p>\n<p>Помните, что это нужно делать только для продакшен-сборки. Вам не следует использовать плагин <code class=\"gatsby-code-text\">terser</code> или плагин <code class=\"gatsby-code-text\">replace</code> со значением <code class=\"gatsby-code-text\">&#39;production&#39;</code> в процессе разработки, потому что это скроет вспомогательные предупреждения React и замедлит процесс сборки.</p>\n<h3 id=\"webpack\"><a href=\"#webpack\" aria-hidden class=\"anchor\"><svg aria-hidden=\"true\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>webpack </h3>\n<blockquote>\n<p><strong>Примечание:</strong></p>\n<p>Если вы используете Create React App, пожалуйста, следуйте <a href=\"#create-react-app\">инструкциям выше</a>.<br>\nЭтот раздел подойдёт для тех, кто самостоятельно настраивает webpack.</p>\n</blockquote>\n<p>Webpack 4.0 и выше по умолчанию минифицирует код в продакшен-режиме.</p>\n<div class=\"gatsby-highlight\" data-language=\"jsx\"><pre class=\"gatsby-code-jsx\"><code class=\"gatsby-code-jsx\"><span class=\"token keyword\">const</span> TerserPlugin <span class=\"token operator\">=</span> <span class=\"token function\">require</span><span class=\"token punctuation\">(</span><span class=\"token string\">'terser-webpack-plugin'</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span>\n\nmodule<span class=\"token punctuation\">.</span>exports <span class=\"token operator\">=</span> <span class=\"token punctuation\">{</span>\n  mode<span class=\"token operator\">:</span> <span class=\"token string\">'production'</span><span class=\"token punctuation\">,</span>\n  optimization<span class=\"token operator\">:</span> <span class=\"token punctuation\">{</span>\n    minimizer<span class=\"token operator\">:</span> <span class=\"token punctuation\">[</span><span class=\"token keyword\">new</span> <span class=\"token class-name\">TerserPlugin</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">{</span> <span class=\"token comment\">/* additional options here */</span> <span class=\"token punctuation\">}</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">]</span><span class=\"token punctuation\">,</span>\n  <span class=\"token punctuation\">}</span><span class=\"token punctuation\">,</span>\n<span class=\"token punctuation\">}</span><span class=\"token punctuation\">;</span></code></pre></div>\n<p>Вы можете узнать об этом больше в <a href=\"https://webpack.js.org/guides/production/\" target=\"_blank\" rel=\"nofollow noopener noreferrer\">документации webpack</a>.</p>\n<p>Помните, что это нужно делать только для продакшен-сборки. Вам не стоит использовать <code class=\"gatsby-code-text\">TerserPlugin</code> в процессе разработки, потому что тогда скроются вспомогательные предупреждения React и замедлится процесс сборки.</p>\n<h2 id=\"profiling-components-with-the-chrome-performance-tab\"><a href=\"#profiling-components-with-the-chrome-performance-tab\" aria-hidden class=\"anchor\"><svg aria-hidden=\"true\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>Анализ производительности компонентов с помощью вкладки Chrome «Performance» </h2>\n<p>В режиме <strong>разработки</strong> вы можете видеть как компоненты монтируются, обновляются и размонтируются с помощью инструментов производительности в браузерах, которые их поддерживают. Например:</p>\n<center>\n  <a class=\"gatsby-resp-image-link\" href=\"/static/64d522b74fb585f1abada9801f85fa9d/1ac66/react-perf-chrome-timeline.png\" style=\"display: block\" target=\"_blank\" rel=\"noopener\">\n  \n  <span class=\"gatsby-resp-image-wrapper\" style=\"position: relative; display: block;  max-width: 651px; margin-left: auto; margin-right: auto;\">\n    <span class=\"gatsby-resp-image-background-image\" style=\"padding-bottom: 35.23809523809524%; position: relative; bottom: 0; left: 0; background-image: url(&apos;data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAAHCAIAAACHqfpvAAAACXBIWXMAAAsSAAALEgHS3X78AAABYUlEQVQY022NeUsCURTF5yMG0aaZSgniMtqCEfQlgoowqCCoRDNIs+gfdVTMJa3JbdRyaROHyXJ0xuc47zVqC0Rw7uHec/lxsPeqmyJ0WT+e8xspwli+wp9ipnZ+QRJHzfP3y3RyPeXAMycm0oEXXeayx/zmXWIDliZhwXgmHzuQxQ+VKefcg0db9+kaQT1D6Gm/vu7V0gEzW7JVLxTF45Gya4wLyoSwvBOaAqFJEBrHel2+Gt1PnGqj9onIkTx3pqLcyrxbVfdrGsFZJowLbKlbcHK32+BmAyTXAGntkFZAboH0LgYhRBCKIAUYX9JmiO0pSLsm7pzJeNSVy2k6toKgAIcSOVFgYY+DQguKvJT34T4tGULP6R3KO0pTm48Rw8v1In23ytWcUg6//mhg6OtACBtuUrfkzdd44VzdqkXZSuijTIB6QuSYbxj+YH/hfiKNwPN0Vuy2ByUQoV/mX/gTU11epAmedTIAAAAASUVORK5CYII=&apos;); background-size: cover; display: block;\">\n      <img class=\"gatsby-resp-image-image\" style=\"width: 100%; height: 100%; margin: 0; vertical-align: middle; position: absolute; top: 0; left: 0; box-shadow: inset 0px 0px 0px 400px white;\" alt=\"&#x41A;&#x43E;&#x43C;&#x43F;&#x43E;&#x43D;&#x435;&#x43D;&#x442;&#x44B; React &#x432; &#x433;&#x440;&#x430;&#x444;&#x438;&#x43A;&#x435; &#x432;&#x440;&#x435;&#x43C;&#x435;&#x43D;&#x438; Chrome\" title src=\"/static/64d522b74fb585f1abada9801f85fa9d/1ac66/react-perf-chrome-timeline.png\" srcset=\"/static/64d522b74fb585f1abada9801f85fa9d/65ed1/react-perf-chrome-timeline.png 210w,\n/static/64d522b74fb585f1abada9801f85fa9d/d10fb/react-perf-chrome-timeline.png 420w,\n/static/64d522b74fb585f1abada9801f85fa9d/1ac66/react-perf-chrome-timeline.png 651w\" sizes=\"(max-width: 651px) 100vw, 651px\">\n    </span>\n  </span>\n  \n  </a>\n    </center>\n<p>Для того, чтобы сделать это в Chrome:</p>\n<ol>\n<li>Временно <strong>отключите все расширения Chrome, особенно React DevTools</strong>. Они могут существенно исказить результаты!</li>\n<li>Убедитесь, что вы запускаете приложение в режиме разработки.</li>\n<li>Откройте в инструментах разработчика Chrome вкладку <strong><a href=\"https://developers.google.com/web/tools/chrome-devtools/evaluate-performance/timeline-tool\" target=\"_blank\" rel=\"nofollow noopener noreferrer\">Performance</a></strong> и нажмите <strong>Record</strong>.</li>\n<li>Выполните действия, которые вы хотите проанализировать на производительность. Не записывайте более 20 секунд, иначе Chrome может зависнуть.</li>\n<li>Остановите запись.</li>\n<li>События React будут сгруппированы под меткой <strong>User Timing</strong>.</li>\n</ol>\n<p>Для более детального ознакомления, посмотрите <a href=\"https://calibreapp.com/blog/react-performance-profiling-optimization\" target=\"_blank\" rel=\"nofollow noopener noreferrer\">эту статью от Бена Шварца (Ben Schwarz)</a>.</p>\n<p>Обратите внимание, что <strong>результаты являются относительными и в продакшене рендеринг компонентов будет быстрее</strong>. Всё же это должно помочь вам понять, когда не имеющий отношения пользовательский компонент обновляется по ошибке, а также как глубоко и часто обновляется пользовательский интерфейс.</p>\n<p>В настоящее время Chrome, Edge и IE единственные браузеры, которые поддерживают данную возможность, но мы используем стандарт <a href=\"https://developer.mozilla.org/en-US/docs/Web/API/User_Timing_API\" target=\"_blank\" rel=\"nofollow noopener noreferrer\">User Timing API</a> поэтому ожидайте, что больше браузеров добавят его поддержку.</p>\n<h2 id=\"profiling-components-with-the-devtools-profiler\"><a href=\"#profiling-components-with-the-devtools-profiler\" aria-hidden class=\"anchor\"><svg aria-hidden=\"true\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>Анализ производительности компонентов с помощью инструмента разработки «Profiler» </h2>\n<p>Пакеты <code class=\"gatsby-code-text\">react-dom</code> версии 16.5+ и <code class=\"gatsby-code-text\">react-native</code> версии 0.57+ предоставляют расширенные возможности анализа производительности в режиме разработки с помощью инструментов разработчика React Profiler.\nОбзор профайлера можно найти в посте блога <a href=\"/blog/2018/09/10/introducing-the-react-profiler.html\">«Введение в React Profiler»</a>.\nПошаговое видео-руководство также <a href=\"https://www.youtube.com/watch?v=nySib7ipZdk\" target=\"_blank\" rel=\"nofollow noopener noreferrer\">доступно на YouTube</a>.</p>\n<p>Если вы ещё не установили инструменты разработчика React, вы можете найти их здесь:</p>\n<ul>\n<li><a href=\"https://chrome.google.com/webstore/detail/react-developer-tools/fmkadmapgofadopljbjfkapdkoienihi?hl=en\" target=\"_blank\" rel=\"nofollow noopener noreferrer\">Chrome Browser Extension</a></li>\n<li><a href=\"https://addons.mozilla.org/en-GB/firefox/addon/react-devtools/\" target=\"_blank\" rel=\"nofollow noopener noreferrer\">Firefox Browser Extension</a></li>\n<li><a href=\"https://www.npmjs.com/package/react-devtools\" target=\"_blank\" rel=\"nofollow noopener noreferrer\">Standalone Node Package</a></li>\n</ul>\n<blockquote>\n<p>Примечание</p>\n<p>Профилирование продакшен-пакета для <code class=\"gatsby-code-text\">react-dom</code> также доступно как <code class=\"gatsby-code-text\">react-dom/profiling</code>.\nПодробнее о том, как использовать этот пакет, читайте на <a href=\"https://fb.me/react-profiling\" target=\"_blank\" rel=\"nofollow noopener noreferrer\">fb.me/react-profiling</a></p>\n</blockquote>\n<h2 id=\"virtualize-long-lists\"><a href=\"#virtualize-long-lists\" aria-hidden class=\"anchor\"><svg aria-hidden=\"true\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>Виртуализация длинных списков </h2>\n<p>Если ваше приложение рендерит длинные списки данных (сотни или тысячи строк), мы рекомендуем использовать метод известный как «оконный доступ». Этот метод рендерит только небольшое подмножество строк в данный момент времени и может значительно сократить время, необходимое для повторного рендера компонентов, а также количество создаваемых DOM-узлов.</p>\n<p><a href=\"https://react-window.now.sh/\" target=\"_blank\" rel=\"nofollow noopener noreferrer\">react-window</a> и <a href=\"https://bvaughn.github.io/react-virtualized/\" target=\"_blank\" rel=\"nofollow noopener noreferrer\">react-virtualized</a> — это популярные библиотеки для оконного доступа. Они предоставляют несколько повторно используемых компонентов для отображения списков, сеток и табличных данных. Если вы хотите использовать что-то более специфическое для вашего конкретного случая, то вы можете создать собственный компонент с оконным доступом, как это сделано в <a href=\"https://medium.com/@paularmstrong/twitter-lite-and-high-performance-react-progressive-web-apps-at-scale-d28a00e780a3\" target=\"_blank\" rel=\"nofollow noopener noreferrer\">Twitter</a>.</p>\n<h2 id=\"avoid-reconciliation\"><a href=\"#avoid-reconciliation\" aria-hidden class=\"anchor\"><svg aria-hidden=\"true\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>Избежание согласования </h2>\n<p>React создаёт и поддерживает внутреннее представление отображаемого пользовательского интерфейса. Оно также включает React-элементы возвращаемые из ваших компонентов. Это представление позволяет React избегать создания DOM-узлов и не обращаться к текущим без необходимости, поскольку эти операции могут быть медленнее, чем операции с JavaScript-объектами. Иногда его называют «виртуальный DOM», но в React Native это работает точно так же.</p>\n<p>Когда изменяются пропсы или состояние компонента, React решает нужно ли обновление DOM, сравнивая возвращённый элемент с ранее отрендеренным. Если они не равны, React обновит DOM.</p>\n<p>Несмотря на то, что React обновляет только изменённые DOM-узлы, повторный рендеринг всё же занимает некоторое время. В большинстве случаев это не проблема, но если замедление заметно, то вы можете всё ускорить, переопределив метод жизненного цикла <code class=\"gatsby-code-text\">shouldComponentUpdate</code>, который вызывается перед началом процесса ререндеринга. Реализация этой функции по умолчанию возвращает <code class=\"gatsby-code-text\">true</code>, указывая React выполнить обновление:</p>\n<div class=\"gatsby-highlight\" data-language=\"jsx\"><pre class=\"gatsby-code-jsx\"><code class=\"gatsby-code-jsx\"><span class=\"token function\">shouldComponentUpdate</span><span class=\"token punctuation\">(</span><span class=\"token parameter\">nextProps<span class=\"token punctuation\">,</span> nextState</span><span class=\"token punctuation\">)</span> <span class=\"token punctuation\">{</span>\n  <span class=\"token keyword\">return</span> <span class=\"token boolean\">true</span><span class=\"token punctuation\">;</span>\n<span class=\"token punctuation\">}</span></code></pre></div>\n<p>Если вы знаете ситуации, в которых ваш компонент не нуждается в обновлении, вы можете вернуть <code class=\"gatsby-code-text\">false</code> из <code class=\"gatsby-code-text\">shouldComponentUpdate</code>, чтобы пропустить весь процесс рендеринга, включая вызов <code class=\"gatsby-code-text\">render()</code> и так далее ниже по иерархии.</p>\n<p>В большинстве случаев вместо того, чтобы писать <code class=\"gatsby-code-text\">shouldComponentUpdate()</code> вручную, вы можете наследоваться от <a href=\"/docs/react-api.html#reactpurecomponent\"><code class=\"gatsby-code-text\">React.PureComponent</code></a>. Это эквивалентно реализации <code class=\"gatsby-code-text\">shouldComponentUpdate()</code> с поверхностным сравнением текущих и предыдущих пропсов и состояния.</p>\n<h2 id=\"shouldcomponentupdate-in-action\"><a href=\"#shouldcomponentupdate-in-action\" aria-hidden class=\"anchor\"><svg aria-hidden=\"true\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>shouldComponentUpdate в действии </h2>\n<p>Вот поддерево компонентов. Для каждого из них <code class=\"gatsby-code-text\">SCU</code> указывает что возвратил <code class=\"gatsby-code-text\">shouldComponentUpdate</code>, а <code class=\"gatsby-code-text\">vDOMEq</code> указывает эквивалентны ли отрендеренные React элементы. Наконец, цвет круга указывает требуется ли согласовать компонент или нет.</p>\n<figure>\n  <a class=\"gatsby-resp-image-link\" href=\"/static/5ee1bdf4779af06072a17b7a0654f6db/cd039/should-component-update.png\" style=\"display: block\" target=\"_blank\" rel=\"noopener\">\n  \n  <span class=\"gatsby-resp-image-wrapper\" style=\"position: relative; display: block;  max-width: 555px; margin-left: auto; margin-right: auto;\">\n    <span class=\"gatsby-resp-image-background-image\" style=\"padding-bottom: 66.66666666666666%; position: relative; bottom: 0; left: 0; background-image: url(&apos;data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAANCAYAAACpUE5eAAAACXBIWXMAAAsTAAALEwEAmpwYAAACcklEQVQ4y2Ow8jZgAIHgXDcGHn5OMPv///9g+lhdTerB9CTv3QwMsu+U1dhAYqUMTAzpToYM9j0MDF5JAmB1Ti0MmODU/y2MUIOYgZhDgIuLDS5pbA0SYwNaxwS2cPNOxv8MnQw3oNIgXYeRDYO5CATYZUTZgRQjiP1tQi/T/yWzGEGyQEFmPk4ODiCTBUUvussmzO0Fa55/eMrMtRMKY6A2MNQAqZmT+sHcipBwhv97N4DVHaqq1Dzb3bZ6drCUzREGBlGQ2JQ6X4akeAaGbo/HDAwTj+aCFS44PCFg+7ZJWiB29/8rjDCbJ1TOQnHF5NBAiR2VZcnr5VUUdzAwCKO4rpIBN+jf1YYuxMoQzseOIqIixQIWB4L1uZBgYlhwYNLyVcfnOoJds7mCc+GByavXnV6kDeIfXj4FHF5Xurvbt9dktPcyMEisXdqgv/TAlI3XncxUQHIzdvWazd3bu1G1gUkXGE6CDEtPTvLacn65AkiS9xwDw/KTU33Wn1gkBuKfXTENHKs3u9ut7ze1mPwGxv7y7jix1Wdn+h6LCeMFyS07P0F4xanpfgzVHMJAA0WxxjQyuNbewMhACth4f/nClnm1xkAmPw8ft5iwuKA4KxurBJDPB1NTFyXH2RzJriTHwCDIyMwkJSIuKMHMyCgOlJLi5ObgATsmmIkRnDROHpi/cNOqKeDYlZWR4AIlYFDChiZwiIHaDKxRngz6zMUMIENYmFjB8pxQdWywiAGDD5Onrt1aV28CcpEANzdIgwgQiyH7IseKgbnalMGs3IDBEBTULEzg5CIKxeLIvmFgeN7IiCv8/iPRQMz8H5r18AEAM723cnu0lYoAAAAASUVORK5CYII=&apos;); background-size: cover; display: block;\">\n      <img class=\"gatsby-resp-image-image\" style=\"width: 100%; height: 100%; margin: 0; vertical-align: middle; position: absolute; top: 0; left: 0; box-shadow: inset 0px 0px 0px 400px white;\" alt=\"&#x414;&#x435;&#x440;&#x435;&#x432;&#x43E; &#x43A;&#x43E;&#x43C;&#x43F;&#x43E;&#x43D;&#x435;&#x43D;&#x442;&#x43E;&#x432;\" title src=\"/static/5ee1bdf4779af06072a17b7a0654f6db/cd039/should-component-update.png\" srcset=\"/static/5ee1bdf4779af06072a17b7a0654f6db/65ed1/should-component-update.png 210w,\n/static/5ee1bdf4779af06072a17b7a0654f6db/d10fb/should-component-update.png 420w,\n/static/5ee1bdf4779af06072a17b7a0654f6db/cd039/should-component-update.png 555w\" sizes=\"(max-width: 555px) 100vw, 555px\">\n    </span>\n  </span>\n  \n  </a>\n    </figure>\n<p>Поскольку <code class=\"gatsby-code-text\">shouldComponentUpdate</code> возвратил <code class=\"gatsby-code-text\">false</code> для поддерева с корнем C2, React не пытался отрендерить C2, следовательно не нужно вызывать <code class=\"gatsby-code-text\">shouldComponentUpdate</code> на C4 и C5.</p>\n<p>Для C1 и C3 <code class=\"gatsby-code-text\">shouldComponentUpdate</code> возвратил <code class=\"gatsby-code-text\">true</code>, поэтому React пришлось спуститься к листьям и проверить их. Для C6 <code class=\"gatsby-code-text\">shouldComponentUpdate</code> вернул <code class=\"gatsby-code-text\">true</code>, и поскольку отображаемые элементы не были эквивалентны, React должен был обновить DOM.</p>\n<p>Последний интересный случай — C8. React должен был отрисовать этот компонент, но поскольку возвращаемые им React-элементы были равны ранее предоставленным, ему не нужно обновлять DOM.</p>\n<p>Обратите внимание, что React должен был делать изменения только для C6. Для C8 этого удалось избежать сравнением отрендеренных React-элементов, а для поддеревьев C2 и C7 даже не пришлось сравнивать элементы, так как нас выручил <code class=\"gatsby-code-text\">shouldComponentUpdate</code> и <code class=\"gatsby-code-text\">render</code> не был вызван.</p>\n<h2 id=\"examples\"><a href=\"#examples\" aria-hidden class=\"anchor\"><svg aria-hidden=\"true\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>Примеры </h2>\n<p>Если единственный случай изменения вашего компонента это когда переменная <code class=\"gatsby-code-text\">props.color</code> или <code class=\"gatsby-code-text\">state.count</code> изменяются, вы могли бы выполнить проверку в <code class=\"gatsby-code-text\">shouldComponentUpdate</code> следующим образом:</p>\n<div class=\"gatsby-highlight\" data-language=\"jsx\"><pre class=\"gatsby-code-jsx\"><code class=\"gatsby-code-jsx\"><span class=\"token keyword\">class</span> <span class=\"token class-name\">CounterButton</span> <span class=\"token keyword\">extends</span> <span class=\"token class-name\">React<span class=\"token punctuation\">.</span>Component</span> <span class=\"token punctuation\">{</span>\n  <span class=\"token function\">constructor</span><span class=\"token punctuation\">(</span><span class=\"token parameter\">props</span><span class=\"token punctuation\">)</span> <span class=\"token punctuation\">{</span>\n    <span class=\"token keyword\">super</span><span class=\"token punctuation\">(</span>props<span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span>\n    <span class=\"token keyword\">this</span><span class=\"token punctuation\">.</span>state <span class=\"token operator\">=</span> <span class=\"token punctuation\">{</span>count<span class=\"token operator\">:</span> <span class=\"token number\">1</span><span class=\"token punctuation\">}</span><span class=\"token punctuation\">;</span>\n  <span class=\"token punctuation\">}</span>\n\n  <span class=\"token function\">shouldComponentUpdate</span><span class=\"token punctuation\">(</span><span class=\"token parameter\">nextProps<span class=\"token punctuation\">,</span> nextState</span><span class=\"token punctuation\">)</span> <span class=\"token punctuation\">{</span>\n    <span class=\"token keyword\">if</span> <span class=\"token punctuation\">(</span><span class=\"token keyword\">this</span><span class=\"token punctuation\">.</span>props<span class=\"token punctuation\">.</span>color <span class=\"token operator\">!==</span> nextProps<span class=\"token punctuation\">.</span>color<span class=\"token punctuation\">)</span> <span class=\"token punctuation\">{</span>\n      <span class=\"token keyword\">return</span> <span class=\"token boolean\">true</span><span class=\"token punctuation\">;</span>\n    <span class=\"token punctuation\">}</span>\n    <span class=\"token keyword\">if</span> <span class=\"token punctuation\">(</span><span class=\"token keyword\">this</span><span class=\"token punctuation\">.</span>state<span class=\"token punctuation\">.</span>count <span class=\"token operator\">!==</span> nextState<span class=\"token punctuation\">.</span>count<span class=\"token punctuation\">)</span> <span class=\"token punctuation\">{</span>\n      <span class=\"token keyword\">return</span> <span class=\"token boolean\">true</span><span class=\"token punctuation\">;</span>\n    <span class=\"token punctuation\">}</span>\n    <span class=\"token keyword\">return</span> <span class=\"token boolean\">false</span><span class=\"token punctuation\">;</span>\n  <span class=\"token punctuation\">}</span>\n\n  <span class=\"token function\">render</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">)</span> <span class=\"token punctuation\">{</span>\n    <span class=\"token keyword\">return</span> <span class=\"token punctuation\">(</span>\n      <span class=\"token tag\"><span class=\"token tag\"><span class=\"token punctuation\">&lt;</span>button</span>\n        <span class=\"token attr-name\">color</span><span class=\"token script language-javascript\"><span class=\"token script-punctuation punctuation\">=</span><span class=\"token punctuation\">{</span><span class=\"token keyword\">this</span><span class=\"token punctuation\">.</span>props<span class=\"token punctuation\">.</span>color<span class=\"token punctuation\">}</span></span>\n        <span class=\"token attr-name\">onClick</span><span class=\"token script language-javascript\"><span class=\"token script-punctuation punctuation\">=</span><span class=\"token punctuation\">{</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">)</span> <span class=\"token operator\">=></span> <span class=\"token keyword\">this</span><span class=\"token punctuation\">.</span><span class=\"token function\">setState</span><span class=\"token punctuation\">(</span><span class=\"token parameter\">state</span> <span class=\"token operator\">=></span> <span class=\"token punctuation\">(</span><span class=\"token punctuation\">{</span>count<span class=\"token operator\">:</span> state<span class=\"token punctuation\">.</span>count <span class=\"token operator\">+</span> <span class=\"token number\">1</span><span class=\"token punctuation\">}</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">}</span></span><span class=\"token punctuation\">></span></span><span class=\"token plain-text\">\n        Счётчик: </span><span class=\"token punctuation\">{</span><span class=\"token keyword\">this</span><span class=\"token punctuation\">.</span>state<span class=\"token punctuation\">.</span>count<span class=\"token punctuation\">}</span><span class=\"token plain-text\">\n      </span><span class=\"token tag\"><span class=\"token tag\"><span class=\"token punctuation\">&lt;/</span>button</span><span class=\"token punctuation\">></span></span>\n    <span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span>\n  <span class=\"token punctuation\">}</span>\n<span class=\"token punctuation\">}</span></code></pre></div>\n<p>В этом коде <code class=\"gatsby-code-text\">shouldComponentUpdate</code> — это простая проверка на наличие каких-либо изменений в <code class=\"gatsby-code-text\">props.color</code> или <code class=\"gatsby-code-text\">state.count</code>. Если эти значения не изменяются, то компонент не обновляется. Если ваш компонент стал более сложным, вы можете использовать аналогичный паттерн «поверхностного сравнения» между всеми полями <code class=\"gatsby-code-text\">props</code> и <code class=\"gatsby-code-text\">state</code>, чтобы определить должен ли обновиться компонент. Этот механизм достаточно распространён, поэтому React предоставляет вспомогательную функцию для работы с ним — просто наследуйтесь от <code class=\"gatsby-code-text\">React.PureComponent</code>. Поэтому, следующий код — это более простой способ добиться того же самого эффекта:</p>\n<div class=\"gatsby-highlight\" data-language=\"jsx\"><pre class=\"gatsby-code-jsx\"><code class=\"gatsby-code-jsx\"><span class=\"token keyword\">class</span> <span class=\"token class-name\">CounterButton</span> <span class=\"token keyword\">extends</span> <span class=\"token class-name\">React<span class=\"token punctuation\">.</span>PureComponent</span> <span class=\"token punctuation\">{</span>\n  <span class=\"token function\">constructor</span><span class=\"token punctuation\">(</span><span class=\"token parameter\">props</span><span class=\"token punctuation\">)</span> <span class=\"token punctuation\">{</span>\n    <span class=\"token keyword\">super</span><span class=\"token punctuation\">(</span>props<span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span>\n    <span class=\"token keyword\">this</span><span class=\"token punctuation\">.</span>state <span class=\"token operator\">=</span> <span class=\"token punctuation\">{</span>count<span class=\"token operator\">:</span> <span class=\"token number\">1</span><span class=\"token punctuation\">}</span><span class=\"token punctuation\">;</span>\n  <span class=\"token punctuation\">}</span>\n\n  <span class=\"token function\">render</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">)</span> <span class=\"token punctuation\">{</span>\n    <span class=\"token keyword\">return</span> <span class=\"token punctuation\">(</span>\n      <span class=\"token tag\"><span class=\"token tag\"><span class=\"token punctuation\">&lt;</span>button</span>\n        <span class=\"token attr-name\">color</span><span class=\"token script language-javascript\"><span class=\"token script-punctuation punctuation\">=</span><span class=\"token punctuation\">{</span><span class=\"token keyword\">this</span><span class=\"token punctuation\">.</span>props<span class=\"token punctuation\">.</span>color<span class=\"token punctuation\">}</span></span>\n        <span class=\"token attr-name\">onClick</span><span class=\"token script language-javascript\"><span class=\"token script-punctuation punctuation\">=</span><span class=\"token punctuation\">{</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">)</span> <span class=\"token operator\">=></span> <span class=\"token keyword\">this</span><span class=\"token punctuation\">.</span><span class=\"token function\">setState</span><span class=\"token punctuation\">(</span><span class=\"token parameter\">state</span> <span class=\"token operator\">=></span> <span class=\"token punctuation\">(</span><span class=\"token punctuation\">{</span>count<span class=\"token operator\">:</span> state<span class=\"token punctuation\">.</span>count <span class=\"token operator\">+</span> <span class=\"token number\">1</span><span class=\"token punctuation\">}</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">}</span></span><span class=\"token punctuation\">></span></span><span class=\"token plain-text\">\n        Счётчик: </span><span class=\"token punctuation\">{</span><span class=\"token keyword\">this</span><span class=\"token punctuation\">.</span>state<span class=\"token punctuation\">.</span>count<span class=\"token punctuation\">}</span><span class=\"token plain-text\">\n      </span><span class=\"token tag\"><span class=\"token tag\"><span class=\"token punctuation\">&lt;/</span>button</span><span class=\"token punctuation\">></span></span>\n    <span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span>\n  <span class=\"token punctuation\">}</span>\n<span class=\"token punctuation\">}</span></code></pre></div>\n<p>В большинстве случаев вы можете использовать <code class=\"gatsby-code-text\">React.PureComponent</code> вместо написания собственного <code class=\"gatsby-code-text\">shouldComponentUpdate</code>. Но он делает только поверхностное сравнение, поэтому его нельзя использовать, если пропсы и состояние могут измениться таким образом, который не сможет быть обнаружен при поверхностном сравнении.</p>\n<p>Это может стать проблемой для более сложных структур данных. Например, вы хотите, чтобы компонент <code class=\"gatsby-code-text\">ListOfWords</code> отображал список слов, разделённых через запятую, с родительским компонентом <code class=\"gatsby-code-text\">WordAdder</code>, который позволяет кликнуть на кнопку, чтобы добавить слово в список. Этот код работает <em>неправильно</em>:</p>\n<div class=\"gatsby-highlight\" data-language=\"jsx\"><pre class=\"gatsby-code-jsx\"><code class=\"gatsby-code-jsx\"><span class=\"token keyword\">class</span> <span class=\"token class-name\">ListOfWords</span> <span class=\"token keyword\">extends</span> <span class=\"token class-name\">React<span class=\"token punctuation\">.</span>PureComponent</span> <span class=\"token punctuation\">{</span>\n  <span class=\"token function\">render</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">)</span> <span class=\"token punctuation\">{</span>\n    <span class=\"token keyword\">return</span> <span class=\"token tag\"><span class=\"token tag\"><span class=\"token punctuation\">&lt;</span>div</span><span class=\"token punctuation\">></span></span><span class=\"token punctuation\">{</span><span class=\"token keyword\">this</span><span class=\"token punctuation\">.</span>props<span class=\"token punctuation\">.</span>words<span class=\"token punctuation\">.</span><span class=\"token function\">join</span><span class=\"token punctuation\">(</span><span class=\"token string\">','</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">}</span><span class=\"token tag\"><span class=\"token tag\"><span class=\"token punctuation\">&lt;/</span>div</span><span class=\"token punctuation\">></span></span><span class=\"token punctuation\">;</span>\n  <span class=\"token punctuation\">}</span>\n<span class=\"token punctuation\">}</span>\n\n<span class=\"token keyword\">class</span> <span class=\"token class-name\">WordAdder</span> <span class=\"token keyword\">extends</span> <span class=\"token class-name\">React<span class=\"token punctuation\">.</span>Component</span> <span class=\"token punctuation\">{</span>\n  <span class=\"token function\">constructor</span><span class=\"token punctuation\">(</span><span class=\"token parameter\">props</span><span class=\"token punctuation\">)</span> <span class=\"token punctuation\">{</span>\n    <span class=\"token keyword\">super</span><span class=\"token punctuation\">(</span>props<span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span>\n    <span class=\"token keyword\">this</span><span class=\"token punctuation\">.</span>state <span class=\"token operator\">=</span> <span class=\"token punctuation\">{</span>\n      words<span class=\"token operator\">:</span> <span class=\"token punctuation\">[</span><span class=\"token string\">'словцо'</span><span class=\"token punctuation\">]</span>\n    <span class=\"token punctuation\">}</span><span class=\"token punctuation\">;</span>\n    <span class=\"token keyword\">this</span><span class=\"token punctuation\">.</span>handleClick <span class=\"token operator\">=</span> <span class=\"token keyword\">this</span><span class=\"token punctuation\">.</span><span class=\"token function\">handleClick</span><span class=\"token punctuation\">.</span><span class=\"token function\">bind</span><span class=\"token punctuation\">(</span><span class=\"token keyword\">this</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span>\n  <span class=\"token punctuation\">}</span>\n\n  <span class=\"token function\">handleClick</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">)</span> <span class=\"token punctuation\">{</span>\n    <span class=\"token comment\">// Данная секция содержит плохой код и приводит к багам</span>\n    <span class=\"token keyword\">const</span> words <span class=\"token operator\">=</span> <span class=\"token keyword\">this</span><span class=\"token punctuation\">.</span>state<span class=\"token punctuation\">.</span>words<span class=\"token punctuation\">;</span>\n    words<span class=\"token punctuation\">.</span><span class=\"token function\">push</span><span class=\"token punctuation\">(</span><span class=\"token string\">'словцо'</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span>\n    <span class=\"token keyword\">this</span><span class=\"token punctuation\">.</span><span class=\"token function\">setState</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">{</span>words<span class=\"token operator\">:</span> words<span class=\"token punctuation\">}</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span>\n  <span class=\"token punctuation\">}</span>\n\n  <span class=\"token function\">render</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">)</span> <span class=\"token punctuation\">{</span>\n    <span class=\"token keyword\">return</span> <span class=\"token punctuation\">(</span>\n      <span class=\"token tag\"><span class=\"token tag\"><span class=\"token punctuation\">&lt;</span>div</span><span class=\"token punctuation\">></span></span><span class=\"token plain-text\">\n        </span><span class=\"token tag\"><span class=\"token tag\"><span class=\"token punctuation\">&lt;</span>button</span> <span class=\"token attr-name\">onClick</span><span class=\"token script language-javascript\"><span class=\"token script-punctuation punctuation\">=</span><span class=\"token punctuation\">{</span><span class=\"token keyword\">this</span><span class=\"token punctuation\">.</span>handleClick<span class=\"token punctuation\">}</span></span> <span class=\"token punctuation\">/></span></span><span class=\"token plain-text\">\n        </span><span class=\"token tag\"><span class=\"token tag\"><span class=\"token punctuation\">&lt;</span><span class=\"token class-name\">ListOfWords</span></span> <span class=\"token attr-name\">words</span><span class=\"token script language-javascript\"><span class=\"token script-punctuation punctuation\">=</span><span class=\"token punctuation\">{</span><span class=\"token keyword\">this</span><span class=\"token punctuation\">.</span>state<span class=\"token punctuation\">.</span>words<span class=\"token punctuation\">}</span></span> <span class=\"token punctuation\">/></span></span><span class=\"token plain-text\">\n      </span><span class=\"token tag\"><span class=\"token tag\"><span class=\"token punctuation\">&lt;/</span>div</span><span class=\"token punctuation\">></span></span>\n    <span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span>\n  <span class=\"token punctuation\">}</span>\n<span class=\"token punctuation\">}</span></code></pre></div>\n<p>Проблема в том, что <code class=\"gatsby-code-text\">PureComponent</code> сделает сравнение по ссылке между старыми и новыми значениями <code class=\"gatsby-code-text\">this.props.words</code>. Поскольку этот код мутирует массив <code class=\"gatsby-code-text\">words</code> в методе <code class=\"gatsby-code-text\">handleClick</code> компонента <code class=\"gatsby-code-text\">WordAdder</code>, старые и новые значения <code class=\"gatsby-code-text\">this.props.words</code> при сравнении по ссылке будут равны, даже если слова в массиве изменились. <code class=\"gatsby-code-text\">ListOfWords</code> не будет обновляться, даже если он содержит новые слова, которые должны быть отрендерены.</p>\n<h2 id=\"the-power-of-not-mutating-data\"><a href=\"#the-power-of-not-mutating-data\" aria-hidden class=\"anchor\"><svg aria-hidden=\"true\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>Сила иммутабельных данных </h2>\n<p>Лучший способ решения этой проблемы — избегать мутирования значений, которые вы используете как свойства или состояние. К примеру, описанный выше метод <code class=\"gatsby-code-text\">handleClick</code> можно переписать с помощью <code class=\"gatsby-code-text\">concat</code> следующим образом:</p>\n<div class=\"gatsby-highlight\" data-language=\"jsx\"><pre class=\"gatsby-code-jsx\"><code class=\"gatsby-code-jsx\"><span class=\"token function\">handleClick</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">)</span> <span class=\"token punctuation\">{</span>\n  <span class=\"token keyword\">this</span><span class=\"token punctuation\">.</span><span class=\"token function\">setState</span><span class=\"token punctuation\">(</span><span class=\"token parameter\">state</span> <span class=\"token operator\">=></span> <span class=\"token punctuation\">(</span><span class=\"token punctuation\">{</span>\n    words<span class=\"token operator\">:</span> state<span class=\"token punctuation\">.</span>words<span class=\"token punctuation\">.</span><span class=\"token function\">concat</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">[</span><span class=\"token string\">'словцо'</span><span class=\"token punctuation\">]</span><span class=\"token punctuation\">)</span>\n  <span class=\"token punctuation\">}</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span>\n<span class=\"token punctuation\">}</span></code></pre></div>\n<p>ES6 поддерживает <a href=\"https://developer.mozilla.org/ru/docs/Web/JavaScript/Reference/Operators/Spread_syntax\" target=\"_blank\" rel=\"nofollow noopener noreferrer\">синтаксис расширения</a> для массивов, который поможет сделать это проще. Если вы используете Create React App, то этот синтаксис доступен там по умолчанию.</p>\n<div class=\"gatsby-highlight\" data-language=\"jsx\"><pre class=\"gatsby-code-jsx\"><code class=\"gatsby-code-jsx\"><span class=\"token function\">handleClick</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">)</span> <span class=\"token punctuation\">{</span>\n  <span class=\"token keyword\">this</span><span class=\"token punctuation\">.</span><span class=\"token function\">setState</span><span class=\"token punctuation\">(</span><span class=\"token parameter\">state</span> <span class=\"token operator\">=></span> <span class=\"token punctuation\">(</span><span class=\"token punctuation\">{</span>\n    words<span class=\"token operator\">:</span> <span class=\"token punctuation\">[</span><span class=\"token operator\">...</span>state<span class=\"token punctuation\">.</span>words<span class=\"token punctuation\">,</span> <span class=\"token string\">'словцо'</span><span class=\"token punctuation\">]</span><span class=\"token punctuation\">,</span>\n  <span class=\"token punctuation\">}</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span>\n<span class=\"token punctuation\">}</span><span class=\"token punctuation\">;</span></code></pre></div>\n<p>Таким же образом вы можете переписать код, который мутирует объекты. К примеру, мы имеем объект с именем <code class=\"gatsby-code-text\">colormap</code> и хотим написать функцию, которая изменяет <code class=\"gatsby-code-text\">colormap.right</code> на <code class=\"gatsby-code-text\">&#39;blue&#39;</code>. Мы могли бы написать:</p>\n<div class=\"gatsby-highlight\" data-language=\"jsx\"><pre class=\"gatsby-code-jsx\"><code class=\"gatsby-code-jsx\"><span class=\"token keyword\">function</span> <span class=\"token function\">updateColorMap</span><span class=\"token punctuation\">(</span><span class=\"token parameter\">colormap</span><span class=\"token punctuation\">)</span> <span class=\"token punctuation\">{</span>\n  colormap<span class=\"token punctuation\">.</span>right <span class=\"token operator\">=</span> <span class=\"token string\">'blue'</span><span class=\"token punctuation\">;</span>\n<span class=\"token punctuation\">}</span></code></pre></div>\n<p>Чтобы написать это без мутирования исходного объекта, мы можем использовать метод <a href=\"https://developer.mozilla.org/ru/docs/Web/JavaScript/Reference/Global_Objects/Object/assign\" target=\"_blank\" rel=\"nofollow noopener noreferrer\">Object.assign</a>:</p>\n<div class=\"gatsby-highlight\" data-language=\"jsx\"><pre class=\"gatsby-code-jsx\"><code class=\"gatsby-code-jsx\"><span class=\"token keyword\">function</span> <span class=\"token function\">updateColorMap</span><span class=\"token punctuation\">(</span><span class=\"token parameter\">colormap</span><span class=\"token punctuation\">)</span> <span class=\"token punctuation\">{</span>\n  <span class=\"token keyword\">return</span> Object<span class=\"token punctuation\">.</span><span class=\"token function\">assign</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">{</span><span class=\"token punctuation\">}</span><span class=\"token punctuation\">,</span> colormap<span class=\"token punctuation\">,</span> <span class=\"token punctuation\">{</span>right<span class=\"token operator\">:</span> <span class=\"token string\">'blue'</span><span class=\"token punctuation\">}</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span>\n<span class=\"token punctuation\">}</span></code></pre></div>\n<p>Функция <code class=\"gatsby-code-text\">updateColorMap</code> теперь возвращает новый объект, вместо того, чтобы мутировать исходный. Метод <code class=\"gatsby-code-text\">Object.assign</code> входит в ES6 и требует полифила.</p>\n<p><a href=\"https://developer.mozilla.org/ru/docs/Web/JavaScript/Reference/Operators/Spread_syntax\" target=\"_blank\" rel=\"nofollow noopener noreferrer\">Синтаксис расширения свойств объекта</a> упрощает обновление объектов без мутаций:</p>\n<div class=\"gatsby-highlight\" data-language=\"jsx\"><pre class=\"gatsby-code-jsx\"><code class=\"gatsby-code-jsx\"><span class=\"token keyword\">function</span> <span class=\"token function\">updateColorMap</span><span class=\"token punctuation\">(</span><span class=\"token parameter\">colormap</span><span class=\"token punctuation\">)</span> <span class=\"token punctuation\">{</span>\n  <span class=\"token keyword\">return</span> <span class=\"token punctuation\">{</span><span class=\"token operator\">...</span>colormap<span class=\"token punctuation\">,</span> right<span class=\"token operator\">:</span> <span class=\"token string\">'blue'</span><span class=\"token punctuation\">}</span><span class=\"token punctuation\">;</span>\n<span class=\"token punctuation\">}</span></code></pre></div>\n<p>Этот синтаксис был добавлен в JavaScript в ES2018. </p>\n<p>Если вы используете Create React App, то <code class=\"gatsby-code-text\">Object.assign</code> и синтаксис расширения объектов доступны вам по умолчанию.</p>\n<p>При работе с глубоко вложенными объектами, постоянное их обновление может запутать. Если вы столкнулись с такой проблемой, обратите внимание на <a href=\"https://github.com/mweststrate/immer\" target=\"_blank\" rel=\"nofollow noopener noreferrer\">Immer</a> или <a href=\"https://github.com/kolodny/immutability-helper\" target=\"_blank\" rel=\"nofollow noopener noreferrer\">immutability-helper</a>. Эти библиотеки позволяют писать хорошо читаемый код, не теряя преимуществ иммутабельности.</p>","frontmatter":{"title":"Оптимизация производительности","next":null,"prev":null},"fields":{"path":"content/docs/optimizing-performance.md","slug":"docs/optimizing-performance.html"}}},"pageContext":{"slug":"docs/optimizing-performance.html"}},"staticQueryHashes":[]}