Observação
O acesso a essa página exige autorização. Você pode tentar entrar ou alterar diretórios.
O acesso a essa página exige autorização. Você pode tentar alterar os diretórios.
A implantação AOT nativa produz um aplicativo .NET MAUI (Aplicativo de Interface do Usuário Multiplataforma .NET) no iOS e no Mac Catalyst que foi compilado antecipadamente (AOT) para código nativo. O AOT nativo executa a análise estática do programa, o corte completo do seu aplicativo, que é agressivo na remoção de código que não é referenciado estaticamente e na geração antecipada de código.
A publicação e a implantação de um aplicativo AOT nativo produzem os seguintes benefícios:
- Tamanho reduzido do pacote do aplicativo.
- Tempo de inicialização mais rápido.
- Tempo de construção mais rápido.
O AOT nativo introduzirá limitações no uso de determinados aspectos do runtime do .NET e só deve ser usado em cenários em que o tamanho e o desempenho do aplicativo são importantes. Isso exigirá que você adapte seus aplicativos aos requisitos do Native AOT, o que significa garantir que eles sejam totalmente otimizados e compatíveis com AOT. Para obter mais informações sobre as limitações do AOT nativo, consulte Limitações do AOT nativo.
Quando a implantação AOT nativa está habilitada, o sistema de compilação analisa seu código e todas as suas dependências para verificar se ele é adequado para trimming total e compilação AOT. Se forem detectadas incompatibilidades, serão gerados avisos de otimização e AOT. Um único aviso de corte ou AOT significa que o aplicativo não é compatível com a implantação do AOT nativo e que pode não funcionar corretamente. Portanto, ao criar um aplicativo para implantação nativa de AOT, você deve revisar e corrigir todos os avisos de redução e AOT. Não fazer isso pode resultar em exceções em tempo de execução, pois o código necessário pode ter sido removido. Se você suprimir os avisos, o aplicativo AOT implantado deverá ser testado minuciosamente para verificar se a funcionalidade não foi alterada em relação ao aplicativo sem cortes. Para obter mais informações, consulte Introdução aos avisos de trimming e Introdução aos avisos AOT.
Observação
Pode haver casos em que a correção de avisos de corte e AOT não seja possível, como quando eles ocorrem para bibliotecas de terceiros. Nesses casos, as bibliotecas de terceiros precisarão ser atualizadas para se tornarem totalmente compatíveis.
Benefícios de desempenho nativos do AOT
A publicação e a implantação de um aplicativo AOT nativo produzem um aplicativo que normalmente é até 2,5 vezes menor e um aplicativo que é iniciado normalmente até 2 vezes mais rápido. No entanto, os benefícios exatos de desempenho dependem de vários fatores, que incluem a plataforma que está sendo usada, o dispositivo no qual o aplicativo está sendo executado e o próprio aplicativo.
Importante
Os gráficos a seguir mostram os benefícios típicos de desempenho da implantação do AOT nativo para um dotnet new maui aplicativo no iOS e no Mac Catalyst. No entanto, os dados exatos dependem do hardware e podem ser alterados em versões futuras.
O gráfico a seguir mostra o tamanho do pacote do aplicativo para um dotnet new maui aplicativo no iOS e no Mac Catalyst em diferentes modelos de implantação:
O gráfico anterior mostra que, normalmente, o AOT nativo produz aplicativos mais de 2 vezes menores para iOS e Mac Catalyst em comparação com o modelo de implantação padrão.
O gráfico a seguir mostra o tempo médio de inicialização, em hardware específico, para um dotnet new maui aplicativo no iOS e Mac Catalyst na implantação Mono e AOT nativa:
O gráfico anterior mostra que o AOT nativo normalmente tem tempos de inicialização até 2x mais rápidos em dispositivos iOS e tempo de inicialização 1,2x mais rápido no Mac Catalyst, em comparação com a implantação do Mono.
O gráfico a seguir mostra o tempo médio de compilação, em hardware específico, para um dotnet new maui aplicativo no iOS e no Mac Catalyst em diferentes modelos de implantação:
O gráfico anterior mostra que normalmente o AOT nativo tem tempos de build até 2,8 vezes mais rápidos em dispositivos iOS em comparação com o modelo de implantação padrão. Para o Mac Catalyst, os tempos de compilação são comparáveis para aplicativos com RID único para arm64, mas são ligeiramente mais lentos para aplicativos universais quando comparados ao processo de implantação usando o framework Mono.
Importante
Em muitos cenários, o AOT nativo produzirá aplicativos menores e mais rápidos. No entanto, em alguns cenários, o AOT nativo pode não produzir aplicativos menores e mais rápidos. Portanto, é importante testar e fazer o perfil do seu aplicativo para determinar o resultado da habilitação da implantação do AOT Nativo.
Publicar usando AOT nativo
O modelo de implantação nativo AOT é habilitado com a propriedade de construção $(PublishAot) e o comando dotnet publish. O exemplo a seguir mostra como modificar um arquivo de projeto para habilitar a implantação AOT nativa no iOS e Mac Catalyst:
<PropertyGroup>
<!-- enable trimming and AOT analyzers on all platforms -->
<IsAotCompatible>true</IsAotCompatible>
<!-- select platforms to use with NativeAOT -->
<PublishAot Condition="$([MSBuild]::GetTargetPlatformIdentifier('$(TargetFramework)')) == 'ios'">true</PublishAot>
<PublishAot Condition="$([MSBuild]::GetTargetPlatformIdentifier('$(TargetFramework)')) == 'maccatalyst'">true</PublishAot>
</PropertyGroup>
Definir a $(IsAotCompatible) propriedade build como true, para todas as plataformas, habilita analisadores de redução e AOT. Esses analisadores ajudam a identificar código que não é compatível com trimming nem AOT.
A configuração condicional de $(PublishAot) para true, para iOS e Mac Catalyst, permite a análise do uso de código dinâmico durante a compilação e a compilação AOT nativa durante a publicação. A análise AOT nativa inclui todo o código do aplicativo e todas as bibliotecas das quais o aplicativo depende.
Aviso
A $(PublishAot) propriedade build não deve ser condicionada pela configuração de build. Isso ocorre porque as opções de configuração para recursos de otimização são habilitadas ou desabilitadas com base no valor da propriedade de build $(PublishAot), e os mesmos recursos devem ser habilitados ou desabilitados em todas as configurações de build para que seu código se comporte de forma idêntica. Para mais informações sobre como configurar interruptores de recursos, consulte Interruptores de recursos para ajuste.
A única maneira de verificar se um aplicativo AOT nativo funciona corretamente é publicá-lo usando dotnet publish e verificar se não há avisos de corte ou AOT produzidos pelo seu código e suas dependências. Em particular, dotnet build -t:Publish não é equivalente a dotnet publish.
Use o seguinte dotnet publish comando para publicar seu aplicativo no iOS e no Mac Catalyst usando a implantação AOT nativa:
# iOS
dotnet publish -f net9.0-ios -r ios-arm64
# Mac Catalyst
dotnet publish -f net9.0-maccatalyst -r maccatalyst-arm64
dotnet publish -f net9.0-maccatalyst -r maccatalyst-x64
# Universal Mac Catalyst apps
# (when <RuntimeIdentifiers>maccatalyst-x64;maccatalyst-arm64</RuntimeIdentifiers> is set in the project file)
dotnet publish -f net9.0-maccatalyst
Dica
Publique aplicativos com frequência para identificar problemas de redução ou AOT no início do ciclo de vida do desenvolvimento.
Limitações nativas do AOT
O AOT nativo introduzirá limitações no uso de determinados aspectos do runtime do .NET e só deve ser usado em cenários em que o tamanho e o desempenho do aplicativo são importantes. Isso exigirá que você adapte seus aplicativos aos requisitos do AOT Nativo, o que significa garantir que eles sejam totalmente otimizados e compatíveis com o AOT Nativo, e isso pode exigir muito trabalho. Além das limitações do .NET relacionadas à implantação do AOT nativo, a implantação do AOT nativo para o .NET MAUI tem limitações adicionais.
As bibliotecas de terceiros das quais seus aplicativos dependem podem não ser compatíveis com AOT. A única maneira de garantir que uma biblioteca seja reduzida e compatível com AOT é publicar seu aplicativo usando a implantação do AOT nativo com o comando dotnet publish e verificar se o compilador AOT nativo gera algum aviso sobre a biblioteca. Para obter informações sobre como tornar suas próprias bibliotecas compatíveis com AOT, consulte Como tornar bibliotecas compatíveis com AOT nativo.
Reflexão e código dinâmico
A implantação do AOT nativo limita o uso de reflexão em seu código e suas dependências, e pode ser necessário usar anotações para ajudar o compilador AOT nativo a entender os padrões de reflexão. Quando o compilador encontra um padrão de reflexão, ele não pode analisar estaticamente e, portanto, não pode criar o aplicativo, ele produz avisos de corte. O AOT nativo também impede que você use código dinâmico em seu aplicativo. Por exemplo, a compilação System.Linq.Expressions não funcionará conforme o esperado e não é possível carregar e executar assemblies em runtime. Quando o compilador encontra um padrão dinâmico que não pode compilar antecipadamente, ele produzirá um aviso AOT.
No aplicativo .NET MAUI, isso significa que:
- Todo o XAML precisa ser compilado antecipadamente. Portanto, verifique se você não desabilitou a compilação XAML e se todas as associações foram compiladas. Para obter mais informações, consulte Compilação XAML e Vinculações compiladas.
- Todas as expressões de associação devem usar associações compiladas, em vez de um caminho de associação definido como uma cadeia de caracteres. Para obter mais informações, consulte Vinculações compiladas.
- Os operadores de conversão implícitos podem não ser chamados ao atribuir um valor de um tipo incompatível a uma propriedade em XAML ou quando duas propriedades de tipos diferentes usam uma associação de dados. Em vez disso, você deve definir a TypeConverter para o seu tipo e anexá-lo ao tipo usando o TypeConverterAttribute. Para obter mais informações, consulte Definir um TypeConverter para substituir um operador de conversão implícito.
- Não é possível analisar XAML em runtime com o LoadFromXaml método. Embora isso possa ser feito de forma segura contra cortes, anotando todos os tipos que podem ser carregados em tempo de execução com os atributos
DynamicallyAccessedMembersouDynamicDependency, isso é altamente propenso a erros e não é recomendado. - Receber dados de navegação usando o QueryPropertyAttribute não funcionará. Em vez disso, você deve implementar a IQueryAttributable interface em tipos que precisam aceitar parâmetros de consulta. Para obter mais informações, confira Processar os dados de navegação usando um só método.
- A
SearchHandler.DisplayMemberNamepropriedade pode não funcionar. Em vez disso, você deve fornecer um ItemTemplate para definir a aparência dos resultados SearchHandler. Para obter mais informações, consulte Definir a aparência do item de resultados da pesquisa. - Não é possível personalizar a aparência da interface do usuário com a extensão de marcação XAML
OnPlatform. Em vez disso, você deve usar a classe OnPlatform<T>. Para obter mais informações, consulte Personalizar a aparência da interface do usuário (UI) com base na plataforma. - Não é possível personalizar a aparência da interface do usuário com a extensão de marcação XAML
OnIdiom. Em vez disso, você deve usar a classe OnIdiom<T>. Para obter mais informações, consulte Personalizar a aparência da interface de acordo com o tipo de dispositivo.
Importante
O interpretador Mono não é compatível com a implantação Native AOT e, portanto, as propriedades $(UseInterpreter) e $(MtouchInterpreter) do MSBuild não têm efeito ao usar o Native AOT. Para obter mais informações sobre o interpretador Mono, consulte Interpretador Mono no iOS e Mac Catalyst.
Para obter mais informações sobre avisos de corte, consulte Introdução aos avisos de corte. Para obter mais informações sobre avisos AOT, consulte Introdução aos avisos AOT.
Adaptar um aplicativo à implantação de AOT nativa
Use a lista de verificação a seguir para ajudá-lo a adaptar seu aplicativo aos requisitos de implantação do AOT nativo:
- Verifique se todo o XAML está compilado:
- Remova todo o uso de
[XamlCompilation(XamlCompilationOptions.Skip)]. - Remova todo uso de
<?xaml-comp compile="false" ?>.
- Remova todo o uso de
- Remova todas as chamadas para o LoadFromXaml método.
- Verifique se todas as associações de dados são compiladas. Para obter mais informações, consulte Vinculações compiladas.
- Verifique se todas as associações de dados XAML são anotadas com
x:DataType. - Certifique-se de que todas as associações de dados de código substituam todas as associações baseadas em cadeia de caracteres por associações baseadas em lambda.
- Verifique se todas as associações de dados XAML são anotadas com
- Substitua o uso da extensão de marcação XAML
OnPlatformpor uma implementação que usa a classe OnPlatform<T>. Para obter mais informações, consulte Personalizar a aparência da interface do usuário (UI) com base na plataforma. - Substitua o uso da extensão de marcação XAML
OnIdiompor uma implementação que usa a classe OnIdiom<T>. Para obter mais informações, consulte Personalizar a aparência da interface de acordo com o tipo de dispositivo. - Substitua todo o uso de
[QueryProperty(...)]por uma implementação da interfaceIQueryAttributable. Para obter mais informações, confira Processar os dados de navegação usando um só método. - Substitua todo o
SearchHandler.DisplayMemberNameuso por um ItemTemplate. Para obter mais informações, consulte Definir a aparência do item de resultados da pesquisa. - Substitua todos os operadores de conversão implícitos para tipos usados em XAML por um TypeConverter, e anexe-o ao seu tipo usando o TypeConverterAttribute. Para obter mais informações, consulte Definir um TypeConverter para substituir um operador de conversão implícito.
- Ao converter de tipo
Apara tipoB, oConvertTométodo em um conversor de tipo associado aAserá usado ou oConvertFrommétodo em um conversor de tipo associado aBserá usado. - Quando os tipos de origem e de destino têm um conversor de tipo associado, qualquer um deles pode ser usado.
- Ao converter de tipo
- Compile todas as expressões regulares usando geradores de código-fonte. Para obter mais informações, confira Geradores de origem de expressão regular do .NET.
- Verifique se a serialização e a desserialização JSON usam um contexto gerado pela origem. Para obter mais informações, consulte APIs mínimas e cargas JSON.
- Revise e corrija quaisquer avisos de redução ou AOT. Para obter mais informações, consulte Introdução aos avisos de trimming e Introdução aos avisos AOT.
- Teste completamente seu aplicativo.
Suporte nativo ao diagnóstico AOT no iOS e Mac Catalyst
AOT e Mono nativos compartilham um subconjunto de recursos de diagnóstico e instrumentação. Devido à variedade de ferramentas de diagnóstico do Mono, pode ser benéfico diagnosticar e depurar problemas no Mono em vez do AOT nativo. Os aplicativos que são otimizados e compatíveis com AOT não devem ter diferenças comportamentais, portanto, as investigações geralmente se aplicam a ambos os runtimes.
A tabela a seguir mostra o suporte de diagnóstico com AOT nativo no iOS e Mac Catalyst:
| Funcionalidade | Suporte total | Suporte parcial | Sem suporte |
|---|---|---|---|
| Observabilidade e telemetria | Parcialmente compatível | ||
| Diagnósticos durante o desenvolvimento | Totalmente suportado | ||
| Depuração nativa | Parcialmente compatível | ||
| Criação de perfil da CPU | Parcialmente compatível | ||
| Análise de heap | Sem suporte |
As seções a seguir fornecem informações adicionais sobre esse suporte de diagnóstico.
Observabilidade e telemetria
O rastreamento de aplicativos .NET MAUI em plataformas móveis é habilitado por meio de dotnet-dsrouter , que conecta ferramentas de diagnóstico a aplicativos .NET em execução no iOS e Mac Catalyst, por TCP/IP. No entanto, o Native AOT atualmente não é compatível com esse cenário, pois não oferece suporte a componentes EventPipe/DiagnosticServer criados com a pilha TCP/IP. A observabilidade ainda pode ser alcançada explicitamente no código.
Diagnóstico durante o desenvolvimento
As ferramentas da CLI do .NET fornecem comandos separados para build e publish.
dotnet build (ou Start Debugging (F5) no Visual Studio Code), usa o Mono por padrão ao criar ou iniciar aplicativos .NET MAUI iOS ou Mac Catalyst. Só dotnet publish criará um aplicativo AOT nativo, se esse modelo de implantação estiver habilitado no arquivo de projeto.
Nem todas as ferramentas de diagnóstico funcionarão perfeitamente com aplicativos AOT nativos publicados. No entanto, todos os aplicativos compatíveis com trim e AOT (ou seja, aqueles que não produzem nenhum aviso de trim e AOT no momento da compilação) não devem ter diferenças comportamentais entre o Mono e o AOT nativo. Portanto, todas as ferramentas de diagnóstico de tempo de desenvolvimento do .NET, como Recarga Dinâmica, ainda estão disponíveis para desenvolvedores durante o ciclo de desenvolvimento de aplicativos móveis.
Dica
Você deve desenvolver, depurar e testar seu aplicativo como de costume e publicar seu aplicativo final com AOT nativo como uma das últimas etapas.
Depuração nativa
Quando você executa seu aplicativo .NET MAUI iOS ou Mac Catalyst durante o desenvolvimento, ele é executado no Mono por padrão. No entanto, se a implantação do AOT Nativo estiver habilitada no arquivo de projeto, espera-se que o comportamento do Mono e do AOT Nativo seja o mesmo quando o aplicativo não estiver produzindo nenhum aviso de trim ou de AOT durante a construção. Desde que seu aplicativo atenda a esse requisito, você pode usar o mecanismo de depuração gerenciado padrão do Visual Studio Code para desenvolvimento e teste,
Após a publicação, os aplicativos AOT nativos se tornam binários genuinamente nativos e, portanto, o depurador gerenciado não funcionará neles. No entanto, o compilador AOT nativo gera arquivos totalmente nativos e executáveis que você pode depurar com lldb. A depuração de um aplicativo Mac Catalyst com lldb é simples, pois é executada no mesmo sistema. No entanto, a depuração de aplicativos iOS NativeAOT implica esforço adicional.
Depure aplicativos .NET MAUI para iOS com AOT nativo
Os aplicativos iOS do .NET MAUI, que são compatíveis com AOT Nativo e que estão configurados e publicados corretamente com este modelo de distribuição, podem ser depurados da seguinte maneira:
Publique seu aplicativo com segmentação
ios-arm64AOT nativa e observe as seguintes informações:- Nome do aplicativo (referenciado abaixo como
<app-name>). - Identificador de pacote (referenciado abaixo como
<bundle-identifier>). - Caminho para o arquivo de pacote .ipa do aplicativo publicado (referenciado abaixo como
<path-to-ipa>).
- Nome do aplicativo (referenciado abaixo como
Obtenha a ID do seu dispositivo físico (referenciada abaixo como
<device-identifier>):xcrun devicectl list devicesInstale o aplicativo em seu dispositivo físico:
xcrun devicectl device install app --device <device-identifier> <path-to-ipa>Inicie o aplicativo em seu dispositivo físico:
xcrun devicectl device process launch --device <device-identifier> --start-stopped <bundle-identifier>Abra
lldbe conecte-se ao seu dispositivo físico:(lldb) device select <device-identifier> (lldb) device process attach -n <app-name>
Depois de concluir essas etapas com êxito, você poderá começar a depurar seu aplicativo iOS Native AOT .NET MAUI com lldb.
Importância do arquivo de símbolo
Por padrão, os símbolos de depuração são removidos do arquivo binário do aplicativo para um arquivo .dSYM . Esse arquivo é usado por depuradores e ferramentas de análise post mortem para mostrar informações sobre variáveis locais, números de linhas de origem e para recriar rastros de pilha de despejo de falhas. Portanto, é essencial preservar o arquivo de símbolo antes de enviar sua inscrição para a App Store.
Criação de perfil da CPU
O Xcode Instruments pode ser usado para coletar amostras de CPU de um aplicativo AOT nativo.
Análise de heap
No momento, a análise de heap não é suportada com o Native AOT.