ASP.NET Core Blazor WebAssembly 빌드 도구 및 AOT(Ahead-Of-Time) 컴파일

참고 항목

이 문서의 최신 버전은 아닙니다. 현재 릴리스는 이 문서의 .NET 8 버전을 참조 하세요.

Important

이 정보는 상업적으로 출시되기 전에 실질적으로 수정될 수 있는 시험판 제품과 관련이 있습니다. Microsoft는 여기에 제공된 정보에 대해 어떠한 명시적, 또는 묵시적인 보증을 하지 않습니다.

현재 릴리스는 이 문서의 .NET 8 버전을 참조 하세요.

이 문서에서는 독립 실행형 Blazor WebAssembly 앱용 빌드 도구와 AOT(미리 실행형) 컴파일을 사용하여 배포에 앞서 앱을 컴파일하는 방법을 설명합니다.

이 문서는 주로 독립 실행형 Blazor WebAssembly 앱에 초점을 맞추고 있지만 일부 모바일 디바이스 브라우저힙 크기에 대한 섹션은 웹앱의 Blazor 클라이언트 쪽 프로젝트(.Client)에도 적용됩니다.

.NET WebAssembly 빌드 도구

.NET WebAssembly 빌드 도구는 웹 플랫폼을 위한 컴파일러 도구 체인인 Emscripten에 기반합니다. 빌드 도구를 설치하려면 다음 방법 중 하나를 사용하세요.

  • Visual Studio 설치 관리자의 ASP.NET 및 웹 개발 워크로드의 경우 선택적 구성 요소 목록에서 .NET WebAssembly 빌드 도구 옵션을 선택합니다.
  • 관리 명령 셸에서 dotnet workload install wasm-tools를 실행합니다.

참고 항목

.NET 6 프로젝트용 .NET WebAssembly 빌드 도구

워크로드는 wasm-tools 최신 릴리스용 빌드 도구를 설치합니다. 그러나 빌드 도구의 현재 버전은 .NET 6으로 빌드된 기존 프로젝트와 호환되지 않습니다. .NET 6 이상 릴리스를 모두 지원해야 하는 빌드 도구를 사용하는 프로젝트는 다중 대상 지정을 사용해야 합니다.

.NET 7 SDK를 사용하여 앱을 개발할 때 .NET 6 프로젝트용 wasm-tools-net6 워크로드를 사용합니다. wasm-tools-net6 워크로드를 설치하려면 관리 명령 셸에서 다음 명령을 실행합니다.

dotnet workload install wasm-tools-net6

AOT(Ahead-Of-Time) 컴파일

Blazor WebAssembly는 .NET 코드를 WebAssembly로 직접 컴파일할 수 있는 AOT(ahead-of-time) 컴파일을 지원합니다. AOT 컴파일을 수행하면 앱 크기가 커지는 대신 런타임 성능이 향상됩니다.

AOT 컴파일 Blazor WebAssembly 을 사용하도록 설정하지 않으면 앱은 WebAssembly에서 구현된 .NET IL(중간 언어) 인터프리터를 사용하여 브라우저에서 실행되며, JIT(Just-In-Time) 런타임 지원은 비공식적으로 Jiterpreter라고 합니다. .NET IL 코드가 해석되기 때문에 앱은 일반적으로 IL 해석 없이 서버 쪽 .NET JIT 런타임보다 느리게 실행됩니다. AOT 컴파일은 브라우저에서 기본 WebAssembly가 실행되도록 앱의 .NET 코드를 WebAssembly로 직접 컴파일하여 이 성능 문제를 해결합니다. AOT 성능 향상은 CPU 집약적인 작업을 실행하는 앱을 크게 향상할 수 있습니다. AOT 컴파일을 사용하는 경우의 단점은 AOT로 컴파일된 앱이 일반적으로 IL로 해석된 앱보다 크기 때문에 처음 요청 시 클라이언트에 다운로드하는 데 시간이 더 오래 걸린다는 것입니다.

AOT 컴파일 Blazor WebAssembly 을 사용하도록 설정하지 않으면 WebAssembly에서 구현된 .NET IL(중간 언어) 인터프리터를 사용하여 브라우저에서 앱이 실행됩니다. .NET 코드가 해석되기 때문에 앱은 일반적으로 서버 쪽 .NET JIT(Just-In-Time) 런타임보다 느리게 실행됩니다. AOT 컴파일은 브라우저에서 기본 WebAssembly가 실행되도록 앱의 .NET 코드를 WebAssembly로 직접 컴파일하여 이 성능 문제를 해결합니다. AOT 성능 향상은 CPU 집약적인 작업을 실행하는 앱을 크게 향상할 수 있습니다. AOT 컴파일을 사용하는 경우의 단점은 AOT로 컴파일된 앱이 일반적으로 IL로 해석된 앱보다 크기 때문에 처음 요청 시 클라이언트에 다운로드하는 데 시간이 더 오래 걸린다는 것입니다.

.NET WebAssembly 빌드 도구 설치에 대한 지침은 ASP.NET Core Blazor WebAssembly 빌드 도구 및 AOT(미리 보기) 컴파일을 참조하세요.

WebAssembly AOT 컴파일을 사용하도록 설정하려면 true로 설정된 <RunAOTCompilation> 속성을 Blazor WebAssembly 앱의 프로젝트 파일에 추가합니다.

<PropertyGroup>
  <RunAOTCompilation>true</RunAOTCompilation>
</PropertyGroup>

앱을 WebAssembly로 컴파일하려면 앱을 게시합니다. Release 구성을 게시하면 게시된 앱의 크기를 줄일 수 있도록 .NET IL(중간 언어) 연결도 실행됩니다.

dotnet publish -c Release

WebAssembly AOT 컴파일은 프로젝트가 게시될 때만 수행됩니다. AOT 컴파일은 일반적으로 작은 프로젝트에서 몇 분 정도 걸리고 더 큰 프로젝트에서는 훨씬 더 오래 걸릴 수 있으므로, 개발(Development 환경) 중에 프로젝트가 실행될 때는 AOT 컴파일이 사용되지 않습니다. ASP.NET Core의 향후 릴리스를 위해 AOT 컴파일을 위한 빌드 시간 단축이 개발 중입니다.

AOT로 컴파일된 Blazor WebAssembly 앱의 크기는 일반적으로 .NET IL로 컴파일된 경우의 앱보다 큽니다.

  • 크기 차이는 앱에 따라 다르지만 대부분의 AOT로 컴파일된 앱은 IL로 컴파일된 버전의 약 두 배입니다. 즉, AOT 컴파일을 사용하면 로드 성능이 저하되는 대신 런타임 성능이 향상됩니다. 이 득실을 감안하며 AOT 컴파일을 사용할 가치가 있는지는 앱에 따라 달라집니다. CPU를 많이 사용하는 Blazor WebAssembly 앱이 일반적으로 AOT 컴파일의 이점을 가장 많이 누립니다.

  • AOT 컴파일 앱은 다음 두 가지 조건 때문에 크기가 증가합니다.

    • 네이티브 WebAssembly의 상위 수준 .NET IL 지침을 나타내려면 더 많은 코드가 필요합니다.
    • AOT는 앱이 게시될 때 관리되는 DLL을 자르지 않습니다. Blazor에는 리플렉션 메타데이터를 위한 DLL이 필요하고 특정 .NET 런타임 기능을 지원해야 합니다. 클라이언트에서 DLL을 요구하면 다운로드 크기가 증가하지만 보다 호환성 높은 .NET 환경을 제공합니다.

참고 항목

Mono/WebAssembly MSBuild 속성 및 대상은 (dotnet/runtimeGitHub 리포지토리)를 참조 WasmApp.Common.targets 하세요. 일반적인 MSBuild 속성에 대한 공식 설명서는 Document blazor msbuild 구성 옵션(dotnet/docs#27395)에 따라 계획됩니다.

AOT(Ahead-Of-Time) 컴파일 후 .NET IL 자르기

WasmStripILAfterAOT MSBuild 옵션을 사용하면 WebAssembly로 AOT 컴파일을 수행한 후 컴파일된 메서드에 대해 .NET IL(중간 언어)을 제거할 수 있으므로 폴더 크기 _framework 가 줄어듭니다.

앱의 프로젝트 파일에서 다음을 수행합니다.

<PropertyGroup>
  <RunAOTCompilation>true</RunAOTCompilation>
  <WasmStripILAfterAOT>true</WasmStripILAfterAOT>
</PropertyGroup>

이 설정은 라이브러리의 메서드와 앱의 메서드를 포함하여 대부분의 컴파일된 메서드에 대한 IL 코드를 제거합니다. 런타임에 .NET 인터프리터가 여전히 필요하므로 컴파일된 메서드를 모두 잘라낼 수 있는 것은 아닙니다.

트리밍 옵션에 대한 문제를 보고하려면 GitHub 리포지토리에서 dotnet/runtime 문제를 엽니다.

앱이 정상적으로 실행되지 않도록 설정하는 경우 트리밍 속성을 사용하지 않도록 설정합니다.

<WasmStripILAfterAOT>false</WasmStripILAfterAOT>

일부 모바일 디바이스 브라우저의 힙 크기

클라이언트에서 실행되고 모바일 디바이스 브라우저, 특히 iOS의 Safari를 대상으로 하는 앱을 빌드 Blazor 할 때 MSBuild 속성을 EmccMaximumHeapSize 사용하여 앱의 최대 메모리를 줄여야 할 수 있습니다. 자세한 내용은 ASP.NET Core Blazor WebAssembly 호스트 및 배포를 참조하세요.

런타임 다시 링크

Blazor WebAssembly 앱의 가장 큰 부분 중 하나는 사용자의 브라우저에서 앱에 처음 액세스할 때 브라우저가 다운로드해야 하는 WebAssembly 기반 .NET 런타임(dotnet.wasm)입니다. .NET WebAssembly 런타임을 다시 링크하면 사용되지 않는 런타임 코드가 삭제되므로 다운로드 속도가 향상됩니다.

런타임 다시 링크를 사용하려면 .NET WebAssembly 빌드 도구를 설치해야 합니다. 자세한 내용은 ASP.NET Core Blazor 도구를 참조하세요.

.NET WebAssembly 빌드 도구를 설치하면 앱이 Release 구성에 게시될 때 런타임 다시 연결이 자동으로 수행됩니다. 크기 감소는 세계화를 사용하지 않도록 설정할 때 특히 효과가 큽니다. 자세한 내용은 ASP.NET Core Blazor 세계화 및 지역화를 참조하세요.

Important

런타임 다시 연결은 보호되지 않는 한 클래스 인스턴스 JavaScript 호출 가능한 .NET 메서드를 트리밍합니다. 자세한 내용은 ASP.NET Core의 JavaScript 함수에서 .NET 메서드 호출을 참조하세요 Blazor.

단일 명령, SIMD(다중 데이터)

WebAssembly 단일 명령, SIMD(다중 데이터) 는 단일 명령을 사용하여 여러 데이터 조각에 대한 작업을 병렬로 수행하여 벡터화된 계산의 처리량을 향상시킬 수 있습니다. SIMD는 기본적으로 사용하도록 설정됩니다.

SIMD를 사용하지 않도록 설정하려면(예: SIMD를 지원하지 않는 모바일 디바이스에서 이전 브라우저 또는 브라우저를 대상으로 하는 경우) 앱의 프로젝트 파일(.csproj)에서 속성을 false 설정합니다<WasmEnableSIMD>.

<PropertyGroup>
  <WasmEnableSIMD>false</WasmEnableSIMD>
</PropertyGroup>

자세한 내용은 .NET WebAssembly 애플리케이션 구성 및 호스팅을 참조 하세요. SIMD - 단일 명령, 여러 데이터 및 지침의 버전이 지정되지 않고 최신 공개 릴리스에 적용됩니다.

WebAssembly 단일 명령, SIMD(다중 데이터) 는 단일 명령을 사용하여 여러 데이터 조각에 대한 작업을 병렬로 수행하여 벡터화된 계산의 처리량을 향상시킬 수 있습니다. SIMD는 기본적으로 사용하지 않도록 설정됩니다.

SIMD를 <WasmEnableSIMD> 사용하도록 설정하려면 앱의 프로젝트 파일(.csproj)에 속성 집합 true 을 추가합니다.

<PropertyGroup>
  <WasmEnableSIMD>true</WasmEnableSIMD>
</PropertyGroup>

자세한 내용은 .NET WebAssembly 애플리케이션 구성 및 호스팅을 참조 하세요. SIMD - 단일 명령, 여러 데이터 및 지침의 버전이 지정되지 않고 최신 공개 릴리스에 적용됩니다.

예외 처리

예외 처리는 기본적으로 사용하도록 설정됩니다. 예외 처리를 사용하지 않도록 설정하려면 앱의 false 프로젝트 파일(.csproj)에 값이 있는 속성을 추가 <WasmEnableExceptionHandling> 합니다.

<PropertyGroup>
  <WasmEnableExceptionHandling>false</WasmEnableExceptionHandling>
</PropertyGroup>

WebAssembly 예외 처리를 사용하도록 설정하려면 앱의 true 프로젝트 파일(.csproj)에 값이 있는 속성을 추가 <WasmEnableExceptionHandling> 합니다.

<PropertyGroup>
  <WasmEnableExceptionHandling>true</WasmEnableExceptionHandling>
</PropertyGroup>

추가 리소스