共用方式為


iOS 和 Mac Catalyst 上的原生 AOT 部署

原生 AOT 部署會在 iOS 和 Mac Catalyst 上產生 .NET 多平臺應用程式 UI (.NET MAUI) 應用程式,該應用程式已預先編譯為機器碼(AOT)。 原生 AOT 會執行靜態程式分析、完整修剪您的應用程式,這會積極移除未以靜態方式參考的程式代碼,以及預先產生程式代碼。

發佈和部署原生 AOT 應用程式會產生下列優點:

  • 減少應用程式套件大小。
  • 啟動時間更快。
  • 建置時間更快。

原生 AOT 將會對 .NET 運行時間的某些層面的使用造成限制,而且應該只在應用程式大小和效能很重要的案例中使用。 其會要求您將應用程式調整為原生 AOT 需求,這表示確保它們完全修剪且 AOT 相容。 如需原生 AOT 限制的詳細資訊,請參閱 原生 AOT 限制

啟用原生 AOT 部署時,建置系統會分析您的程式代碼及其所有相依性,以確認它是否適合完整修剪和 AOT 編譯。 如果偵測到不相容,就會產生修剪和 AOT 警告。 單一修剪或 AOT 警告表示應用程式與原生 AOT 部署不相容,而且可能無法正常運作。 因此,建置原生 AOT 部署的應用程式時,您應該檢閱並更正所有修剪和 AOT 警告。 若無法這麼做,可能會導致運行時間發生例外狀況,因為可能已移除必要的程序代碼。 如果您隱藏警告,則必須徹底測試 AOT 部署的應用程式,以確認尚未從未嘗試的應用程式變更功能。 如需詳細資訊,請參閱 修剪警告 簡介和 AOT 警告簡介。

注意

在某些情況下,修正修剪和 AOT 警告是不可能的,例如第三方連結庫發生時。 在這種情況下,必須更新第三方連結庫,才能完全相容。

原生 AOT 效能優點

發佈和部署原生 AOT 應用程式會產生通常小於 2.5 倍的應用程式,而啟動的應用程式通常快 2 倍。 不過,確切的效能優點取決於多種因素,包括正在使用的平臺、執行應用程式的裝置,以及應用程式本身。

重要

下圖顯示 iOS 和 Mac Catalyst 上應用程式原生 AOT 部署的典型 dotnet new maui 效能優點。 不過,確切的數據與硬體相依,未來版本可能會變更。

下圖顯示不同部署模型中 iOS 和 Mac Catalyst 上應用程式的應用程式套件大小 dotnet new maui

圖表顯示不同部署模型的應用程式套件大小。

上圖顯示,相較於預設部署模型,原生 AOT 通常會針對 iOS 和 Mac Catalyst 產生超過 2 倍以上的應用程式。

下圖顯示 iOS 和 Mac Catalyst on Mono 和 Native AOT 部署上應用程式的特定硬體 dotnet new maui 平均啟動時間:

顯示Mono和Native AOT 上平均應用程式啟動時程的圖表。

上圖顯示,相較於Mono部署,原生 AOT 通常會在iOS裝置上擁有高達2倍的啟動時間,以及Mac Catalyst上啟動時間快1.2倍。

下圖顯示 iOS 和 Mac Catalyst 上應用程式在不同部署模型中的特定硬體 dotnet new maui 上的平均建置時間:

顯示Mono和Native AOT 上平均應用程式建置時間的圖表。

上圖顯示,相較於預設部署模型,原生 AOT 在 iOS 裝置上的建置時間通常高達 2.8 倍。 針對 Mac Catalyst,組建時間與 arm64 單一 RID 應用程式相當,但與 Mono 部署相比,通用應用程式的建置時間會稍微慢一點。

重要

在許多情況下,原生 AOT 會產生更小且更快的應用程式。 不過,在某些情況下,原生 AOT 可能不會產生更小且更快的應用程式。 因此,請務必測試和分析您的應用程式,以判斷啟用原生 AOT 部署的結果。

使用原生 AOT 發佈

原生 AOT 部署模型會使用 $(PublishAot) 組建屬性和 dotnet publish 命令來啟用。 下列範例示範如何修改項目檔,以在iOS和Mac Catalyst上啟用原生 AOT 部署:

<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>

針對所有平臺,將 $(IsAotCompatible) build屬性設定為 true,即可進行修剪和AOT分析器。 這些分析器可協助您識別與修剪或 AOT 不相容的程式代碼。

針對 iOS 和 Mac Catalyst,有條件地設定 $(PublishAot)true,可在發行期間建置和原生 AOT 編譯期間啟用動態程式碼使用分析。 原生 AOT 分析包含應用程式的所有程式代碼,以及應用程式相依的任何連結庫。

警告

$(PublishAot)建置屬性不應該受到組建組態的條件。 這是因為修剪功能參數會根據建置屬性的值 $(PublishAot) 啟用或停用,而且所有建置組態中都應該啟用或停用相同的功能,讓您的程式碼運作方式相同。 如需修剪功能參數的詳細資訊,請參閱 修剪功能參數

驗證原生 AOT 應用程式是否正常運作的唯一方式,是使用 dotnet publish 發佈它,並確認您的程式代碼及其相依性不會產生任何修剪或 AOT 警告。 特別是, dotnet build -t:Publish 不等於 dotnet publish

使用下列 dotnet publish 命令,使用原生 AOT 部署在 iOS 和 Mac Catalyst 上發布您的應用程式:

# 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

提示

經常發佈應用程式,以在開發生命週期早期探索修剪或 AOT 問題。

原生 AOT 限制

原生 AOT 將會對 .NET 運行時間的某些層面的使用造成限制,而且應該只在應用程式大小和效能很重要的案例中使用。 其會要求您調整應用程式以符合原生 AOT 需求,這表示確保它們完全修剪且 AOT 相容,這可能需要大量工作。 除了原生 AOT 部署.NET 限制之外,.NET MAUI 的原生 AOT 部署也有其他限制。

應用程式相依的第三方連結庫可能與 AOT 不相容。 確保連結庫修剪且 AOT 相容的唯一方法是使用原生 AOT 部署和 dotnet publish 命令發布您的應用程式,並查看原生 AOT 編譯程式是否產生連結庫的任何警告。 如需建立您自己的連結庫 AOT 相容的詳細資訊,請參閱 如何讓連結庫與原生 AOT 相容。

反映和動態程序代碼

原生 AOT 部署會限制在您的程式代碼及其相依性中使用反映,而且可能需要使用註釋來協助原生 AOT 編譯程式瞭解反映模式。 當編譯程式遇到無法以靜態方式分析的反映模式時,因此無法建置應用程式,它會產生修剪警告。 原生 AOT 也會防止您在應用程式中使用動態程式代碼。 例如,編譯 System.Linq.Expressions 無法如預期般運作,而且無法在運行時間載入和執行元件。 當編譯程式遇到無法預先編譯的動態模式時,它會產生 AOT 警告。

在 .NET MAUI 應用程式中,這表示:

重要

Mono 解釋器與原生 AOT 部署不相容,因此 $(UseInterpreter) $(MtouchInterpreter) 和 MSBuild 屬性在使用原生 AOT 時沒有作用。 如需Mono解釋器的詳細資訊,請參閱 iOS和Mac Catalyst上的Mono解釋器

如需修剪警告的詳細資訊,請參閱 修剪警告簡介。 如需 AOT 警告的詳細資訊,請參閱 AOT 警告簡介。

將應用程式調整為原生 AOT 部署

使用下列檢查清單可協助您將應用程式調整為原生 AOT 部署需求:

  • 確定已編譯所有 XAML:
    • 拿掉所有 [XamlCompilation(XamlCompilationOptions.Skip)] 使用量。
    • 拿掉所有 <?xaml-comp compile="false" ?> 使用量。
  • 拿掉對 LoadFromXaml 方法的所有呼叫。
  • 請確定已編譯所有數據系結。 如需詳細資訊,請參閱 編譯的系結。
    • 請確定所有 XAML 資料系結都會以 x:DataType標註。
    • 確定所有程式代碼數據系結都會以 Lambda 型系結取代所有以字串為基礎的系結。
  • [QueryProperty(...)]將所有使用方式取代為 介面的實作IQueryAttributable。 如需詳細資訊,請參閱 使用單一方法處理導覽數據。
  • 以取代所有 SearchHandler.DisplayMemberName 使用方式 ItemTemplate。 如需詳細資訊,請參閱 定義搜尋結果項目外觀
  • 將 XAML 中使用的型別的所有隱含轉換運算子取代為 TypeConverter,並使用 將它附加至您的型 TypeConverterAttribute別。 如需詳細資訊,請參閱 定義 TypeConverter 以取代隱含轉換運算符
    • 從類型 A 轉換成類型 B時, ConvertTo 將會使用與 A 相關聯之類型轉換子上的方法,或是 ConvertFrom 使用與 B 相關聯之類型轉換子上的方法。
    • 當來源和目標型別都有相關聯的型別轉換器時,可以使用其中一個。
  • 使用來源產生器編譯所有正則表達式。 如需詳細資訊,請參閱 .NET 規則運算式來源產生器
  • 確定 JSON 串行化和還原串行化使用來源產生的內容。 如需詳細資訊,請參閱 最小 API 和 JSON 承載
  • 檢閱並更正任何修剪或 AOT 警告。 如需詳細資訊,請參閱 修剪警告 簡介和 AOT 警告簡介。
  • 徹底測試您的應用程式。

另請參閱