Дуэль: React Native против Cordova

Опубликовано: 2022-03-11

В результате того, что смартфоны и мобильные приложения стали настолько популярными, веб-разработчики стали искать способы создания мобильных приложений с использованием JavaScript. Эта популярность привела к разработке многих фреймворков JavaScript, способных запускать нативные приложения на мобильных устройствах. В настоящее время Cordova и React Native являются наиболее популярными вариантами. Cordova поддерживает мобильные платформы iOS, Android и Windows Phone. С другой стороны, с React Native Android, iOS и UWP являются целями для разработчиков. (UWP означает Universal Windows Platform, платформу Microsoft, которая позволяет запускать одно и то же приложение на Windows Phone 10 Mobile, XBox One и Windows 10.)

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

Различия в философии

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

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

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

Свобода развития

На мобильных устройствах Cordova запускает одностраничное приложение внутри встроенного мобильного веб-браузера, называемого WebView, а затем оборачивает его как собственное приложение. Хотя снаружи это выглядит как нативное приложение, наш веб-код работает внутри движка мобильного браузера. Для нас это означает, что мы не привязаны к конкретной библиотеке или фреймворку. Если мы используем ванильный JavaScript, jQuery, Angular или что-то еще, любой из этих вариантов может быть объединен в мобильное приложение с Cordova. Cordova не навязывает наш стек технологий. Пока у нас есть файл index.html , все готово. Одним из простых примеров может быть следующий фрагмент кода:

 <html> <head> <title>My Cordova App</title> </head> <body> <div>Tap me</div> <script> // Select our element var element = document.getElementById('tapme'); // Send an alert once it was tapped/clicked element.addEventListener('click', function() { alert('Hello there!'); }); </script> </body> </html>

Этот пример означает, что мы можем использовать практически все, что пожелаем, например, с помощью менеджера пакетов, такого как NPM или Bower, с помощью транспилятора, такого как Babel, CoffeeScript или TypeScript, сборщика, такого как Webpack или Rollup, или чего-то еще. Это не имеет значения, если результатом является файл index.html , который загружает все необходимые нам JavaScript и таблицы стилей.

React Native, как следует из названия, основан на React. Важно понимать, что часть React в React Native является одной из его основных функций. Если вы не являетесь поклонником декларативной природы React, включая JSX, его компонентизацию и поток данных, скорее всего, вам не понравится React Native. Хотя React Native сразу кажется разработчикам React знакомым, на первый взгляд, есть некоторые отличия, о которых следует помнить. С React Native у нас нет ни HTML, ни CSS. Вместо этого эта технология ориентирована на сторону JavaScript. В качестве альтернативы CSS стили записываются встроенными, а Flexbox является моделью стилей по умолчанию.

Самое простое приложение React Native будет выглядеть примерно так:

 // Import the React module for JSX conversion import { React } from 'react'; // Import React Native's components import { View, Text, AppRegistry, TouchableOpacity, } from 'react-native'; // Create an App component const App = () => { // Define our press handler const onPress = () => alert('Hello there!'); // Compose the components we are going to render return ( <View> <TouchableOpacity onPress={onPress} /> <Text>Tap me!</Text> </TouchableOpacity> </View> ); }; // Registers the `App` component as our main entry point AppRegistry.registerComponent('App', () => App);

У React Native есть собственный упаковщик. Он объединяет все файлы JavaScript в один гигантский файл, который затем используется и выполняется JavaScriptCore, механизмом JavaScript от Apple. JavaScriptCore используется на iOS и Android, а ChakraCore поддерживает приложения React Native UWP. По умолчанию React Native использует транспилятор JavaScript Babel, что позволяет нам использовать синтаксис ECMAScript 2015+ (ECMAScript 6). Хотя нет необходимости использовать синтаксис ECMAScript 2015+, это определенно рекомендуется, так как все официальные примеры и сторонние модули охватывают его. Поскольку React Native берет на себя процесс упаковки и транспиляции, наш код приложения и сторонние модули могут использовать преимущества этих функций без необходимости настраивать инструменты для себя.

Подводя итог, можно сказать, что React Native — это самоуверенный подход к мобильной разработке, ориентированный на React, а Cordova позволяет нам объединять веб-технологии внутри оболочки WebView.

Родной внешний вид

Одна вещь, которая важна для пользователей, — это иметь родной внешний вид приложения. Поскольку приложения Cordova обычно представляют собой простые веб-приложения, есть несколько вещей, которые поначалу могут показаться странными. Проблемы могут варьироваться от отсутствия визуальной обратной связи в областях касания до прокрутки, которая не кажется такой гладкой, как в нативных приложениях, до 300-миллисекундной задержки событий касания. Хотя есть решения для всех этих проблем, мы должны помнить, что нам может потребоваться приложить дополнительные усилия, если мы хотим, чтобы наше приложение Cordova было как можно ближе к родным приложениям. В Кордове у нас нет доступа к каким-либо встроенным элементам управления. Если мы хотим иметь собственный внешний вид, у нас остается два варианта: либо воссоздать собственные элементы управления, такие как кнопки и элементы ввода, с помощью HTML и CSS, либо реализовать собственные модули, которые напрямую обращаются к этим собственным элементам управления. Мы могли бы сделать это самостоятельно или с помощью сторонней библиотеки, такой как Ionic или Onsen UI. Обратите внимание, что важно поддерживать их в актуальном состоянии с обновлениями ОС по мере их появления. Иногда внешний вид мобильной операционной системы преображается, как это произошло, когда была представлена ​​iOS 7. Наличие приложения, которое оно не может адаптировать, лишит пользователей опыта. Мы также могли бы прибегнуть к плагинам Cordova, которые связывают нас с нативной стороной вещей. Одним из наиболее полных собственных элементов управления является библиотека Microsoft Ace.

С другой стороны, с React Native у нас есть доступ к встроенным элементам управления и взаимодействию из коробки. Такие компоненты, как Text , TextInput или Slider , сопоставляются со своими нативными аналогами. Хотя некоторые компоненты доступны для всех платформ, другие компоненты работают только на определенных платформах. Чем ближе мы хотим, чтобы наше приложение имело нативный внешний вид, тем больше нам нужно использовать компоненты, доступные только для этой конкретной платформы, и тем больше расходится наша кодовая база. Взаимодействие разума и жесты также являются частью React Native.

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

Поскольку в распоряжении Cordova есть только WebView, мы связаны ограничениями WebView. Например, после версии 4.0 Android, наконец, начал использовать (намного более быстрый) движок Chrome в качестве WebView по умолчанию. В то время как с iOS долгое время приложение, работающее внутри механизма WebView по умолчанию, было значительно медленнее, чем то же приложение в мобильном браузере Safari. Кроме того, поскольку JavaScript является однопоточным, мы можем столкнуться с проблемами, если в коде нашего приложения происходит слишком много вещей. Эти ограничения приводят к медленным анимациям, и наше приложение может ощущаться не так быстро, как хотелось бы. Хотя могут быть некоторые приемы, которые мы можем использовать здесь и там, в конце концов, мы связаны ограничениями мобильного браузера.

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

Рабочий процесс разработчика

Cordova предлагает утилиту командной строки для создания новых шаблонов проектов, запуска приложения в симуляторе и создания приложения для реального устройства в рабочем режиме. Большую часть времени мы разрабатываем приложение в настольном браузере, а позже можем объединить его в мобильное приложение. Со свободой, которую предлагает Cordova, нам нужно самим заняться рабочим процессом разработки. Если мы хотим живую перезагрузку на устройстве, нам нужно реализовать ее самим. Для отладки приложений Cordova мы применяем те же принципы, что и для отладки веб-сайта. Например, в iOS мы подключаем наше мобильное устройство через USB, открываем Safari и его инструменты разработчика.

React Native предлагает аналогичный интерфейс командной строки и предлагает рабочий процесс разработки, знакомый веб-разработчикам. Мы получаем живую перезагрузку из коробки. Как только мы изменяем компонент React, наше приложение перезагружается с внесенными нами изменениями. Одной из самых интересных функций является горячая замена модуля, которая частично перезагружает изменения в компоненте, который мы сделали, не изменяя состояние приложения. Мы могли бы даже подключиться к реальному устройству и посмотреть, работают ли наши изменения так, как мы ожидаем, на реальном устройстве. Наши приложения React Native можно отлаживать удаленно с помощью Chrome для ПК. Обработка ошибок очевидна в React Native; если мы сталкиваемся с ошибкой, наше приложение отображает красный фон и показывается трассировка стека. Благодаря исходным картам мы можем увидеть точное местоположение ошибки. Когда мы нажимаем на него, наш выбранный редактор открывается в точном месте кода.

Расширяемость и доступ к собственным функциям

Что касается JavaScript, мы можем использовать любую библиотеку JavaScript, включая пакеты из NPM. Однако, поскольку React Native не является средой браузера, нам может быть сложно использовать код, основанный на DOM. React Native поддерживает модули CommonJS и ES2015, поэтому любые библиотеки, использующие эти форматы, легко интегрируются.

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

Если бы мы гипотетически написали плагин Cordova для iOS на языке Objective-C, это могло бы выглядеть как следующий фрагмент кода. Наш плагин просто зарегистрирует входной параметр.

 #import <Cordova/CDVPlugin.h> // Create a class that inherits from CDVPlugin @interface Log : CDVPlugin - (void)log:(CDVInvokedUrlCommand*)command; @end // The actual implementation of the class we just defined @implementation Log - (void)log:(CDVInvokedUrlCommand*)command { CDVPluginResult* pluginResult = nil; // We are getting all parameters and taking the first one NSString* echo = [command.arguments objectAtIndex:0]; // We are checking for the validity of the parameters if (echo != nil && [echo length] > 0) { // We are just printing the parameter using the native log method NSLog(echo); // Let's create a result for the plugin pluginResult = [CDVPluginResult resultWithStatus:CDVCommandStatus_OK messageAsString:echo]; } // Let's send a signal back with the plugin's result [self.commandDelegate sendPluginResult:pluginResult callbackId:command.callbackId]; } @end

Чтобы использовать модуль, этот фрагмент кода JavaScript поможет:

 window.log = function(str, callback) { cordova.exec(callback, function(err) { callback('Nothing to echo.'); }, "Log", "log", [str]); };

Чтобы использовать плагин, нам просто нужно вызвать функцию log :

 window.log('Hello native!');

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

 #import "RCTBridgeModule.h" @interface Log : NSObject <RCTBridgeModule> @end @implementation Log RCT_EXPORT_MODULE(); // This makes this method available NativeModules.Log.log RCT_EXPORT_METHOD(log:(NSString *)message) { NSLog(message); } @end

React Native связывает модуль для нас вызовами RCT_EXPORT_MODULE и RCT_EXPORT_METHOD . Теперь мы можем получить к нему доступ с помощью NativeModules.Log.log следующим образом:

 import { React } from 'react'; import { View, Text, AppRegistry, NativeModules TouchableOpacity, } from 'react-native'; // Create an App component const App = () => { // Log with our module once we tap the text const onPress = () => NativeModules.Log.log('Hello there'); return ( <View> <TouchableOpacity onPress={onPress} /> <Text>Tap me!</Text> </TouchableOpacity> </View> ); }; // Registers the `App` component as our main entry point AppRegistry.registerComponent('App', () => App);

Хотя мы только внимательно рассмотрели создание модуля в iOS с использованием Objective-C, те же принципы применимы и к созданию модуля для Android с использованием Java.

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

Вывод: React Native или Cordova?

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

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

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

Связанный: Холодное погружение в React Native: учебник для начинающих