React Native e Xamarin

Pedro Jesus
11 min readFeb 5, 2019

--

Já perdi a conta de quantas discussões técnicas já entrei para comparar essas duas tecnologias de desenvolvimento e responder a pergunta “React Native é nativo? Não, o React Native só é nativo no nome”. E para facilitar o meu lado e não ter que ficar repetindo a mesma coisa em todo debate, resolvi escrever este artigo. Lembrando que todos os dados citados aqui não foram tirados da cartola e podem ficar “relax” que as fontes estarão disponíveis para vocês também, através de hiperlinks.

Antes de mais nada, deixo claro que serei o mais técnico possível, ou seja, nada de falar que “ah eu gosto da tecnologia X por isso ela é a melhor”. E espero que nos comentários vocês também sejam o mais técnico possível, porque só pelo fato de você gostar/amar uma tecnologia não quer dizer que ela seja a melhor do mercado ;)!

Sempre que eu usar o termo “Nativo” eu me refiro as ferramentas oficiais de cada plataforma, XCode com swift ou objective-c, no caso do iOS. Android Studio, Java ou kotlin, no caso do Android.

A partir de agora tudo que estiver neste formato é comentário pessoal.

O que elas tem em comum?

Essas duas tecnologias são nada mais nada menos, do que uma forma de desenvolver aplicativos móveis* utilizando uma única linguagem de programação.

*Xamarin consegue entregar, não somente, aplicativos móveis como também aplicativos para MacOS, Linux, Windows 10, webAssembly(experimental)

E tanto o React Native(RN) quanto o Xamarin, prometem te entregar uma aplicação nativa! O que é uma grande vantagem, afinal você desenvolve para várias plataformas, compartilhando a maior parte do código e no fim você tem uma aplicação nativa, que consegue aproveitar tudo que o SO tem a oferecer.

Agora vamos falar dessas tecnologias um pouco mais fundo…

React Native (RN)

RN é uma ferramenta criada pelo Facebook e é opensource, utiliza JavaScript(js) como linguagem de programação e utiliza o React como framework para desenhar a Interface de Usuário (UI). Sem dúvida qualquer desenvolvedor web irá se sentir confortável com essa solução, pois não vai precisar aprender uma nova linguagem de programação, basta aplicar os conhecimentos que já possui, acredito que esse seja um dos motivos desta ferramenta ser muito famosa e ter uma aceitação enorme.

Edição de UI no RN. (https://facebook.github.io/react-native/)

Xamarin

O Xamarin, que é nome tanto da ferramenta quanto da empresa que o criou, que posteriormente foi comprada pela Microsoft. Permite criar aplicativos usando o C# como linguagem de desenvolvimento. Ele roda em cima do compilador Mono e possui bindings das bibliotecas nativas de cada plataforma, com isso o desenvolvedor tem acesso a todas as APIs existentes no SO. Um dos slogans do Xamarin é: Se você consegue fazer com java/objective-c você faz com Xamarin.

O Xamarin possui duas abordagens de desenvolvimento, onde você pode utilizar o Xamarin.Android e Xamarin.iOS criando as UIs de forma nativa ou pode usar o Xamarin.Forms e criar as UIs usando o XAML.

Ambiente de desenvolvimento do Xamarin(https://visualstudio.microsoft.com/pt-br/xamarin/?rr=https%3A%2F%2Fduckduckgo.com%2F)

Interface de usuário (UI)

No RN a interface de usuário é construída com o React, ou seja, você utiliza HTML e js para desenhar a tela do seu aplicativo. Então para quem é front-end, nada de novo sob o Sol.

Mas temos um problema… No caso do Android e iOS, nativos, a UI é criada usando XML e StoryBoard, respectivamente, e por isso não é possível você pegar uma tela criada utilizando XML ou StoryBoard e jogar dentro de um projeto RN e consumir diretamente… Ai você pergunta, mas é tem como fazer isso? Sim, é possível, porém exige um grande trabalho braçal pra fazer isso e se fizer algum passo errado, perdeu-se tempo. Caso queira ver como se faz para Android e iOS.

No Xamarin a UI pode ser construída usando XML (Android), StoryBoard(iOS), XAML (UWP e Android/iOS(Xamarin.Forms)), ou até mesmo uma “mistureba” dessas duas abordagens. Em relação ao uso de UIs criadas de forma nativa é muito simples o uso, basta importar interfaces e componentes já existes em código nativo, bastando adicionar esses arquivos aos projetos e no caso do Android, renomear a extensão “.xml” para “.axml” (sem as aspas). Se você estiver trabalhando com o Xamarin.Forms(XF), você também pode fazer uso das interfaces nativas para criar controles personalizados, mas vale lembrar que nem sempre isso é um trabalho fácil.

Com isso podemos ver que aproveitar as UIs de projetos legados ou até mesmo componentes visuais que você já tenha pronto pode ser bem doloroso no RN, sendo a primeira opção buscar na internet por alguém que já tenha seguido o caminho das pedras ou implementar a UI diretamente no RN. Em contrapartida o Xamarin consegue lidar com isso muito bem, uma vez que você não precisar gastar muito tempo migrando as UIs para o Xamarin. Ainda existem desenvolvedores que criam a UI no Android Studio ou XCode e depois exportam pro projeto Xamarin.

Uso de código nativo

Aqui vamos falar sobre a capacidade dessas ferramentas de permitir o uso ao código nativo. Ambas ferramentas permitem isso, porém com algumas diferenças entre si.

No RN, o acesso a código nativo é bem burocrático, o que pode torná-lo impraticável em alguns cenários. Para fazer uso de um código nativo é necessário adicionar algumas linhas código antes. Isso é chamado de “native modules”(módulos nativos, em tradução livre), o exemplo abaixo mostra como isso pode ser feito no iOS, ele foi retirado do artigo da infoQ. O procedimento no Android é semelhante e pode ser encontrado na documentação.

Código em Objective-C
RN consumindo o código escrito no gist acima.

Se você tem acesso ao código fonte, isso não é tão problemático, mas e se estiver usando bibliotecas de terceiros, onde nem sempre se tem acesso ao código fonte? Se o autor dessa biblioteca não se preocupar em adicionar essas linhas de código, infelizmente, não poderá utilizá-la em seu projeto. O quem, por muitas vezes, pode ser desastroso…

No Xamarin, o acesso ao código nativo difere entre as plataformas, então vamos falar separadamente. Mas no geral é menos burocrático que no React Native, pois não é necessário ter acesso ao código fonte. Em ambos casos é utilizado um projeto do tipo Binding Library.

No Android basta adicionar o arquivo compilado, .jar ou .aar , no projeto. Logo em seguida é só compilar e usar a .dll em seus projetos. Claro que nem tudo são flores, algumas bibliotecas mais complexas podem exigir algumas modificações, mas acalme-se, essas modificações são feitas no projeto de Binding utilizando o C# (para modificar o comportamento de alguns métodos ou adicionar funcionalidades a biblioteca) ou usando XML (para modificar o namespace da biblioteca, fazer alterações nos métodos e/ou parâmetros do método).

Ainda é possível adicionar o gradle ao seu Visual Studio e fazer uso dele, para gerenciar as bibliotecas disponíveis para Android. Basta clicar aqui para acessar a extensão. Bem interessante, não?!

No caso do iOS deve-se adicionar o arquivo .a, no projeto e fazer algumas definições, usando atributos. Reforço que não é necessário ter acesso ao código fonte da biblioteca, mas pode ser necessário saber as propriedades e métodos, para fazer o mapeamento corretamente. O que pode ser um pouco chato e até mesmo trabalhoso. Abaixo vemos um exemplo, retirado da documentação, de como é esse mapeamento.

Mapeamento de uma lib em Objective-c para C#.

Para mais detalhes de como fazer esse binding no iOS, você pode acessar esse vídeo tutorial.

Enfim, ambas ferramentas conseguem fazer uso do código nativo, mas obviamente o Xamarin leva uma grande vantagem por não ser necessário fazer alterações dentro do código nativo, mesmo que no iOS exija a escrita de código, esse código é em C#. E em relação ao Android o Xamarin leva uma vantagem ainda maior, principalmente por ser possível utilizar o gradle. É importante salientar que o Xamarin tem acesso a 100% das APIs nativas, enquanto o RN não.

Compilação

Neste capítulo vamos ver um pouco como funciona por baixo do capô em cada uma dessas tecnologias e o que é gerado no final da compilação.

No RN, não é gerado um código nativo, o núcleo do RN serve como uma ponte entre o que é nativo e o javaScript da sua aplicação. Ele inclui uma Máquina Virtual(VM) JS, no Android, no iOS ele utiliza a JavaScriptCore, que já faz parte do sistema.

Em resumo, o RN é o seu código javaScript rodando dentro de uma máquina virtual e lidando com a interface nativa. Cada componente do RN (implementado com React) faz uma chamada para seu respectivo componente nativo. Acredito que os leitores mais sagazes, já devem perceber que isso tem um custo na performance. Este post fala sobre isso mais detalhadamente.

Esquemático sobre funcionamento do RN (https://www.infoq.com/articles/react-native-introduction?fbclid=IwAR2ifRn_eFDzMwJqSOXB7OVfcGU5lHNsHwgtuWQyvhSBVRz5P07U3LMGgX0)

No Xamarin, que roda em cima do compilador Mono, nós conseguimos obter, no final da compilação, um código 100% nativo e que respeita as “exigências” de cada SO. No caso do iOS a exigência é que a compilação seja AOT(Ahead Of Time) e no final seja gerado um arquivo binário. No Android pode ser tanto uma compilação JIT(Just In Time)quanto AOT.

A grosso modo a compilação AOT é mais segura que a JIT, pois como o resultado de saída é um binário que o sistema vai ler, é quase impossível injetar código malicioso para que o programa execute. Para saber mais sobre JIT e AOT clique aqui.

Ainda falando sobre o Mono, temos acesso ao Linker, que é uma ferramenta para reduzir o tamanho do arquivo final, ela tem a função de deletar os códigos e bibliotecas que não utilizamos no projeto, vale lembrar que você ainda pode utilizar o ProGuard, que faz a mesma coisa que o Linker só que na linguagem Java (lembrem-se que o Xamarin faz bindings de código Java e você ainda pode utilizar bibliotecas java no seu projeto). Aqui vc pode ver um pequeno tutorial de como ativar o ProGuard.

Compilação no Xamarin (https://pt.slideshare.net/JamesMontemagno/introduction-to-cross-platform-natitve-mobile-development-with-c-and-xamarin-33930619)

Mas ainda sim, o tamanho final do aplicativo pode ficar um pouco maior, comparado a outros aplicativos nativos, mas não se assuste. O que acontece é que para rodar o aplicativo é necessário anexar o API Support, para que os bindings rodem corretamente.

Com isso podemos ver que o Xamarin respeita a compilação e criação de pacotes de cada plataforma. Em relação ao RN, não consegui achar na documentação maiores informações sobre como é feita a compilação, mas acredito que ele se mantenha em JIT, mesmo no iOS. No caso do Xamarin vocês podem acessar maiores informações sobre a compilação neste link.

Performance

Agora vamos falar, do que para mim é um fator muito importante, tanto como desenvolvedor quanto como usuário. Sei que é comum a máxima “Aplicativos nativos são mais performáticos do que soluções CrossPlataform”, aqui vamos colocar essa máxima a prova… Infelizmente, ainda não há testes, confiáveis, de performance que comparem Xamarin com o RN.

Gostaria de salientar, que fiz uma vasta pesquisa e optei pelas referências mais detalhadas e/ou que possuem uma visibilidade maior na internet. Fazer testes de performance não é uma tarefa trivial. É necessário ter um excelente conhecimento da Linguagem de Programação (LP) que se pretende testar. Por exemplo, para um teste confiável é necessário que o Garbage Collector não rode durante a coleta de dados, caso isso ocorra ele pode fazer com que a medição fique completamente errada. É importante, também, ter certeza de que o código está em modo Release. Então antes de tomar um benchmark como verdadeiro, avalie como ele foi conduzido.

No RN, a perda de performance não é muito grande, pois ele renderiza a UI utilizando componentes nativos. Porém como a parte lógica roda na mesma thread da UI, pode acontecer alguns engasgos (lembram daquela VM, que compila o js e faz a ponte com a parte nativa?). Em um teste feito, comparando o RN, Flutter e nativo, para aplicativos Android, observaram que o RN consome quase o mesmo tanto de memória que uma aplicação nativa, porém consome até 30% mais da CPU.

No iOS, compararam o RN com swift, utilizando um aplicativo de tarefas (ToDo). O RN consome mais memória que o swift, quando se faz necessário o uso de múltiplas tarefas, para todo resto o consumo de memória no RN é ligeiramente menor. Porém o consumo de CPU, por aplicativos feitos em RN são muito elevados, chegando a superar o swift em até 129%. Abaixo é possível ver uma comparação gráfica para o ato de rolar a lista múltiplas vezes.

Comparação entre o consumo de memória, para rolagem de lista(https://www.simform.com/react-native-vs-swift-ios-application-development/)
Comparação entre o consumo de CPU, para rolagem de lista (https://www.simform.com/react-native-vs-swift-ios-application-development/)

No Xamarin, podemos achar uma quantidade maior de testes na internet, acredito que por conta da idade da ferramenta (Xamarin é mais velho que o RN).

As críticas em relação a performance do Xamarin são bem positivas. Um benchmark bem famoso/confiável foi feito pelo Harry Cheung , ex-engenheiro do Google, onde mostra o desempenho do Xamarin em relação a diversos modelos de desenvolvimento de aplicativos.

Para o Android, podemos ver que a performance do Xamarin.Android (não confundir com o XF) é a segunda melhor, ficando a frente até mesmo do Java. Já no iOS o Xamarin.iOS leva o terceiro lugar, ficando atrás do C++ e Swift, porém leva a melhor se comparado ao Objective-C. Abaixo vocês podem conferir os valores no teste.

Comparação entre as diversas ferramentas para desenvolvimento em Android (https://medium.com/@harrycheung/mobile-app-performance-redux-e512be94f976)
Comparação entre as diversas ferramentas para desenvolvimento em iOS (https://medium.com/@harrycheung/mobile-app-performance-redux-e512be94f976)

Infelizmente não consegui achar analises que mostram o consumo de CPU e memória no Xamarin. E nem analises de RN utilizando o tempo de inicialização como unidade de medida.De um modo geral, podemos ver que o Xamarin leva uma boa vantagem sobre o RN, comparando cada um deles com o nativo e não entre si. Claro que isso pode mudar, afinal essas tecnologias estão em constante evolução. Performance é um quesito bem delicado, pois , além da ferramenta,depende, também, da competência do desenvolvedor. E muitas vezes a falta de conhecimento causa resultados desastrosos.

Sempre procurem conhecer sua ferramenta de trabalho a fundo, tanto o framework quanto a linguagem de programação que é utilizada, para conseguir extrair os melhores resultados. O melhor lugar pra isso são as docs, para o React Native e para o Xamarin.Forms, Xamarin.Android, Xamarin.iOS. E essa palestra do Miguel de Icaza sobre aplicativos mobile, também pode ser uma boa referência (para desenvolver aplicativos no geral).

Antes do fim

Antes de apresentar a conclusão, gostaria de propor um exercício a você, testar a qualidade de aplicativos desenvolvidos por essas duas plataformas. É claro, que a qualidade do código influência diretamente no resultado final. Então para isso sugiro que teste os aplicativos desenvolvidos pelas empresas que criam/mantém as ferramentas.

Para o caso do React Native, testem os aplicativos desenvolvidos pelo Facebook, Messenger, Instragram, Facebook… No caso do Xamarin, testem os aplicativo desenvolvidos pela Microsoft, Noticias e do Azure, Pix Camera, Hyperlapse Mobile (nestes dois últimos a microsoft utilizou código C/C++ também).

Nos meus testes como usuário, achei terrível a experiência nos apps desenvolvidos pelo Facebook, são pesados, ocupam muito espaço, necessitam de uma versão lite (vale lembrar que até o Uber, que possui seu aplicativo em RN, lançou uma versão lite). Nos apps em Xamarin a experiência é completamente oposta, aplicativos com tamanho aceitável e leves.

Considerações finais

Por fim, até o presente momento, React Native não me convenceu que é realmente nativo. A infoQ, em seu artigo, escreveu:

One of the first things that surprises people about React Native is that it’s “actually” native” (Uma das primeiras coisas que surpreendem as pessoas sobre o React Native é que ele é “realmente” nativo , em tradução livre).

Já o Xamarin é realmente (sem aspas) nativo. E isso faz toda diferença no resultado final.

Sei que na hora de definir qual tecnologia usar em um projeto, o que mais pesa, pelo que tenho visto nas empresas brasileiras, é a base de conhecimento da equipe contratada e é inegável o fato de JavaScript ser mais popular que C#, afinal o JS é a linguagem de programação da internet. Porém é importante conhecer as ferramentas mais a fundo antes de decidir usá-la.

--

--