[Перевод] Болевые точки в React Native, которые окупились для меня

внешний интерфейс Программа перевода самородков iOS React Native

Мысли после использования React Native в проектах уровня предприятия любого размера

React Native существует уже некоторое время. Когда он был выпущен для Android (примерно через год после iOS), я использовал его для разработки на профессиональном уровне и решил потратить время на кроссплатформенную разработку на RN. Когда я открыл для себя React Native, я уже шесть лет занимался разработкой для iOS, а не только разработчиком для Mac OS X.

Я разработал четыре проекта среднего размера (от 10 000 до 20 000 строк кода, не считая зависимостей) для своих клиентов в App Store и Play Store. Я также курировал и участвовал в большом проекте с более чем 50 000 строк кода, написанного на React Native (в дополнение к нативному коду), который теперь работает и работает без сбоев. Я накопил достаточно опыта, чтобы понять, в чем преимущество React (и React Native) и как устранить его недостатки.

Примечание. Я знаю, что некоторые из вас упомянули при чтении этогоFlutter. Но так как он далеко не такой зрелый, как его конкуренты, я еще не вникал в него.

На момент написания этой статьи текущая стабильная версия React Native — 0,57, что приближается к 0,58RC.

Это моя идея:

Самые известные функции React Native не самые важные

Наиболее известной особенностью React Native является то, что он кроссплатформенный, но мое внимание он привлек не этим. Наиболее важные функции React Native:Он использует React, который позволяет использовать общие декларативные макеты.. Кроссплатформенная поддержка стоит на втором месте по важности. Как разработчик iOS, я экспериментировал с системами Auto Layout, которые являются менее интуитивными способами проектирования пользовательских интерфейсов.

Если ваша система очень динамична и элементы на экране зависят друг от друга (например, некоторые боковые панели и анимация), то использование Apple Autolayout — лучший способ управления содержимым на экране. Однако это не относится к большинству приложений для Android и iOS. В большинстве приложений для Android и iOS используются стандартные элементы, которые мы часто видим: текст, кнопки, списки, общие представления и изображения, и они расположены в наиболее веб-подобном стиле.

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

  • YogaИли какой-то производный фреймворк, зависящий от него: Android (Java или Kotlin)Lithoи для iOS (Объектив С++)ComponentKit.
  • TextureKit(ранее AsyncDisplayKit)
  • LayoutKit от LinkedIn(не флексбокс, но аналогичный)

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

Особенности декларативного пользовательского интерфейса:

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

Вот некоторые из проблем мобильной разработки, которые решает декларативный пользовательский интерфейс:

составной. iOS использует ViewController внутри ViewController или представления внутри представлений, в то время как Android использует фрагменты. Оба имеют объявления интерфейса XML, и оба позволяют создавать экземпляры и редактировать представления во время выполнения. Когда дело доходит до разбиения их на более мелкие модули или повторного использования, вы делаете небольшой рефакторинг. В декларативном пользовательском интерфейсе вы можете повторно использовать модули или компоненты в любое время.

продуктивность разработчиков. Декларативный пользовательский интерфейс позаботится о размерах компонентов за вас. Взгляните на этот код (пример React Native):

class TestTextLabel extends React.Component {
  render() {
    return (
      <view>
        <text>This is a small text</text>
        <text>{this}</text>
      </view>
    );
  }
}

Приведенный выше код отображает компонент только с двумя текстовыми компонентами. Уведомлениеthis.props.sampleText, что произойдет, если эта переменная слишком длинная (скажем, 10000 символов или около того)? В результате размер компонента изменится, чтобы он соответствовал всему тексту. Если текст достигает предела доступного пространства (скажем, размера экрана), то представление будет обрезано, и пользователь не сможет увидеть весь текст, вам нужен вид прокрутки.

class TestTextLabel extends React.Component {
  render() {
    return (
      <ScrollView style={{flex : 1}}>
        <Text>This is a small text</Text>
        <Text>{this}</Text>
      </ScrollView>
    );
  }
}

Единственное, что изменилось, это добавление<ScrollView>элемент, который потребует дополнительной работы на iOS.

Совместная работа — удобный опыт работы с Git. Я вижу, что каждый декларативный интерфейс может быть лучше.

В iOS и Android, если у вас большой монолитный пользовательский интерфейс, вы делаете это неправильно. Однако в большинстве случаев большие XML-файлы неизбежны (обратите внимание на iOS: XIB на самом деле являются XML-файлами). Их изменения ничего не значат для рецензента кода (или для вас), если вы не согласны с предыдущей версией (вашими изменениями или другими разработчиками).всеЕсли зарезервировано, практически невозможно инициировать запрос на слияние.

С React и другими декларативными библиотеками пользовательского интерфейса эти проблемы в значительной степени сведены к минимуму, потому что макет — это фактический код, который вы можете обновлять, удалять, объединять, сравнивать и делать все то, что вы обычно делаете с другим программным обеспечением.

Самое главное - знать, что такое "производительность" на самом деле

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

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

В то же время повторный рендеринг компонентов вашего приложения в React Native становится дорогим. Поскольку React Native по существу использует мосты, выrender()Любые инструкции, представленные внутри функции, будут переданы из JavascriptCore в Java или Objective C++. Родная сторона получитrender()Задайте теги JSX и преобразуйте их в их нативные аналоги, такие как представления, метки и изображения. Если преобразование происходит сотни раз в секунду, оно занимает существенное время процессора.

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

Одним из таких примеров является большой набор данных (и список). При наличии больших представлений списка и сетки и Android, и iOS предлагают отличное и чрезвычайно гибкое решение — повторное использование представлений. Представьте себе, что при использовании представления большого списка (будь то iOS или Android) отображаются только те ячейки, которые отображаются в любой момент времени. Другие ячейки помечены как повторно используемые, чтобы их можно было использовать повторно, когда будут отображаться новые ячейки. При изменении набора данных ОС требуется только обновить отображаемые ячейки.

React Native предоставляет VirtualizedList и его производные (FlatList и SectionList) для больших наборов данных. Однако даже это оставляет желать лучшего. Это снижает производительность, особенно при рендеринге сложных компонентов в SectionList и попытке обновить большие наборы данных, содержащие более сотни объектов. Механизм обновления может замедлить работу мобильных устройств низкого или среднего класса.

Чтобы исправить это, я переключился с Redux на MobX, который обеспечивает более предсказуемые обновления для моих компонентов. Кроме того, в случае больших списков MobX может обновлять определенные ячейки без повторного рендеринга всего списка. Обычно это также возможно с Redux, но вам нужно переопределитьcomponentShouldUpdate()метод и напишите больше шаблонов, чтобы избежать ненужных повторных рендеров. Ваш редуктор по-прежнему будет выполнять ненужную работу, копируя остальные переменные в новое состояние.

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

Важно понимать среду выполнения JS и то, как она влияет на вас.

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

React Native на Android и iOS использует JavascriptCore для выполнения Javascript. Однако инструменты отладки работают на V8 (Chrome). Чтобы сделать систему более универсально применимой, на момент написания React Native использовал Javascript Core от Apple на iOS, а на Android они использовалиJS Core выпускается уже три годадля создания сценария (поскольку Android не предоставляет JS-среды выполнения, такой как iOS, из коробки, Facebook должен создать ее самостоятельно). Это приводит к отсутствию многих новых функций JS, таких как прокси-объекты, которые поддерживаются только в 64-разрядных версиях Android и iOS. Итак, если вы хотите использоватьMobX 5+, то вы должны использовать обновленную среду выполнения Javascript (читайте дальше, чтобы узнать, как это сделать).

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

Например, когда речь идет о React Native, лучшим решением для мобильной базы данных является Realm. Однако при входе в режим отладки происходит следующее:GitHub.com/realm/realm…. Хотя разработчики Realm объяснилипочему это, но самое главное, если мы хотим более стабильное решение для отладки, необходимо улучшить архитектуру отладки React Native. Хорошая новость заключается в том, что я используюHaulВ качестве моего пакета он позволяет мне выполнять отладку непосредственно с моего устройства iOS, не используя Chrome Dev Tools (к сожалению, вам нужен Mac, iOS Simulator и Safari).

Обратите внимание, что эта проблема была обнаружена людьми из Facebook, которые переделывают ядро ​​React Native, чтобы нативная и React Native части могли совместно использовать одну и ту же память. Как только это будет сделано, можно будет выполнять отладку непосредственно в среде выполнения JavaScript устройства. (См. статью:React Native Fabric (UI-Layer Re-architecture))

Мало того, сообщество React NativeТеперь доступны сценарии сборки JS для Android., который может создавать сценарии, ориентированные на более новые версии JavascriptCore, и встраивать их в приложения React Native. Это сводит возможности Javascript React Native на Android наравне с iOS, а также создает основу для добавления 64-разрядной поддержки React Native, работающей на Android.

Навигация в приложении с React Native выглядит великолепно

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

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

React Native — это не серебряная пуля (панацея)

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

  • контент-ориентированные приложения
  • Приложения с веб-интерфейсом
  • Кроссплатформенные приложения, которые могут требовать или не требовать быстрого выхода на рынок

Вот некоторые категории приложений, которые не очень хорошо работают для RN:

  • Приложения с огромными списками
  • Медиа-приложения, не требующие компоновки (например, простые/мини-игры, анимация, программы обработки видео) или переходы между экранами.
  • Задачи, интенсивно использующие процессор

Действительно, для вещей, которые React не может сделать, вы можете написать все, что вам нужно, на нативе, а затем вызвать соответствующий код из React Native. Но это означает, что вам нужно написать код один раз для каждой платформы (iOS, Android), а затем написать дополнительный код для интерфейса Javascript.

Внутренние компоненты React Native в настоящее время подвергаются серьезному рефакторингу, чтобы позволить RN выполнять больше синхронных операций параллельно, чтобы он мог использовать общий код с нативным:Facebook.GitHub.IO/реагировать-Nat IV…. Итак, перед этим вы должны провести некоторое исследование, прежде чем решить, использовать его или нет.

В заключение

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

Тем не менее, он также попадает в другую странную категорию: иногда вам нужна только одна команда для разработки вашего приложения, а иногда вам нужны три! В какой-то момент вам понадобятся некоторые разработчики iOS и Android для создания компонентов, которые React Native не поставляется по умолчанию. Как только ваша команда начнет расти, вам нужно будет решить, делать ли ваше приложение на 100 % нативным. Итак, выберете ли вы React Native для своего следующего проекта, зависит от того, сколько у вас нативного кода (Java, Kotlin, Swift, ObjC).

Мой личный совет: если вы понимаете, что вам нужно три команды для разработки трех разных уровней приложения (команда iOS, команда Android и команда React), то вы должны быть в состоянии придерживаться нативных iOS и Android и отказаться от Реагировать нативно. Вы сэкономите время и деньги, поддерживая только две базы кода вместо разработки трех.

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

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


Программа перевода самородковэто сообщество, которое переводит высококачественные технические статьи из Интернета сНаггетсДелитесь статьями на английском языке на . Охват контентаAndroid,iOS,внешний интерфейс,задняя часть,блокчейн,товар,дизайн,искусственный интеллектЕсли вы хотите видеть более качественные переводы, пожалуйста, продолжайте обращать вниманиеПрограмма перевода самородков,официальный Вейбо,Знай колонку.