TL;DR

Спустя полтора года после того, как я написал эту статью…

С течением времени я осознал пути великих мастеров, и я должен сказать, что почти все нижеприведенное менее применимо сейчас, когда я знаю Immutable.js. Тем не менее, многое из приведенного ниже по-прежнему применимо, однако в будущем я почти всегда буду использовать Immutable для моих компонентов контейнера и логики хранилища redux. Кроме того, я бы также использовал атрибут mergeProps метода connect в React Redux, чтобы гарантировать, что презентационный компонент получает только те реквизиты, которые ему действительно нужны, и не более того.

Если вы используете большие формы в React, у вас могут возникнуть проблемы с производительностью в процессе разработки. Существуют различные методы оптимизации ваших форм для повышения скорости при работе с большим количеством вводимых форм. Ниже приведен один из таких методов, который решает проблему путем группировки полей и разумного обновления только отдельной группы полей, если это значения, или любые значения, входные данные в группе зависят от изменений.

Пример кода для следующей демонстрации можно найти здесь.

Формы Big React могут иметь проблемы с производительностью

Мы уже знаем, что приложение Create React, Formik и библиотека проверки yup действительно хорошо работают вместе. Объедините их с Redux и React Router, и вы на правильном пути к своему следующему потрясающему клиентскому приложению.

Однако время идет, масштабы уменьшаются, и вы понимаете, что формы Formik становятся довольно большими. 50 или 60 полей в одной форме, и ваше приложение начинает работать вялым и невосприимчивым, особенно при заполнении форм с открытыми инструментами разработчика вашего браузера. Увеличьте это до 100+ полей формы, и все остановится.

Одним из требований наших форм (и, скорее всего, всех больших форм) является зависимость полей (или динамических входов): значения определенных полей определяют параметры, требования к видимости и проверке других полей. Таким образом, каждое поле является собственным компонентом, который получает свойства рендеринга Formik. На основе логики конфигурации (также переданной как опора в соответствующий компонент ввода) и значений других полей (определяемых из опоры рендеринга Formik), параметры, требования к валидации и видимость дочерних компонентов ввода изменяются.

Formik предлагает возможность ускорить процесс проверки при каждом нажатии клавиши, поэтому вы validateOnChange выключаете и надеетесь на лучшее. Это немного помогает, но все еще далеки от совершенства, поскольку каждое нажатие клавиши вызывает повторный рендеринг всех дочерних компонентов в форме (из-за valueschanges в опоре рендеринга Formik).

Осмотрев вещи немного глубже с помощью профилировщика инструментов разработчика (график пламени) или https://github.com/welldone-software/why-did-you-render, становится очевидным, что все дочерние компоненты ввода Formik (т. Е. Ваш текст входы, выборки, текстовые поля, флажки и т. д.) повторно визуализируются при каждом нажатии клавиши. Почему? Поскольку они являются динамическими входами, они должны: их свойства меняются. Это довольно сложная проблема для решения, не так ли? Сегодня я расскажу о решении этой проблемы нашей командой: использование полевых групп и наблюдателей, что, вероятно, является лишь одним из способов обойти эту проблему. Если у вас есть идеи по улучшению, прокомментируйте и поделитесь.

1. Конфиг

Перед определением формы Formik и дочерних компонентов ввода мы начнем с декларативной конфигурации JSON:

Вышеупомянутое сокращено (может быть много, много других полей), но я думаю, вы уловили идею.

2. Форма Formik

Центральным элементом этой головоломки является форма Formik. Мы настроили его довольно стандартным образом:

3. Группа полей

В компоненте FieldGroup происходит волшебство. Он группирует как поля, а затем использует логику, настроенную в файле конфигурации JSON, чтобы решить, должна ли группа обновляться или нет, когда происходят изменения в любом из входных данных формы. Фактически это создает мини-формы внутри формы, тем самым оптимизируя скорость обновлений в целом. Поля отображаются с помощью компонента Formik Field, который автоматически обрабатывает onChange и обновляет значения каждого ввода.

Короче говоря, каждый раз, когда Formikprops.valueschanges, все группы полей в форме будут отображаться, однако внутри каждой группы полей существует логика, позволяющая решить, участвует ли эта группа напрямую в изменении (т.е. входные данные в самой группе изменили значение) или есть ли какие-либо внесенных изменений влияет на группу (т. е. негрупповые поля, которые условно влияют на входы в этой группе). Если какое-либо из этих условий истинно, группа будет повторно визуализирована, в противном случае визуализация будет исключена в методе shouldComponentUpdatelifecycle.

Как вы можете видеть выше, несмотря на то, что все свойства группы меняются при каждом нажатии клавиши, обновляются только группы, на которые это изменение оказывает непосредственное влияние. Это дает огромные преимущества в производительности для больших форм.

Пример кода для этой демонстрации можно найти по ссылке ниже. Не стесняйтесь разветвлять или отправлять PR, чтобы улучшить его. Кроме того, поделитесь с нами своими комментариями (или даже хлопайте в ладоши), и давайте вместе сделаем этот мир и веб-формы лучше.



Заключительное примечание…

Вышеупомянутый шаблон для оптимизации обновлений форм был придуман блестящим Джулианом Рахманном до того, как я взял его в руки и полностью испортил дело. Все похвалы и обвинения должны быть направлены на него 😉.

Если вам понравилась эта статья, пожалуйста, посоветуйте мне написать больше, если она вам понравится. Также ознакомьтесь с еще одной из моих статей о шаблоне контейнер / компонент здесь.

Фото sergio souza на Unsplash