Mecânica de Compilação do iOS

Este guia explora como determinar o ritmo dos seus aplicativos e como usar métodos que podem ser empregados para compilações mais rápidas para todas as configurações de compilação.

Desenvolver excelentes aplicativos é mais do que apenas escrever um código de funcione. Um aplicativo bem escrito deve conter otimizações que conseguem compilações mais rápidas com aplicativos que são menores e que executam mais rápido. Essas otimizações não apenas resultarão em uma melhor experiência para o usuário, mas também para você ou qualquer desenvolvedor trabalhando no projeto. É fundamental garantir que ao gerenciar seu aplicativo tudo seja sincronizado com frequência.

Lembre-se de que as opções padrão são seguras e rápidas, mas não são ideias para todas as situações. Além disso, muitas opções podem reduzir ou aumentar a velocidade do ciclo de desenvolvimento, dependendo do projeto individual. Por exemplo, a remoção nativa requer tempo, mas se pouco tamanho for obtido, o tempo gasto com a remoção não será recuperado por uma implantação mais rápida. Por outro lado, a remoção nativa pode reduzir o aplicativo significativamente, nesse caso, a implantação será mais rápida. Isso varia de projeto para projeto e a única maneira de saber é testando.

A velocidade de compilação do Xamarin também pode ser afetada por vários recursos e entre os recursos de um computador que podem afetar o desempenho estão: capacidade do processador, velocidades de barramento, quantidade de memória física, velocidade do disco, velocidade da rede. Essas limitações de desempenho estão além do escopo deste documento e são de responsabilidade do desenvolvedor.

Sincronizar aplicativos

Para habilitar os resultados de diagnóstico do MSBuild no Visual Studio para Mac:

  1. Clique Visual Studio para Mac > Preferências...
  2. No modo de exibição de árvore à esquerda, selecione Build de Projetos >
  3. No painel direito, defina a lista suspensa Detalhamento do log como Diagnóstico: definindo o detalhamento do log
  4. Clique em OK
  5. Reiniciar o Visual Studio para Mac
  6. Limpar e recompilar o seu pacote
  7. Exiba a saída de diagnóstico no Painel de Erros ( Exibir > Erros de Painéis > ) clicando no botão Saída do Build

Sincronizar o mtouch

Para exibir informações específicas para o processo de compilação do mtouch, passe o --time --time para os argumentos do mtouch nas Opções de Projeto. Os resultados são encontrados no Resultado da Compilação, pesquisando a tarefa MTouch:

Setup: 36 ms
Resolve References: 982 ms
Extracted native link info: 987 ms
...
Total time: 1554 ms

Conectando do Visual Studio com o Host de Compilação

As ferramentas do Xamarin, tecnicamente, funcionam em qualquer Mac que possa executar o OS X 10.10 Yosemite ou posterior. No entanto, as experiências de desenvolvedor e tempos de compilação podem ser prejudicados pelo desempenho do Mac.

No estado desconectado, o Visual Studio no Windows só realizará a fase de compilação do C# e não tentará executar a vinculação ou compilação AOT, empacotar o aplicativo em um pacote .app ou conectar-se ao pacote de aplicativos. (A fase de compilação do C# raramente é um gargalo de desempenho.) Tente identificar onde no pipeline o build está desacelerando criando diretamente no host de build do Mac em Visual Studio para Mac.

Além disso, um dos locais mais comuns para a lentidão é a conexão de rede entre o computador Windows e o host de compilação do Mac. Isso pode ocorrer devido a um obstáculo físico na rede, usar uma conexão sem fio ou ter que viajar por um computador saturado (como um serviço Mac na nuvem).

Truques do Simulador

Ao implantar aplicativos móveis, é fundamental implantar o código rapidamente. Por uma série de motivos, incluindo a velocidade e a falta de requisitos de provisionamento de dispositivos, os desenvolvedores, muitas vezes, optam por implantar um emulador ou simulador pré-instalado. Para os fabricantes de ferramentas de desenvolvedor, a decisão de fornecer um simulador ou emulador se resume a uma compensação entre a velocidade e compatibilidade.

A Apple fornece um simulador para desenvolvimento do iOS, promovendo a velocidade sobre a compatibilidade, com a criação de um ambiente menos restritivo para executar o código. Esse ambiente menos restritivo permite ao Xamarin usar o compilador Em Tempo Real (JIT) do simulador (em vez do AOT em um dispositivo), o que significa que a compilação é compilada no código nativo em runtime. Como o Mac é muito mais rápido do que um dispositivo, isso permite um melhor desempenho.

O simulador usa um inicializador do aplicativo compartilhado, permitindo que o iniciador seja reutilizado, em vez de ser compilado cada vez, como é necessário no dispositivo.

Levando em consideração as informações acima, a lista abaixo fornece algumas informações sobre etapas a serem executadas ao compilar e implantar seu aplicativo no simulador para fornecer o melhor desempenho.

Dicas

  • Para compilações:
    • Desmarque a opção Otimizar imagens PNG nas Opções de Projeto. Essa otimização não é necessária para compilações no simulador.
    • Defina o vinculador como Não Vincular. Desabilitar o vinculador é mais rápido, porque executá-lo requer um tempo significativamente maior.
    • Desabilitar o inicializador do aplicativo compartilhado usando o sinalizador --nofastsim faz com que as compilações do simulador fiquem muito mais lentas. Remova esse sinalizador quando ele não for mais necessário.
    • Usar bibliotecas nativas é mais lento porque o arquivo executável principal do inicializador de simulação compartilhado não pode ser reutilizado em tais casos e um arquivo executável específico do aplicativo precisa ser compilado para cada compilação.
  • Para implantação
    • Sempre que possível mantenha o simulador em execução. São necessários até 12 segundos para inicialização a frio o simulador.
  • Dicas Adicionais
    • Prefira Compilar a Recompilar, porque Recompilar limpa antes de compilar. A limpeza pode demorar muito tempo para remover as referências que podem ser usadas.
    • Aproveite o fato de que o simulador não impõe a área restrita. Ter recursos grandes como vídeos ou outros ativos no projeto pode criar operações de cópia de arquivos dispendiosas sempre que o aplicativo é inicializado no simulador. Evite essas operações dispendiosas colocando os arquivos no diretório base e faça referência a eles no seu aplicativo pelo caminho completo.
    • Em caso de dúvida, use o sinalizador --time --time para medir sua alteração

A captura de tela abaixo ilustra como definir essas opções para o simulador nas opções do iOS:

A captura de tela mostra opções do projeto, incluindo o comportamento do Vinculador, argumentos mtouch adicionais e otimizar imagens P N G.

Truques de dispositivos

A implantação no dispositivo é semelhante à implantação no simulador, uma vez que o simulador é um pequeno subconjunto de compilação usado para o dispositivo iOS. A compilação para o dispositivo requer várias etapas, mas tem a vantagem de fornecer outras oportunidades para otimizar o seu aplicativo.

Configurações de compilação

Uma série de configurações de compilação é oferecida ao implantar aplicativos iOS. É importante ter uma boa compreensão de cada configuração, saber quando e por que você deve otimizar.

  • Depurar
    • Essa é a configuração principal que deve ser usada enquanto um aplicativo está em desenvolvimento e deve, portanto, ser o mais rápido possível.
  • Versão
    • As compilações de versão são aquelas que são enviadas aos seus usuários e o foco no desempenho é fundamental. Ao usar a configuração de Versão, convém usar o compilador de otimização do LLVM e otimizar arquivos PNG.

Também é importante entender a relação entre compilação e implantação. O tempo de implantação é uma função do tamanho do aplicativo. Um aplicativo maior leva mais tempo para implantação. Minimizando o tamanho do aplicativo, é possível reduzir o tempo de implantação.

Minimizar o tamanho do aplicativo também pode reduzir o tempo de compilação. Isso ocorre porque a remoção do código do aplicativo leva menos tempo do que compilar nativamente o código que não será usado. Arquivos de objetos menores significam vinculação mais rápida, o que cria um arquivo executável menor e com menos símbolos para gerar. Portanto, economizar espaço tem um benefício duplo, e é por isso que Vincular SDK é o padrão para todas as compilações de dispositivos.

Observação

A opção Vincular SDK pode ser exibida como Vincular somente SDKs de estruturas ou Vincular somente assemblies de SDK, dependendo do IDE que está sendo usado.

Dicas

  • Build:
    • Compilar uma única arquitetura (por exemplo, ARM64) é mais rápido do que um binário FAT (por exemplo, ARMv7 + ARM64)
    • Evite otimizar arquivos PNG ao depurar
    • Considere Vincular todos os assemblies. Otimizar cada assembly
    • Desabilite a criação de símbolos de depuração usando --dsym=false. No entanto, saiba que desabilitar essa opção significa que os relatórios de falhas só poderão ser simbolizados na máquina que compilou o aplicativo e somente se o aplicativo não tiver sido eliminado.

O que evitar:

  • Binários FAT (depuração)
  • Desabilitar o vinculador --nolink
  • Desabilitar a remoção
    • Símbolos --nosymbolstrip
    • IL (versão) --nostrip.

Dicas adicionais

  • Como no simulador, prefira Compilar a Recompilar
    • Assemblies do AOT (arquivos de objetos) são armazenados em cache
  • Depurar compilações demora mais tempo devido aos símbolos que executam o dsymutil e como eles acabam sendo maiores, é necessário mais tempo para carregar os dispositivos.
  • As compilações de versão farão, por padrão, uma faixa de IL dos assemblies. Isso requer pouco de tempo, o qual será provavelmente recuperado ao implantar um .app menor no dispositivo.
  • Evitar a implantação de arquivos estáticos grandes em cada compilação (depuração)
    • Use UIFileSharingEnabled (info.plist)
      • Os ativos podem ser carregados uma vez
  • Em caso de dúvida, use o sinalizador --time --time para medir sua alteração

A captura de tela abaixo ilustra como definir essas opções para o simulador nas opções do iOS:

A captura de tela mostra opções do projeto, incluindo o comportamento do Vinculador, arquiteturas com suporte e outras configurações.

Usar o Vinculador

Ao compilar seu aplicativo, o mtouch usa um vinculador para o código gerenciado, que remove o código que o aplicativo não está usando. Na teoria, isso oferece compilações menores e, portanto, mais rápidas. Para obter mais informações sobre o vinculador, consulte o guia Vinculação no iOS.

Considere as seguintes opções ao usar o Vinculador:

  • Selecionar Não Vincular para uma compilação de Dispositivos requer uma grande quantidade de tempo e gera um aplicativo maior.
    • A Apple rejeitará aplicativos com tamanho acima do limite. Dependendo do MinimumOSVersion, isso pode ser tão pequeno quanto 60 MB.
    • O arquivo executável nativo está sendo incluído.
    • Usar Não vincular é mais rápido para compilações de simulador porque a compilação JIT é usada (em vez de AOT em um dispositivo).
  • Vincular o SDK é a opção padrão.
  • Usar Vincular Todos pode não ser seguro, especialmente se você estiver usando um código que não seja o seu próprio, como um NuGets ou Componentes. Se você optar por não vincular assemblies, todo o código desses serviços será incluído no seu aplicativo, possivelmente criando aplicativos maiores.
    • No entanto, se você escolher Vincular Todos o aplicativo poderá falhar, principalmente se os componentes externos forem usados. Isso ocorre porque alguns componentes usam Reflexão em determinados tipos.
    • A reflexão e análise estática não funcionam em conjunto.

As ferramentas podem ser instruídas a manter as coisas dentro do aplicativo usando o [Preserve] atributo .

Caso você não tenha acesso ao código-fonte ou ele seja gerado por uma ferramenta e você não queira alterá-lo, ele ainda poderá ser vinculado criando um arquivo XML que descreve todos os tipos e membros que precisam ser preservados. Em seguida, é possível adicionar o sinalizador --xml={file.name}.xml às opções de projeto, que processaram o código exatamente como se você estivesse usando Atributos.

Vinculação Parcial de Aplicativos

Também é possível vincular parcialmente os aplicativos, para ajudar a otimizar o tempo de compilação do seu aplicativo:

  • Use Link All e ignore alguns assemblies

    • Algumas das otimizações de tamanho do aplicativo serão perdidas.
    • Não é necessário acesso ao código-fonte.
    • Por exemplo, --linkall --linkskip=fieldserviceiOS.
  • Use Link SDK a opção e use o [LinkerSafe] atributo nos assemblies necessários

    • É necessário acesso ao código-fonte.
    • Informa ao sistema que o assembly é seguro para vincular e é processado como se ele fosse um SDK do Xamarin.

Objective-C Bindings

  • Usar o atributo [Assembly: LinkerSafe] nas suas associações pode economizar tempo e reduzir o tamanho.

  • SmartLink

    • Feito no lado Nativo
    • Use o atributo [LinkWith (SmartLink=true)]
    • Isso ajuda o vinculador nativo a eliminar o código nativo da biblioteca à qual você está vinculando.
    • Observe que a pesquisa dinâmica de símbolos não funcionará com isso.

Resumo

Este guia explorou como determinar o ritmo de um aplicativo iOS e as opções a considerar que dependem da configuração da compilação do projeto.