Trabalhando com WebAssembly e C#: técnicas avançadas e otimização

Treinador Online de Python para Iniciantes

Aprenda Python facilmente sem sobrecarga teórica. Resolva tarefas práticas com verificação automática e escreva código diretamente no navegador.

Start Course

Trabalho Avançado com WebAssembly e C#: da Teoria à Otimização

WebAssembly (Wasm) tornou-se uma tecnologia chave para executar código de alto desempenho no navegador. No ecossistema .NET, a principal ferramenta para trabalhar com Wasm é o Blazor, no entanto, para resolver problemas complexos, é necessário um profundo entendimento dos mecanismos internos. Neste artigo, abordaremos aspectos avançados: otimização do tempo de execução, transferência de estruturas de dados complexas, ajuste fino da compilação AOT e interação eficiente com JavaScript.

O artigo é destinado a desenvolvedores já familiarizados com os fundamentos do Blazor WebAssembly e que desejam obter o máximo desempenho e flexibilidade de suas aplicações.



1. Otimização de Desempenho: AOT vs JIT e Gerenciamento de Memória

Por padrão, o Blazor WebAssembly usa o interpretador .NET IL (MSIL) no navegador. Para trechos de código críticos para o desempenho, é necessário mudar para a compilação AOT (Ahead-of-Time).

Configuração da Compilação AOT

Adicione a flag <RunAOTCompilation>true</RunAOTCompilation> no arquivo de projeto (.csproj). Isso compilará seu código em bytecode Wasm nativo, acelerando a execução em 5 a 10 vezes, mas aumentará o tamanho da compilação.

<Project Sdk="Microsoft.NET.Sdk.BlazorWebAssembly">  <PropertyGroup>    <TargetFramework>net8.0</TargetFramework>    <RunAOTCompilation>true</RunAOTCompilation>  </PropertyGroup></Project>

Gerenciamento de Memória: Evite Marshalling

Cada chamada de C# para JavaScript (e vice-versa) é uma operação cara. Para transferir grandes arrays de dados, use System.Buffers.ArrayPool<T> e memória compartilhada através de MonoWasmRuntime.

using System.Buffers;using System.Runtime.InteropServices;

public class MemoryOptimizer{ public static void ProcessLargeArray(int size) { // Aluga um array do pool para evitar pressão no GC int[] buffer = ArrayPool<int>.Shared.Rent(size); try { // Seu trabalho intensivo com o array for (int i = 0; i < size; i++) { buffer[i] = i * 2; } } finally { ArrayPool<int>.Shared.Return(buffer); } }}

Perfil de Desempenho

Use as ferramentas integradas do navegador (Chrome DevTools) para criar perfil do código Wasm. Ative <WasmProfiling>true</WasmProfiling> na configuração do projeto para obter stack traces legíveis.



2. Interoperabilidade JavaScript Avançada: Transferência de Objetos Complexos e Chamadas Sem Cópia

O IJSRuntime padrão serializa objetos em JSON, o que é lento para grandes volumes de dados. Use o trabalho direto com memória através de MonoWasmRuntime e System.Runtime.InteropServices.JavaScript.

Acesso Direto à Memória JS a partir de C#

using System.Runtime.InteropServices.JavaScript;

public partial class WasmInterop{ // Importa uma função JavaScript que retorna um ponteiro para um array [JSImport("getDataPointer", "main.js")] public static partial nint GetDataPointer(int length);

public static void ProcessExternalData(int length) { nint ptr = GetDataPointer(length); // Converte o ponteiro em um array gerenciado sem cópia Span<byte> data = new Span<byte>((void*)ptr, length); // Trabalha com os dados diretamente for (int i = 0; i < data.Length; i++) { data[i] = (byte)(data[i] ^ 0xFF); // Exemplo: inversão de bits } }}

Exportação de Funções C# para Chamada a partir de JavaScript

public partial class ExportedFunctions{    [JSExport]    public static int Add(int a, int b)    {        return a + b;                

Blogs

Book Recommendations