Здесь, в Walmart, покупатель всегда №1, поэтому мы постоянно ищем способы улучшить качество покупок, которое мы предоставляем нашим клиентам. Приложение Walmart в его нынешнем виде имеет ряд встроенных веб-представлений, и мы обнаружили, что эти реализации не соответствуют стандартам, которые и мы, и наши клиенты требуем от приложения. Производительность гибридных реализаций веб-представлений невысока даже на высокопроизводительных устройствах, и отсутствует какое-либо подобие нативного восприятия. Не только это, но и потому, что веб-представления сильно зависят от сетевых запросов (мы используем рендеринг на стороне сервера для нашей веб-реализации), пользователи с более медленным подключением могут столкнуться с трудностями. Итак, мы задавались вопросом: Есть ли способ обновить или заменить текущие реализации, чтобы обеспечить лучший и плавный опыт для наших клиентов? И мы начали поиск ответа.

Возможные решения

После мозгового штурма мы пришли к следующим решениям:

  1. Чистая собственная реализация (больше никаких веб-представлений)
  2. React Native

Нативная реализация хороша в теории, но на практике нам нужно подумать о производительности / совместном использовании кода / времени выхода на рынок, и именно здесь на помощь приходит кроссплатформенный фреймворк, такой как React Native. Существуют и другие кроссплатформенные фреймворки для мобильной разработки. React Native, таких как PhoneGap, Xamarin и Meteor, но, учитывая, что наша текущая веб-кодовая база использует React и Redux, имеет смысл рассмотреть React Native перед любой другой кроссплатформенной структурой - не говоря уже о том, что она довольно стабильна и, вероятно, какое-то время останется популярным.

Вот преимущества, которые мы наблюдали с React Native:

Производительность

  • 95% кодовой базы разделяется между iOS и Android.
  • Обмен знаниями не требуется, поскольку каждая функция реализуется одной командой
  • Отличный опыт разработчика. Не нужно перезапускать упаковщик, чтобы увидеть простые изменения
  • React Native написан на JavaScript. Мы можем использовать навыки / ресурсы программирования в масштабах всей организации.

Совместное использование кода

  • Код FrontEnd / Presentation может использоваться совместно с iOS и Android.
  • Бизнес-логика (redux store) также может использоваться совместно с веб-приложениями.
  • Возможность многократного использования кода между платформами

Одобрение магазина приложений

  • Нет необходимости проходить процесс утверждения в магазине приложений. Мы можем разместить пакет на нашем собственном сервере и делать обновления по беспроводной сети.

Время выхода на рынок

  • Очень быстро
  • Мы контролируем даты выхода
  • Обе платформы могут быть выпущены в один и тот же день и время.

Производительность

  • React Native обеспечивает почти такую ​​же производительность, что и native

Анимация

  • React Native обеспечивает чрезвычайно плавную анимацию, поскольку код преобразуется в собственные представления перед рендерингом.

UX

  • У нас может быть дизайн пользовательского интерфейса для конкретной платформы

Автоматизация

  • Один и тот же пакет автоматизации может работать как на iOS, так и на Android.

Производительность

У нас было несколько целей, когда мы проводили тестирование производительности в WalmartLabs. Мы хотели узнать, насколько React Native превосходит своих конкурентов, основываясь на таких показателях, как использование ОЗУ, FPS, загрузка ЦП и т. Д., Но мы также хотели изучить возможности масштабирования React Native - поскольку потенциально React Native может стать стандартной мобильной технологией. для всего предприятия. Поскольку этот проект является экспериментом для WalmartLabs, нашей краткосрочной целью было доказать, что эта технология имеет профиль производительности, эквивалентный или лучше, чем текущее решение. В долгосрочной перспективе нам нужно интегрировать тестирование производительности с нашим CI, как это делает Facebook, чтобы мы могли проверить влияние каждого нашего изменения на общую производительность приложения.

Проблема с триблами

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

Facebook попытался преодолеть разрыв между тестированием производительности Android и iOS, предоставив монитор производительности, встроенный в меню разработчика React Native. К сожалению, это решение далеко не безупречно. В iOS он обеспечивает использование ОЗУ, данные FPS, а также множество измерений, связанных с React Native, однако для Android монитор perf предоставляет только данные FPS. В будущем мне бы хотелось, чтобы предоставленные измерения были стандартизированы для обеих платформ, если это возможно.

Заткнись и расскажи мне, как справился React Native!

Хорошо, хорошо, но имейте в виду, что показатели, которые мы сообщаем, основаны на НАШЕМ приложении и могут не соответствовать ВАШЕМУ приложению. Однако я постараюсь дать общие выводы, которые можно сделать из наших тестов.

Собранные нами данные обнадеживают. Он показал, что React Native действительно является жизнеспособным решением для больших и малых мобильных приложений. Что касается графической производительности, использования ОЗУ и ЦП, все меры, которые мы предприняли, были сопоставимы или лучше, чем у нашего текущего гибридного решения, и это справедливо для обеих платформ. Общее впечатление от приложения было значительно улучшено, и теперь он обеспечивает гораздо лучший пользовательский интерфейс по сравнению с гибридным.

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

Тестирование

Чтобы обеспечить качество нашего кода React Native, мы стремимся обеспечить 100% тестовое покрытие как для модульных, так и для интеграционных тестов.

Интеграционные тесты

Приложения Walmart для iOS и Android созданы сотнями инженеров. Мы используем наши интеграционные тесты, чтобы гарантировать, что наш код React Native остается функциональным по мере того, как кодовая база продолжает развиваться.

В Walmart нам необходимо поддерживать широкий спектр устройств и операционных систем. Sauce Labs позволяет нам запускать наши интеграционные тесты на нескольких комбинациях оборудования и версий ОС iOS и Android. Выполнение интеграционных тестов на нескольких устройствах занимает много времени, поэтому мы делаем это только один раз каждую ночь.

Мы также используем наши интеграционные тесты, чтобы предотвратить регресс. Мы подключили наш TeamCity CI к GitHub Enterprise, чтобы запускать наши тесты при каждом запросе на вытягивание. В отличие от ночного задания, с запросами на включение мы запускаем тесты только на одном устройстве. Но даже это потенциально может занять больше времени, чем это возможно, поэтому мы используем некоторые инструменты, чтобы сократить это время. Magellan, который является одним из наших проектов с открытым исходным кодом, позволяет нам запускать тесты параллельно, что значительно сокращает время тестирования.

Сами тесты написаны на JavaScript, запускаются Mocha и используют команды Appium для управления мобильными симуляторами. React Native позволяет нам устанавливать свойство testID для каждого компонента. Эти testID действуют как имена классов CSS. Мы используем их, чтобы точно и удобно указать компонент с помощью XPath и взаимодействовать с ним в целях тестирования.

Модульные тесты

Мы используем модульные тесты для изолированной проверки наших компонентов React Native и предотвращения непреднамеренных изменений.

Мы используем стандартные инструменты модульного тестирования React, такие как Mocha, Chai, Sinon и Enzyme. Но у React Native есть некоторые уникальные проблемы, потому что его компоненты имеют зависимости от среды, которые не позволяют ему работать на Node. Response-native-mock решает эту проблему для нас, потому что он предоставляет имитированные компоненты React Native, которые не ломаются при запуске вне iOS или Android. А когда нам нужно имитировать дополнительные зависимости, мы используем модуль узла rewire.

Возможность повторного использования

Мы используем один и тот же набор тестов автоматизации для работы как на iOS, так и на Android.

Развертывание

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

Однако одна проблема, которую представляет React Native, заключается в том, что для работы пакета JS должен быть совместимый аналог React Native на нативной стороне. Если вы обновите нативную часть до последней версии React Native, и пользователь обновит свое приложение, но загрузит старый пакет, приложение сломается. И если вы обновите пакет, чтобы он соответствовал последней версии нативной версии, и предоставите его пользователю, который еще не обновил свое приложение, он тоже сломается.

Такие инструменты, как Microsoft CodePush, можно использовать для сопоставления пакетов с правильными версиями приложения. Но одновременная поддержка нескольких версий приложения - это накладные расходы, которые следует учитывать при принятии решения об использовании React Native.

Вызовы

Различия между iOS и Android

Между функциями React Native на iOS и Android достаточно несоответствий, поэтому поддержка обеих платформ усложняется. Некоторые варианты поведения и реализации стиля React Native различаются между платформами. Например, свойство стиля «overflow» поддерживается на iOS, но не на Android. Свойства компонентов также могут зависеть от платформы. В документации React Native вы можете увидеть множество свойств и функций, отмеченных как «Только для Android» или «Только для iOS». Код автоматизации тестирования также необходимо настроить для каждой платформы.

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

Разработка и отладка

Одна из проблем в нашем опыте заключалась в том, что код React Native по-разному ведет себя в режиме отладки и в обычном режиме из-за того, что React Native использует разные движки JavaScript для каждого из этих двух режимов. Когда ошибка связана с обычным режимом, ее, естественно, трудно отладить, поскольку в режиме отладки ее невозможно воспроизвести.

Заключение

В React Native есть отличные вещи. Определяющей особенностью React Native и, возможно, его лучшим преимуществом является кроссплатформенность, позволяющая одновременно разрабатывать на iOS и Android одной и той же командой, что может сократить затраты на рабочую силу примерно вдвое. Говоря о команде, разработчиков JavaScript предостаточно, а требуемые навыки работы с мобильными устройствами минимальны, а это означает, что легко доступна квалифицированная рабочая сила. Первоначальная разработка, а также разработка дополнительных функций происходит очень быстро, и поэтому вы можете удовлетворить потребности своих клиентов быстрее, чем ваши конкуренты. В качестве вишенки на торте, приложения, написанные на React Native, в целом, имеют сравнимую или даже потенциально лучшую производительность по сравнению с приложениями, написанными как собственные приложения.

Хотя у React Native действительно есть несколько фантастических преимуществ, есть также несколько вещей, которые вам нужно помнить, прежде чем начинать проект с React Native. Во-первых, хотя React Native хорошо справляется с преодолением разрыва между iOS и Android, вы не добьетесь полного равенства между двумя операционными системами. Есть определенные вещи, которые одна платформа может делать, но с которыми другая не справляется, в основном связанные со стилизацией представлений, но также и с более важными аспектами, такими как тестирование производительности. В то время как сообщество с открытым исходным кодом прекрасно относится к разработке и выпуску новых функций и настроек производительности, на самом деле обновление вашей версии React Native, как правило, вызывает огромную боль, особенно если у вас есть платформа, построенная на React Native, как это делаем мы в Walmart.

Мы твердо верим, что React Native - фантастический фреймворк. Он сделал все, что мы от него хотели, и сделал это превосходно. Хотя у него есть несколько проблем, они затмеваются массой преимуществ, которые вы получаете от его использования. Если вы собираетесь заняться новым мобильным проектом, от стартапов до компаний из списка Fortune 500, подумайте об использовании React Native - мы знаем, что вы не пожалеете об этом.

Кредиты

Эта статья была написана совместными усилиями инженеров команды React Native в WalmartLabs - Мэтта Бреснана, М.К. Сафи, Санкет Патель и Кеерти.