Integração de Dependências iOS no LuizaLabs
By: Carlos Henrique, Gabriel Beltrame, Rafael Valer
Intro
Nós aqui do time de plataforma mobile iOS do LuizaLabs, resolvemos publicar um estudo que fizemos internamente com intuito de ajudar a comunidade e informar sobre integração de dependência. Hoje existem diferentes gerenciadores de dependências no mundo iOS, com isso, existe sempre a dúvida de qual poderia nos atender melhor, ser mais performático, mais escalável e etc. Resolvermos então por a mão na massa e levantar essa informação.
Recentemente, realizamos a migração do Buck pelo Tuist. Com isso, estamos buscando aperfeiçoar a performance do projeto durante o build e geração de projeto, o que nos faz ganharmos mais tempo para codar :] .
Um dos pontos impactantes neste processo é a maneira como integramos dependências externas ao projeto. Por este motivo, buscamos realizar alguns testes de outras duas formas bem famosas de integração: Carthage e Swift Package Manager (SPM), e comparar com a maneira hoje utilizada (Cocoapods).
Objetivos dos testes
- Analisar em detalhes os diferentes métodos de integração de dependências no SuperApp e colher resultados a cerca de diferentes aspectos performáticos.
- Auxiliar o time de plataforma mobile iOS na decisão de qual método utilizar para integrar dependências externas ao projeto.
Abordagem
A fim de testarmos os impactos e performance dos diferentes modos de integração de dependências existentes, realizamos testes para observar características relacionadas à compilação do projeto.
Como não foi possível migrar todo o conjunto de dependências externas para os dois gerenciadores de dependências analisados, uma comparação direta entre Carthage vs. SPM não pôde ser feita. Nesse caso, somente análises SPM vs. Cocoapods e Carthage vs. Cocoapods foram realizadas.
*Para cada métrica observada, realizamos N testes de coleta dos dados, o valor de N aparece junto aos resultados obtidos.
Dispositivos Utilizados
Cocoapods vs. SPM vs. Carthage — Aplicação
- Cold Make Project — Geração do projeto após execução de um
clean
. (N=5) - Warm Make Project — Geração do projeto após já ter sido gerado anteriormente. (N=5)
- Cold Indexing — Indexação do projeto após execução de um
clean
. (N=3) - Warm Indexing — Indexação do projeto após já ter sido indexado. (N=7)
- Cold Build — Build do projeto após execução de um
clean
. (N=3) - Warm Build — 1º build do projeto após
start project
e sem ter tido suas dependências apagadas. (N=7) - Incremental Build — Rebuild do projeto após mudança em arquivo. Neste caso editamos um método de um dos módulos. (N=7)
- Os testes foram realizados com as dependências já baixadas.
Análise dos Resultados
- SPM vs Cocoapods:
— Aumento médio no tempo de Cold Make Project em ~61.2% utilizando SPM. Essa alta diferença durante o Cold Make Project se explica pelo fato de o SPM realizar a busca das dependências durante o step de make project.
— Aumento médio no tempo de Warm Make Project em ~5.4% utilizando SPM. - Carthage vs Cocoapods:
— Redução média no tempo de Cold Make Project em ~10.2% utilizando Carthage.
— Redução média no tempo de Warm Make Project em ~10.4% utilizando Carthage.
Indexação do Projeto
Apesar de o tempo de Cold Indexing ter apresentado uma redução média de ~9% ao comparar SPM com Cocoapods, e de ~8.9% ao usar Carthage, os tempos mensurados na máquina Macbook Pro i7 trazem resultados inesperados em relação à esta medida. Testes adicionais devem ser feitos no futuro para tirar conclusões mais assertivas.
Compilação do Projeto
- SPM vs. Cocoapods:
- Redução média no tempo de Cold Build em ~47% utilizando SPM.
- Tempo de Warm Build inconclusivo.
- Tempo de Incremental Build com leve redução de ~5% utilizando SPM. - Carthage vs Cocoapods:
- Redução média no tempo de Cold Build em ~15% utilizando Carthage.
- Redução média no tempo de Warm Build em ~9% utilizando Carthage.
- Redução média no tempo de Incremental Build em ~12% utilizando Carthage.
Testes do Projeto
Fastlane Test:
- SPM aumentou ~2.5%
- Carthage reduziu ~8.7%
Warm Test Build:
- SPM reduziu ~3%
- Carthage reduziu ~12%
Incremental Test Build:
- SPM reduziu ~14%
- Carthage reduziu ~22%
Tempo no CI — Bitrise
Também foi notada uma redução no tempo total de duração dos testes no CI ao usar SPM/Carthage se comparado com Cocoapods.
- SPM: redução de ~3.1%
- Carthage: redução de ~4.6%
Tamanho do App
- Testflight :
- SPM reduziu em ~3.8% o tamanho do ZIP gerado em comparação ao Cocoapods.
- SPM reduziu em ~2.4% o tamanho do app instalado em devices em comparação ao Cocoapods.
- Carthage aumentou em ~6.7% o tamanho do ZIP gerado em comparação ao Cocoapods.
- Carthage aumentou em ~1.6% o tamanho do app instalado em devices em comparação ao Cocoapods.
Conclusões:
Com a substituição ferramental do Buck pelo Tuist para geração do projeto iOS, foi possível realizar este estudo. Seu objetivo principal visa o teste e comparação entre diferentes gerenciadores de dependências e seus distintos aspectos performáticos.
Dentre os principais resultados, podemos destacar:
Geração de Build:
- SPM — Obteve um aumento no tempo de geração do projeto, tanto
cold
comowarm
, ~61.2% e ~5.4%, respectivamente. No entanto, isso pode ser facilmente explicado visto que o SPM realiza busca das dependências durante este step. Além disso, esse tempo pode ser reduzido através do uso da flagdisablePackageVersionLocking
. (Config.swift | Tuist Documentation) - Carthage — Redução no tempo de geração do projeto, tanto
cold
comowarm
, ~10.2% e ~10.4%, respectivamente.
Indexação do Projeto:
- Ambos gerenciadores (SPM e Carthage) apresentaram resultados parciais com redução de cerca de 9% nos tempo de
cold indexing
.
Compilação do Projeto:
- SPM — Apresentou redução nos tempos de
cold build
eincremental build
, ~47% e ~5%, respectivamente. Tempo parawarm build
inconclusivo. - Carthage — Apresentou redução nos tempos de
cold build
,warm build
eincremental build
, ~15%, ~9%, e ~12%, respectivamente.
Testes do Projeto:
- SPM — Reduziu levemente o tempo da lane de testes em ~2.5%. Assim como o tempo de
warm build
dos teste em ~3%, e o debuild incremental
em ~14%. - Carthage — Reduziu o tempo da lane de testes em ~8.7%. Assim como o tempo de
warm build
dos teste em ~12%, e o debuild incremental
em ~22%.
Tempo no CI:
- Ambos gerenciadores (SPM e Carthage) apresentaram uma leve redução no tempo total de duração dos testes no CI, ~3.1% e ~4.6%, respectivamente.
Tamanho do Aplicativo:
- SPM — Redução no temanho do ZIP (~3.8%) e do tamanho do app instalado no device (~2.4%) para Testflight.
- Carthage — Aumentou o tamanho do ZIP (~6.7%) e o tamanho do app instalado no device (~1.6%) para Testflight .
Essa redução no tamanho do binário final ao utilizar SPM também foi reportado em outros experimentos(What Adding Dependencies Will Do To Your App in 2020).
Outras Análises:
- Embora na maioria das medidas extraídas o Carthage tenha superado o SPM, como migramos um maior número de dependências para o Carthage do que para o SPM, essa diferença pode ter sido responsável por uma melhor performance do primeiro. Além disso, para que possamos usar o Carthage, devemos pré compilar as bibliotecas externas e alocá-las em um repositório próprio para que seja baixada conforme necessidade. Esse processo gera uma manutenção um pouco pesada, deixando a desejar se comparado ao processo fácil de integração via Pods/SPM.
- A comparação foi realizada com um número relativamente pequeno de dependências externas, isso deixa aberto uma margem de melhoria nas performances extraídas a medida que um maior número de libs externas sejam migradas.
Nossa conclusão a partir deste levantamento é que a migração das dependências de Cocoapods para SPM irá resultar em uma série de benefícios ligados a performance de build, e indexação, além de também reduzir o tamanho dos binários gerados nas versões de release.
Embora o Carthage também tenha demonstrado bons resultados, entendemos que sua aplicação necessitaria de muitos outros steps adicionais, elevando a complexidade e manutenção da plataforma. Além disso, pelo fato da própria Apple ser a detentora do Swift Package Manager, isso nos dá uma garantia de manutenção e eventuais melhorias no processo como é integrada à projetos nativos iOS. O Carthage também gera muita dor de cabeça para atualizar versões do Xcode e obriga que o time todo esteja sempre usando a mesma versão e atualize sempre junto.
Por fim, vale destacar que a ferramenta usada atualmente para geração do projeto -Tuist- também oferece suporte ao SPM. Contando inclusive com um novo método para integração das dependências (atulamente em Alpha Version — Adding external dependencies | Tuist Documentation).
Esperamos que tenha curtido esse levantamento. Esses resultados são específicos para o nosso setup de projeto. E isso não quer dizer que os resultados vão se repetir para outros projetos com diferentes configurações.
Caso tenha alguma dúvida, é só comentar ;] .
Até a próxima pessoal.