Не секрет, что Capacitor и React Native конкурируют в экосистеме разработки кроссплатформенных приложений. Мы в студии AppTor активно применяем кроссплатформенный подход для разработки приложений и в равной мере используем Capacitor и React Native.
Быстрый поиск в Интернете покажет вам бесчисленные статьи, сравнивающие эти два кроссплатформенных решения. В этих статьях сторонники React Native часто склоняются к производительности как к самой большой причине выбора одной платформы по сравнению с другой. Они полагают, что поскольку React Native организует нативные элементы управления через пользовательский интерфейс (в отличие от рендеринга пользовательского интерфейса в браузере, как в Capacitor), то она должна быть быстрее.
В чем же загвоздка? Ни одно из этих объяснений никак не связано с реальными показателями производительности. Скорее, авторы опираются на мнение, что React Native "более нативный", и поэтому у него лучше производительность.
Но правда ли то, что React Native имеет самую высокую производительность? Мы решили создать два приложения с одинаковым набором функций и провести несколько собственных тестов на одном и том же iPhone 11. Давайте посмотрим, что из этого вышло.
Во-первых, если вы только начинаете знакомиться с Capacitor или React Native, давайте вкратце расскажем, чем они отличаются друг от друга в плане подхода и лежащей в основе архитектуры.
Capacitor полностью придерживается философии использования веб-технологий для создания своих приложений. React Native, с другой стороны, также работает на JavaScript (JS), но делает это под видом реализации специфических для платформы элементов управления через пользовательский интерфейс (UI). Обе платформы создают настоящие нативные приложения с полным нативным доступом через плагины и пользовательский нативный код.
Время, которое требуется приложению для загрузки, является самым частым показателем для измерения оценки производительности.
Время загрузки бывает двух видов:
Время холодной загрузки измеряется, когда операционная система полностью перезагружается, где исключено кэширование данных приложений. И наоборот, время теплой загрузки измеряется, когда приложение было просто закрыто, то есть оно больше не работает в фоновом режиме, но в операционной системе может оставаться некоторый кэш.
Время холодной загрузки и для React Native, и для Capacitor составило около 1,5 секунды, а время теплой загрузки - около 1 секунды. Посмотрите на время загрузки Capacitor и React Native в сравнении:
Сторонники React Native утверждают, что время загрузки React Native значительно быстрее по сравнению с Capacitor. На самом деле это не так. На видео показано, что приложения загружаются практически с одинаковой скоростью. Если вы заметили, что у React Native есть совсем небольшое преимущество, то оно далеко не настолько существенное, чтобы списать Capacitor со счетов. React Native быстр, но и Capacitor не менее быстр!
Второй главный аргумент, похоже, также связан с представлением о том, что приложения Web Native по своей природе медленнее в рендеринге. Следующий видеоролик говорит сам за себя:
Принято считать, что 60 кадров в секунду (fps) — это скорость, при которой анимация выглядит плавной. В приведенном выше видео вы можете увидеть все своими глазами. При выполнении рендеринга во время прокрутки как приложение Capacitor, так и приложение React Native выполнили задачу примерно за 16,67 миллисекунды или чуть меньше. Это доказывает, что пользователь никогда и ни за что не столкнется с "падением кадров".
Capacitor React FPS (кадров в секунду)
React Native FPS (кадров в секунду)
Вы однозначно не столкнетесь с какими-то проблемами в производительности при работе с веб-приложениями. Веб-экосистема в целом работает быстро, так же, как и приложения Web Native. Конечно, приложения React Native не менее быстры. В видеоролике показано, как загружается список из 2500 сотрудников. Благодаря оптимизированному коду и алгоритмам, применяемых в каждом приложении, списки листаются без задержек. Элементы загружаются легко и плавно. Так что самое время сказать, что данный показатель также не является объективным при выборе фаворита. Обе экосистемы работают невероятно хорошо.
Еще одно опасение, связанное с приложениями Web Native, заключается в том, что, учитывая веб-ориентированный подход, приложения потеряют ощущение естественности и плавности, когда речь идет о перемещении пользователя внутри пунктов приложения. Простым примером может служить анимация "пушей" и "попапов", возникающая при переходе пользователя в меню, подменю и обратно.
Это очень неточное утверждение. Использование специальных UI библиотек, в которых полностью реализованы все элементы и анимации нативных элементов, позволяет сделать приложение визуально (UI) и по пользовательскому опыту (UX) нативным. Взгляните:
В настоящее время люди еще не определились, должны ли мобильные приложения иметь одинаковый стиль во всех операционных системах или нет. Многие придерживаются идеи, что стилизация под конкретную платформу, с которой мы все знакомы, по-прежнему является стандартом. Другие склоняются к концепции, что приложение должно быть стандартизированным и выглядеть одинаково независимо от операционной системы, на которой оно используется.
Независимо от того, к какой точке зрения вы склоняетесь, с использованием Capacitor это не сложно реализовать. Адаптивная стилизация, поставляемая вместе с набором инструментов пользовательского интерфейса UI библиотеки (например Framework7), позаботится о том, чтобы ваши компоненты выглядели точно так же как и те, которые написаны под определенную операционную систему. Ваше приложение автоматически адаптируется под Material Design от Android и Cupertino Design от Apple, в зависимости от того, на какой платформе приложение запускается. Все это поставляется в комплекте и не требует настройки. Однако если вы предпочитаете, чтобы компоненты вашего приложения выглядели одинаково, независимо от операционной системы, открытые CSS-переменные позволят вам отменить авто стилизацию и создать особый стиль вашего продукта!
Сторонники React Native придерживаются идеи, что использование родных компонентов пользовательского интерфейса — это единственный способ добиться действительно оригинального внешнего вида и естественного ощущения. Проверить это очень просто. Посмотрите видео выше, и обратите внимание на то, что без подсказки вы вряд ли сможете определить, был ли продукт создан с помощью Capacitor или React Native.
Одной из самых больших инноваций в JavaScript за последние 15 лет стал компилятор для JavaScript под названием "Just-in-time" (JIT), это перевод интерпретируемого JavaScript в родной машинный код во время выполнения, что значительно повышает производительность и энергопотребление во время работы. Известно, что движок V8, на котором работает Chrome, и движок Nitro, на котором работает Safari, перенесли JavaScript в совершенно новые категории приложений, которые изменили представление о том, на что способны браузеры и веб-приложения.
Однако, поскольку JIT-компиляция требует генерации и выполнения собственного кода во время выполнения, она создает проблемы с безопасностью. Чтобы смягчить эти проблемы, производители разрешают JIT-компиляцию только для JavaScript, работающего в среде браузера в Sandbox. На мобильных устройствах, к примеру, код JavaScript имеет доступ к механизму JIT только при выполнении в режиме Web View, таком как WKWebView. Это означает, что приложения Capacitor всегда запускаются с JIT-движком. Приложения, использующие JavaScriptCore или Hermes, такие как React Native, не имеют доступа к JIT-движку.
Это одно из самых значительных различий в производительности между Capacitor и React Native. Движки, не использующие JIT-компиляцию, имеют значительно более низкую производительность при выполнении JavaScript. Это доказывают общедоступные бенчамрки, например, результаты QuickJS Benchmark. Как видно из этих данных, отсутствие JIT-компиляции приводит к значительному замедлению выполнения JavaScript и значительному увеличению потребления энергии, что продемонстрировано в этой статье далее.
Если рассмотреть производительность под другим углом, мы можем оценить потребления ресурсов процессором для обоих мобильных приложений. При этом обнаруживаются очень интересные детали. Взгляните на следующие скриншоты, сделанные во время работы обоих приложений из Xcode и во время пролистывания списка сотрудников:
Потребление ресурсов процессором при работе Capacitor
Потребление ресурсов процессором при работе React Native
Из этих изображений видно, что приложение Capacitor гораздо менее требовательно к процессору, чем приложение React Native. При максимальной нагрузке приложение React Native использовало почти 200% ресурсов процессора, а Capacitor - всего 10%. Причина этого в том, что гибридные приложения Capacitor имеют доступ к вышеупомянутому более быстрому JS-движку в WKWebView, в сравнение с теми гибридными приложениями, которые используют JavaScriptCore, например, созданные с помощью React Native. Со стороны кажется, что эти приложения работают отлично, но в случае с React Native ваше устройство вынуждено работать намного интенсивнее.
Учитывая показатели потребления ресурсов процессором, мы видим, что приложение React Native оказывает гораздо большую нагрузку на устройство, чем приложение Capacitor.
Потребление энергии Capacitor
Потребление энергии React Native
При повторном пролистывании списков, Capacitor опустился в диапазон высокого потребления энергии, а React Native поднялся еще выше - в диапазон очень высокого потребления. Очень важно взглянуть на эти диапазоны, когда приложения находятся в активной работе, поскольку пользователи гораздо реже взаимодействуют приложением, не выполняя при этом никаких действий. Если энергопотребление вашего приложения будет очень высоким в течение всего времени его использования, оно будет сильно разряжать батарею устройства. Судя по тому, что вы видите на экране, приложение Capacitor будет оказывать меньшее влияние на общее время автономной работы вашего устройства.
React Native - это отличная платформа, с помощью которой можно создавать поистине невероятные приложения. Но "миф" о том, что React Native обеспечивает лучшую производительность — это всего лишь миф. Мы привели достаточно примеров, чтобы доказать это. Приложения на Capacitor на столько же быстры и производительны, а выглядят и ощущаются так же, как и нативные приложения.
Какое же наше мнение? Нет смысла использовать "производительность" в качестве главного аспекта при выборе экосистемы, потому что оба варианта позволят вам получить высокопроизводительные приложения с действительно нативным внешним видом и ощущением плавности. Вместо этого, поэкспериментируйте с каждой платформой и выберите ту, которая лучше всего подходит для вас, с которой проще и интереснее работать.
В любом случае, вы можете быть спокойны, зная, что какой бы вариант вы ни выбрали, то, как ваше приложение покажет себя, будет в большей степени связано с достоинствами вашей идеи и тем, насколько хорошо вы их реализуете. И в меньшей степени это будет связано с выбранным вами инструментом.