23 февраля 16–03 июня 16

Примечание для случайного читателя: это самостоятельное документирование того, над чем я работал, может быть утомительным, вас предупредили.

В конце февраля я вернулся на Тасманию и за обедом встретился с несколькими старыми коллегами по работе. После наверстывания у меня спросили, не хочу ли я присоединиться и помочь с их новым клиентом, который сталкивается с цитированием веб-сайта. У меня была пара проектов, которые я должен был связать сначала, но через пару недель я застрял.

Я провел первые пару дней, просеивая их проект, пытаясь понять, как все это работает и сочетается друг с другом. Это было приложение MVC C# с целой кучей сторонних файлов JavaScript, связанных, чтобы заставить его что-то делать.

Он был построен поверх начальной загрузки, однако у него был один основной большой файл less, который выполнял большую часть стилей. Этот файл состоял из более чем 8000 строк и был переполнен операторами `!important`. Это было совершенно неуправляемо.

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

То, как это работало, было немного ужасным, пользователь мог изменить параметр на панели, у этой панели была собственная форма, и эта форма отправлялась. Сервер отправит обновленный html для всей панели и заменит его. Это довольно типично для старых форм .NET Ajax, но у него были свои проблемы. На странице уже было 7 или 8 форм, которыми довольно сложно управлять и дорабатывать.

Другая проблема, которую это вызвало, была связана с тем, что было много сторонних плагинов jQuery, которые использовали ужасный метод украшения и добавления прослушивателей событий в событие document.ready. Когда форма ajax заменила весь html на этих панелях, эти компоненты больше не украшались и не имели каких-либо необходимых прослушивателей событий для правильной работы. Таким образом, в коде были некоторые обходные пути, которые запускали эти методы плагина, когда панель заменялась новым html. Было совершенно ясно, что эту страницу будет трудно улучшить, если появятся какие-то новые требования.

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

Следующие несколько дней я провел, думая о том, что я хочу изменить, и записывая причины, почему. Затем я представил свои аргументы существующим разработчикам, чтобы убедить их в правильности выбранного пути.

Первое, что я хотел сделать, это взять под контроль множество спагетти-складок клиентских ресурсов, поэтому я предложил использовать Webpack. На данный момент действительно нет ничего лучше для управления кодом на стороне клиента, чем этот инструмент, есть и другие инструменты, но они не такие мощные. Главное, что делает Webpack, чего не делают другие инструменты, — это разделение кода. Что невероятно полезно, когда вы хотите оптимизировать свой сайт позже.

Затем я начал получать весь устаревший код, который был скопирован и вставлен на каждую страницу, в модули, скомпилированные с помощью Webpack. Я перемещал вещи так, чтобы код, который был явно скопирован и вставлен, затем помещался в общий модуль. Это был невероятно утомительный процесс, но он уже начал осваиваться с кодовой базой.

Это проверило мое понимание Webpack, поскольку существовала целая куча различных клиентских ресурсов. Пользовательские шрифты, меньше, файлы sass, изображения и т. д.

У Webpack также было дополнительное преимущество, заключающееся в том, что он мог использовать ES6 для написания всего кода в будущем, что удивительно для того, чтобы делать больше с меньшим количеством кода и упростить анализ и чтение вашей кодовой базы.

Я сделал это, создав небольшие хуки функций JavaScript, которые я мог вызывать из основных представлений бритвы ASP, которые выполняли бы весь код, который раньше был на этих страницах, который теперь был связан с Webpack.

После того, как я вытащил все таблицы стилей и JavaScript из представлений Razor, я захотел улучшить пользовательский интерфейс. Что-либо динамическое в данный момент означало либо полное обновление страницы, либо использование неуклюжей панели форм ASP Ajax, которая отстой для пользователя. Поэтому я применил React и использовал его для написания небольших компонентов, заменяющих части страниц, которые либо нуждались в исправлении, либо появились как новое требование.

На странице предположений было много мелких ошибок, из-за которых она казалась неуклюжей. В основном это было связано с тем, как это работало. Это был беспорядок jQuery, множество функций, которые запускались в зависимости от различных событий и действий пользователя. Пользователь щелкал что-то, что вызывало срабатывание множества других функций и изменение строк в пользовательском интерфейсе или что-то еще. Он остро нуждался в чем-то лучшем, чтобы управлять своим состоянием. Так что я убедил других разработчиков, что добавление избыточности для управления состоянием решит многие из этих проблем. Односторонний поток данных Redux действительно помог упростить ситуацию.

У меня было сочетание компонентов DOM, созданных с помощью jQuery, и компонентов React, поэтому мне пришлось вручную подписаться на хранилище Redux для вещей, не относящихся к React, и я использовал метод `connect` `react-redux` для компонентов React.

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

Поскольку все состоит из компонентов React, все стили для каждого компонента находятся в файле CSS вместе со всеми ресурсами, необходимыми для создания этого компонента. Это было намного проще поддерживать, если вам нужно обновить стиль, разработчик сразу знает, куда идти и что обновлять. Затем я мог удалить файл на 8000 строк меньше, который был замусорен операторами `!important`, которые вызвали огромное количество горя.

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

Благодаря значительному упрощению внешнего интерфейса и отсутствию зависимости от MVC (кроме использования модели для проверки на стороне сервера) это создало возможности для упрощения внутреннего интерфейса. Теперь нет необходимости различать методы, которые работают для определенных страниц, вы можете использовать общие методы, не ограниченные структурой вашей архитектуры. например Вместо методов сохранения данных на странице адреса или странице предположений у вас может быть один метод «сохранить цитату», который вы можете использовать повторно. Это снижает сложность вашего бэкенда и делает ваш код более удобным в сопровождении. Я провел остаток своего времени здесь, прежде чем перейти к другому проекту.

Я невероятно усердно работал над преобразованием приложения, чтобы оно полностью реагировало, и потратил несколько дополнительных часов, чтобы ускорить работу.

В целом было тяжело, но оно того стоило, приложение работает молниеносно. Было сложно убедить моих коллег использовать ES6 и полностью отреагировать, но я благодарен, что они согласились с этим.

Думаю, результаты говорят сами за себя. Через 3 месяца ощутимая производительность будет мгновенной благодаря переходу на одну страницу и разделению кода. А кодовая база на стороне клиента была сокращена с 31 тыс. до 6 тыс. строк кода.

Что было сложно и чему я научился

Состояние и валидация — самые сложные вещи.

Выполнение проверки в реакции, все еще неясно, как лучше всего подойти к этому. У нас уже было много бизнес-логики, написанной в коде проверки сервера, которая была сильно привязана к тому, как работает проверка модели MVC, которую существующие разработчики не хотели повторно реализовывать в коде на стороне клиента.

Поэтому я выбрал создание избыточных действий, которые проверяли и сохраняли данные. Он отправит некоторые данные на сервер, который либо ничего не вернет (успех), либо ошибки проверки. Затем ошибки валидации были помещены прямо в состояние сокращения, где компоненты могли повторно отображать себя для отображения ошибок, это сработало очень хорошо, и я очень доволен простым процессом. Единственным недостатком является задержка проверки на стороне сервера.

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

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

Я обнаружил, что в 99% случаев, если вы используете избыточность с React и у компонента есть состояние, это, вероятно, неправильно и должно быть переведено в состояние избыточности. Единственный допустимый случай для состояния компонента — это что-то вроде раскрывающегося списка, который открывается и закрывается, что может быть состоянием компонента, но, вероятно, не должно быть. Легче рендерить на основе реквизита, добавленного с помощью Redux. Как только вы попытаетесь написать некоторый код, чтобы закрыть это раскрывающееся меню выше по дереву компонентов, оно становится очень запутанным, если оно находится в состоянии компонента.

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

Ищете компанию, которая возьмется за ваш следующий проект? Попробуйте нас www.lunait.solutions