Оптимизация. Рефакторинг¶
В нашем решении есть слабые места:
- некоторые названия переменных избыточны (чтобы было понятно, добавлено
Actions
у экшенов, которые мы приклеиваем); - повторяющийся однотипный код (5 кнопок с номером года в
<Page />
); - в
action
улетает текст с кнопки, если текст изменится - код сломается. Проблема: большая связанность. Нужно облегчить. - возможно существует более простой путь "достать" из вк фото за конкретный год (не рассматриваю это как проблему);
- фраза "Привет, ИМЯ" после обновления страницы заменяется кнопкой "войти", то есть не отображает реальной картины (фотографии у нас при этом доступны для загрузки, то есть мы уже авторизованы);
- после авторизации (или после перезагрузки) было бы неплохо сразу загружать фото для 2018 года, так как юзер видит пустой экран и заголовок 2018;
Можно отнести это к "доработкам". Однако у нас есть место, которое является опасным и о котором я лишь вскользь говорил в учебнике, пора исправится.
Приглашаю вас "убить" главную проблему текущего приложения - лишние перерисовки компонента в следующем подразделе.
Остальные проблемы и будущие доработки живут в одноименном разделе.
Главная проблема приложения¶
У нас есть 2 компонента <User />
и <Page />
. Мы специально сделали для них два редьюсера, чтобы обновлять их независимо! А у нас? А у нас <User />
каждый раз обновляется при обновлении <Page />
и наоборот.
Добавьте console.log
в render
метод у <User />
:
src/components/User.js
1 2 3 4 |
|
Перерисовка компонента User происходит постоянно. Это не влияет на производительность нашего мини-приложения, однако, мы не готовы с этим мириться.
Представьте дашборд (панель) с большим количеством виджетов, информация в которых обновляется по событиям от бэкэнда. Если каждый виджет будет перерисовывать полностью весь дашборд, то это будет крайне некрасиво (как для юзера, так и для производительности).
Чтобы такого не было, мы должны каждую отдельную сущность приложения класть в отдельный контейнер.
Будем исправлять, для этого:
<App />
становится тупым компонентом, который рендерит 2 контейнера:
<PageContainer />
<UserContainer />
Данные контейнеры - просто обертки над нашими компонентами, в которых мы "подключаемся (connect) к Redux".
Так же, я сразу заменю название у экшенов внутри mapDispatchToProps
: уберу оттуда частичку Action
.
В остальном, мы просто "разносим" то, что было в <App />
по раздельным контейнерам.
src/index.js
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 |
|
src/components/App.js
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 |
|
src/containers/PageContainer.js
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 |
|
Как вы могли заметить, все что касалось <Page />
хранится в отдельном контейнере: подписка на часть стора, экшен, пропсы...
То же самое, делаем для <UserContainer />
src/containers/UserContainer.js
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 |
|
Теперь внимание: в компоненте App
есть два "независимых компонента". Сейчас при изменении данных в редьюсере для Page
- User
перерисовываться не будет. App
тоже, само собой. App
у нас вообще не будет перерисовываться более при таком раскладе.
Снова покликаем по кнопкам (console.log
в <User />
остался):
Еще раз заострю внимание: мы не просто сделали хорошо, мы сделали супер-хорошо! Render - обычно самая дорогая операция. Вызывать "перерисовку" каждого "кусочка" приложения нужно осознанно. Всегда проверяйте (например, так же банально с помощью console.log
) сколько раз у вас что рендерится, и нет ли чего лишнего.
Давайте заодно здесь быстренько исправим отрисовку кнопок в <Page />
src/components/Page.js
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 |
|
(Добавьте по вкусу щепотку margin
для .btn
)
Использовать в данной ситуации index
для key
плохо?. В данном случае - не плохо. Напоминаю, что индекс в качестве ключа плохо использовать, когда у вас элементы меняются местами. Справедливости ради, здесь в качестве индекса можно было бы использовать "год", так как главное в индексе - это уникальность.
Итого: мы научились бережно относится к перерисовкам, а так же закрепили на практике вопрос зачем разбивать редьюсер на маленькие редьюсеры.