Partilhar via


ASP.NET Core Blazor inicialização

Observação

Esta não é a versão mais recente deste artigo. Para a versão atual, consulte a versão .NET 10 deste artigo.

Advertência

Esta versão do ASP.NET Core não é mais suportada. Para obter mais informações, consulte a Política de suporte do .NET e .NET Core. Para a versão atual, consulte a versão .NET 10 deste artigo.

Este artigo explica a Blazor configuração de inicialização do aplicativo.

Para obter orientação geral sobre a configuração do aplicativo ASP.NET Core para desenvolvimento do lado do servidor, consulte Configuração em ASP.NET Core.

Processo de inicialização e configuração

O Blazor processo de inicialização é automático e assíncrono através do Blazor script (blazor.*.js), onde o marcador de posição * é:

  • web para um Blazor Web App
  • server para uma Blazor Server aplicação
  • webassembly para uma Blazor WebAssembly aplicação

O Blazor processo de inicialização é automático e assíncrono através do Blazor script (blazor.*.js), onde o marcador de posição * é:

  • server para uma Blazor Server aplicação
  • webassembly para uma Blazor WebAssembly aplicação

Para consultar a localização do script, veja a estrutura do projeto do ASP.NET Core Blazor.

Para iniciar manualmente Blazor:

Blazor Web App:

  • Adicione um atributo e um autostart="false" valor à Blazor<script> tag .
  • Coloque um script que chama Blazor.start() após a Blazor<script> tag e dentro da tag de fechamento </body> .
  • Coloque as opções de renderização estática do lado do servidor (SSR estático) na propriedade ssr.
  • Coloque opções de circuito Blazor-SignalR do lado do servidor na propriedade circuit.
  • Coloque as opções do WebAssembly do cliente no campo webAssembly.
<script src="{BLAZOR SCRIPT}" autostart="false"></script>
<script>
  ...
  Blazor.start({
    ssr: {
      ...
    },
    circuit: {
      ...
    },
    webAssembly: {
      ...
    }
  });
  ...
</script>

Autónomo Blazor WebAssembly e Blazor Server:

  • Adicione um atributo e um autostart="false" valor à Blazor<script> tag .
  • Coloque um script que chama Blazor.start() após a Blazor<script> tag e dentro da tag de fechamento </body> .
  • Você pode fornecer opções adicionais no Blazor.start() parâmetro.
<script src="{BLAZOR SCRIPT}" autostart="false"></script>
<script>
  ...
  Blazor.start({
    ...
  });
  ...
</script>

No exemplo anterior, o marcador {BLAZOR SCRIPT} é o caminho de script Blazor e o nome do ficheiro. Para consultar a localização do script, veja a estrutura do projeto do ASP.NET Core Blazor.

Inicializadores JavaScript

Os inicializadores JavaScript (JS) executam a lógica antes e depois do carregamento de um Blazor aplicativo. JS Os inicializadores são úteis nos seguintes cenários:

  • Personalizar a forma como uma Blazor aplicação é carregada.
  • Inicializar bibliotecas antes de Blazor iniciar.
  • Configuração das definições Blazor.

JS Os inicializadores são detetados como parte do processo de compilação e importados automaticamente. O uso de inicializadores geralmente elimina a necessidade JS ao usar Razor classes (RCLs).

Para definir um JS inicializador, adicione um JS módulo ao projeto chamado {NAME}.lib.module.js, onde o marcador {NAME} representa o nome do assembly, o nome da biblioteca ou o identificador do pacote. Coloque o arquivo na raiz da Web do projeto, que normalmente é a wwwroot pasta.

Para Blazor Web Apps:

  • beforeWebStart(options): Invocado antes do início de Blazor Web App. Por exemplo, beforeWebStart é usado para personalizar o processo de carregamento, o nível de log e outras opções. Recebe opções da Web Blazor(options).
  • afterWebStarted(blazor): Chamado depois de todas as beforeWebStart promessas resolvidas. Por exemplo, afterWebStarted pode ser usado para registrar Blazor ouvintes de eventos e tipos de eventos personalizados. A Blazor instância é passada para afterWebStarted como um argumento (blazor).
  • beforeServerStart(options, extensions): Chamado antes do primeiro tempo de execução do servidor ser iniciado. Recebe SignalR opções de início de circuito (options) e quaisquer extensões (extensions) adicionadas no momento da publicação.
  • afterServerStarted(blazor): Chamado depois que o primeiro runtime do Interactive Server é iniciado.
  • beforeWebAssemblyStart(options, extensions): Chamado antes do runtime WebAssembly interativo ser iniciado. Recebe as Blazor opções (options) e quaisquer extensões (extensions) adicionadas durante a publicação. Por exemplo, as opções podem especificar o uso de um carregador de recursos de inicialização personalizado.
  • afterWebAssemblyStarted(blazor): Chamado após o runtime do Interactive WebAssembly ser iniciado.

Observação

Os inicializadores herdados JS (beforeStart, afterStarted) não são invocados por padrão em um Blazor Web App. Você pode habilitar os inicializadores herdados para serem executados com a enableClassicInitializers opção. No entanto, a execução do inicializador herdado é imprevisível.

<script>
  Blazor.start({ enableClassicInitializers: true });
</script>

Devido a um bug de estrutura no .NET 8 e 9 (dotnet/aspnetcore #54049), o Blazor script deve ser iniciado manualmente quando beforeWebAssemblyStart(options, extensions) ou afterWebAssemblyStarted(blazor) são chamados. Se o aplicativo de servidor ainda não iniciou Blazor manualmente com uma configuração WebAssembly (webAssembly: {...}), atualize o componente App no projeto de servidor com o seguinte.

No Components/App.razor, remova a tag existente Blazor<script> :

- <script src="_framework/blazor.web.js"></script>

Substitua a tag <script> pela seguinte marcação iniciando Blazor manualmente com uma configuração de WebAssembly (webAssembly: {...}):

<script src="_framework/blazor.web.js" autostart="false"></script>
<script>
    Blazor.start({
        webAssembly: {}
    });
</script>

Para as aplicações Blazor Server, Blazor WebAssemblye Blazor Hybrid:

  • beforeStart(options, extensions): Chamado antes de Blazor começar. Por exemplo, beforeStart é usado para personalizar o processo de carregamento, nível de log e outras opções específicas para o modelo de hospedagem.
    • Do lado do cliente, beforeStart recebe as opções (Blazor) e quaisquer extensões (options) adicionadas durante a publicação. Por exemplo, as opções podem especificar o uso de um carregador de recursos de inicialização personalizado.
    • No lado do servidor, beforeStart recebe as opções de início de circuito SignalR (options).
    • Em um BlazorWebView, nenhuma opção é passada.
  • afterStarted(blazor): Chamado depois de Blazor estiver pronto para receber chamadas de JS. Por exemplo, afterStarted é usado para inicializar bibliotecas fazendo JS chamadas de interoperabilidade e registrando elementos personalizados. A Blazor instância é passada para afterStarted como um argumento (blazor).

Chamadas de retorno adicionais do runtime .NET WebAssembly:

  • onRuntimeConfigLoaded(config): Chamado quando a configuração de inicialização é baixada. Permite que o aplicativo modifique parâmetros (config) antes do início do tempo de execução (o parâmetro é MonoConfig de dotnet.d.ts):

    export function onRuntimeConfigLoaded(config) {
      // Sample: Enable startup diagnostic logging when the URL contains 
      // parameter debug=1
      const params = new URLSearchParams(location.search);
      if (params.get("debug") == "1") {
        config.diagnosticTracing = true;
      }
    }
    
  • onRuntimeReady({ getAssemblyExports, getConfig }): Chamado após o runtime do .NET WebAssembly ter iniciado (o parâmetro é RuntimeAPI de dotnet.d.ts):

    export function onRuntimeReady({ getAssemblyExports, getConfig }) {
      // Sample: After the runtime starts, but before Main method is called, 
      // call [JSExport]ed method.
      const config = getConfig();
      const exports = await getAssemblyExports(config.mainAssemblyName);
      exports.Sample.Greet();
    }
    

Ambos os callbacks podem retornar um Promise, e aguarda-se a promessa antes de continuar a inicialização.

Para o nome do arquivo:

  • Se os JS inicializadores forem consumidos como um recurso estático no projeto, use o formato {ASSEMBLY NAME}.lib.module.js, onde o espaço reservado {ASSEMBLY NAME} é o nome do assembly da aplicação. Por exemplo, nomeie o arquivo BlazorSample.lib.module.js de um projeto com um nome de assembly de BlazorSample. Coloque o arquivo na pasta do wwwroot aplicativo.
  • Se os JS inicializadores forem utilizados num RCL, use o formato {LIBRARY NAME/PACKAGE ID}.lib.module.js, onde o placeholder {LIBRARY NAME/PACKAGE ID} é o nome da biblioteca do projeto ou o identificador do pacote (<PackageId> valor no ficheiro de projeto da biblioteca). Por exemplo, nomeie o arquivo RazorClassLibrary1.lib.module.js para um RCL com um identificador de pacote de RazorClassLibrary1. Coloque o arquivo na pasta da wwwroot biblioteca.

Para Blazor Web Apps:

O exemplo a seguir demonstra JS inicializadores que carregam scripts personalizados antes e depois de Blazor Web App ter iniciado, acrescentando-os a <head> em beforeWebStart e afterWebStarted:

export function beforeWebStart() {
  var customScript = document.createElement('script');
  customScript.setAttribute('src', 'beforeStartScripts.js');
  document.head.appendChild(customScript);
}

export function afterWebStarted() {
  var customScript = document.createElement('script');
  customScript.setAttribute('src', 'afterStartedScripts.js');
  document.head.appendChild(customScript);
}

O exemplo anterior beforeWebStart garante apenas que o script personalizado seja carregado antes Blazor de iniciar. Isso não garante que as promessas esperadas no script completem sua execução antes de Blazor começar.

Para as aplicações Blazor Server, Blazor WebAssemblye Blazor Hybrid:

O exemplo a seguir demonstra JS inicializadores que carregam scripts personalizados antes e depois de Blazor ter começado, acrescentando-os ao <head> em beforeStart e afterStarted:

export function beforeStart(options, extensions) {
  var customScript = document.createElement('script');
  customScript.setAttribute('src', 'beforeStartScripts.js');
  document.head.appendChild(customScript);
}

export function afterStarted(blazor) {
  var customScript = document.createElement('script');
  customScript.setAttribute('src', 'afterStartedScripts.js');
  document.head.appendChild(customScript);
}

O exemplo anterior beforeStart garante apenas que o script personalizado seja carregado antes Blazor de iniciar. Isso não garante que as promessas esperadas no script completem sua execução antes de Blazor começar.

Observação

As aplicações MVC e Razor Pages não carregam JS inicializadores automaticamente. No entanto, o código do desenvolvedor pode incluir um script para buscar o manifesto da aplicação e acionar a carga dos JS inicializadores.

Para obter exemplos de JS inicializadores, consulte os seguintes recursos:

Observação

Os links de documentação para a fonte de referência do .NET geralmente carregam a ramificação padrão do repositório, que representa o desenvolvimento atual para a próxima versão do .NET. Para selecionar uma tag para uma versão específica, use a lista suspensa Alternar entre ramificações ou tags. Para obter mais informações, consulte Como selecionar uma marca de versão do código-fonte do ASP.NET Core (dotnet/AspNetCore.Docs #26205).

Garantir que as bibliotecas sejam carregadas em uma ordem específica

Anexe scripts personalizados a <head> em beforeStart e afterStarted na ordem em que devem ser carregados.

O exemplo a seguir carrega script1.js antes de script2.js e script3.js antes de script4.js:

export function beforeStart(options, extensions) {
    var customScript1 = document.createElement('script');
    customScript1.setAttribute('src', 'script1.js');
    document.head.appendChild(customScript1);

    var customScript2 = document.createElement('script');
    customScript2.setAttribute('src', 'script2.js');
    document.head.appendChild(customScript2);
}

export function afterStarted(blazor) {
    var customScript1 = document.createElement('script');
    customScript1.setAttribute('src', 'script3.js');
    document.head.appendChild(customScript1);

    var customScript2 = document.createElement('script');
    customScript2.setAttribute('src', 'script4.js');
    document.head.appendChild(customScript2);
}

Importar módulos adicionais

Use instruções de nível import superior no JS arquivo de inicializadores para importar módulos adicionais.

additionalModule.js:

export function logMessage() {
  console.log('logMessage is logging');
}

JS No arquivo de inicializadores (.lib.module.js):

import { logMessage } from "/additionalModule.js";

export function beforeStart(options, extensions) {
  ...

  logMessage();
}

Importar mapa

Os mapas de importação são suportados pelo ASP.NET Core e Blazorpelo .

Inicializar Blazor quando o documento estiver pronto

O exemplo a seguir começa Blazor quando o documento está pronto:

<script src="{BLAZOR SCRIPT}" autostart="false"></script>
<script>
  document.addEventListener("DOMContentLoaded", function() {
    Blazor.start();
  });
</script>

No exemplo anterior, o marcador {BLAZOR SCRIPT} é o caminho de script Blazor e o nome do ficheiro. Para consultar a localização do script, veja a estrutura do projeto do ASP.NET Core Blazor.

Encadeamento para o Promise que resulta de um início feito manualmente

Para executar tarefas adicionais, como JS inicialização de interoperabilidade, use then para fazer encadeamento com o Promise que resulta de um início manual Blazor da aplicação.

<script src="{BLAZOR SCRIPT}" autostart="false"></script>
<script>
  Blazor.start().then(function () {
    ...
  });
</script>

No exemplo anterior, o marcador {BLAZOR SCRIPT} é o caminho de script Blazor e o nome do ficheiro. Para consultar a localização do script, veja a estrutura do projeto do ASP.NET Core Blazor.

Observação

Para que uma biblioteca processe automaticamente tarefas adicionais após Blazor ter iniciado, use um inicializador JavaScript. O uso de um JS inicializador não exige que o consumidor da biblioteca encadeie JS chamadas para o início manual de Blazor.

Carregar recursos de inicialização do lado do cliente

Quando um aplicativo é carregado no navegador, o aplicativo baixa recursos de inicialização do servidor:

  • Código JavaScript para inicializar o aplicativo
  • Tempo de execução e assemblies do .NET
  • Dados específicos da localidade

Personalize como esses recursos de inicialização são carregados usando a loadBootResource API. A loadBootResource função substitui o mecanismo de carregamento de recursos de inicialização integrado. Use loadBootResource para os seguintes cenários:

  • Carregue recursos estáticos, como dados de fuso horário ou dotnet.wasm, a partir de uma CDN.
  • Carregue assemblies compactados usando uma solicitação HTTP e descompacte-os no cliente para hosts que não suportam a obtenção de conteúdo compactado do servidor.
  • Atribuir um nome alternativo aos recursos, redirecionando cada solicitação fetch para um novo nome.

Observação

As fontes externas devem retornar os cabeçalhos CORS (Cross-Origin Resource Sharing) necessários para navegadores para permitir o carregamento de recursos entre origens. As CDNs geralmente fornecem os cabeçalhos necessários.

loadBootResource Os parâmetros aparecem na tabela a seguir.

Parâmetro Descrição
type O tipo do recurso. Os tipos admissíveis incluem: assembly, pdb, dotnetjs, dotnetwasme timezonedata. Você só precisa especificar tipos para comportamentos personalizados. Os tipos não especificados a loadBootResource são carregados pela estrutura de acordo com os seus comportamentos de carregamento padrão. O dotnetjs recurso de inicialização (dotnet.*.js) deve retornar null para o comportamento de carregamento padrão ou um URI para a origem do dotnetjs recurso de inicialização.
name O nome do recurso.
defaultUri O URI relativo ou absoluto do recurso.
integrity A cadeia de caracteres de integridade que representa o conteúdo esperado na resposta.

A loadBootResource função pode retornar uma cadeia de caracteres URI para substituir o processo de carregamento. No exemplo a seguir, os seguintes arquivos de bin/Release/{TARGET FRAMEWORK}/wwwroot/_framework são servidos a partir de uma CDN em https://cdn.example.com/blazorwebassembly/{VERSION}/:

  • dotnet.*.js
  • dotnet.wasm
  • Dados de fuso horário

O {TARGET FRAMEWORK} espaço reservado é o apelido do framework de destino (por exemplo, net7.0). O marcador {VERSION} é a versão da estrutura partilhada (por exemplo, 7.0.0).

Blazor Web App:

<script src="{BLAZOR SCRIPT}" autostart="false"></script>
<script>
  Blazor.start({
    webAssembly: {
      loadBootResource: function (type, name, defaultUri, integrity) {
        console.log(`Loading: '${type}', '${name}', '${defaultUri}', '${integrity}'`);
        switch (type) {
          case 'dotnetjs':
          case 'dotnetwasm':
          case 'timezonedata':
            return `https://cdn.example.com/blazorwebassembly/{VERSION}/${name}`;
        }
      }
    }
  });
</script>

Blazor WebAssembly: independente

<script src="{BLAZOR SCRIPT}" autostart="false"></script>
<script>
  Blazor.start({
    loadBootResource: function (type, name, defaultUri, integrity) {
      console.log(`Loading: '${type}', '${name}', '${defaultUri}', '${integrity}'`);
      switch (type) {
        case 'dotnetjs':
        case 'dotnetwasm':
        case 'timezonedata':
          return `https://cdn.example.com/blazorwebassembly/{VERSION}/${name}`;
      }
    }
  });
</script>

No exemplo anterior, o marcador {BLAZOR SCRIPT} é o caminho de script Blazor e o nome do ficheiro. Para consultar a localização do script, veja a estrutura do projeto do ASP.NET Core Blazor.

Para personalizar mais do que apenas as URLs para recursos de inicialização, a loadBootResource função pode chamar fetch diretamente e retornar o resultado. O exemplo a seguir adiciona um cabeçalho HTTP personalizado às solicitações de saída. Para manter o comportamento padrão de verificação de integridade, passe pelo integrity parâmetro.

Blazor Web App:

<script src="{BLAZOR SCRIPT}" autostart="false"></script>
<script>
  Blazor.start({
    webAssembly: {
      loadBootResource: function (type, name, defaultUri, integrity) {
        if (type == 'dotnetjs') {
          return null;
        } else {
          return fetch(defaultUri, {
            cache: 'no-cache',
            integrity: integrity,
            headers: { 'Custom-Header': 'Custom Value' }
          });
        }
      }
    }
  });
</script>

Blazor WebAssembly: independente

<script src="{BLAZOR SCRIPT}" autostart="false"></script>
<script>
  Blazor.start({
    loadBootResource: function (type, name, defaultUri, integrity) {
      if (type == 'dotnetjs') {
        return null;
      } else {
        return fetch(defaultUri, {
          cache: 'no-cache',
          integrity: integrity,
          headers: { 'Custom-Header': 'Custom Value' }
        });
      }
    }
  });
</script>

No exemplo anterior, o marcador {BLAZOR SCRIPT} é o caminho de script Blazor e o nome do ficheiro. Para consultar a localização do script, veja a estrutura do projeto do ASP.NET Core Blazor.

Quando a loadBootResource função retorna null, Blazor usa o comportamento de carregamento padrão para o recurso. Por exemplo, o código anterior retorna null para o dotnetjs recurso de inicialização (dotnet.*.js) porque o dotnetjs recurso de inicialização deve retornar null para o comportamento de carregamento padrão ou um URI para a origem do recurso de dotnetjs inicialização.

A loadBootResource função também pode retornar uma Response promessa. Para obter um exemplo, consulte Hospedar e implantar ASP.NET Core Blazor WebAssembly.

Para obter mais informações, consulte ASP.NET Core Blazor WebAssembly falhas de caching e verificação de integridade.

Cabeçalhos de controle em código C#

Controle cabeçalhos na inicialização em código C# usando as seguintes abordagens.

Nos exemplos a seguir, uma Política de Segurança de Conteúdo (CSP) é aplicada ao aplicativo por meio de um cabeçalho CSP. O {POLICY STRING} placeholder é a cadeia de caracteres de política CSP. Para obter mais informações sobre CSPs, consulte Impor uma política de segurança de conteúdo para ASP.NET Core Blazor.

Observação

Os cabeçalhos não podem ser definidos após o início da resposta. As abordagens nesta seção só definem cabeçalhos antes do início da resposta, portanto, as abordagens descritas aqui são seguras. Para obter mais informações, consulte IHttpContextAccessor/HttpContext em aplicações ASP.NET Core Blazor.

Cenários do lado do servidor e cenários pré-renderizados do lado do cliente

Use ASP.NET Core Middleware para controlar a coleção de cabeçalhos.

No ficheiro Program:

Em Startup.Configure de Startup.cs:

app.Use(async (context, next) =>
{
    context.Response.Headers.Append("Content-Security-Policy", "{POLICY STRING}");
    await next();
});

O exemplo anterior usa middleware embutido, mas você também pode criar uma classe de middleware personalizada e chamar o middleware com um método de extensão no Program arquivo. Para obter mais informações, consulte Write custom ASP.NET Core middleware.

Desenvolvimento do lado do cliente sem pré-renderização

Passe StaticFileOptions para MapFallbackToFile, que especifica os cabeçalhos de resposta na fase OnPrepareResponse.

No arquivo Program do lado do servidor:

Em Startup.Configure de Startup.cs:

var staticFileOptions = new StaticFileOptions
{
    OnPrepareResponse = context =>
    {
        context.Context.Response.Headers.Append("Content-Security-Policy", 
            "{POLICY STRING}");
    }
};

...

app.MapFallbackToFile("index.html", staticFileOptions);

Indicadores de carga no lado do cliente

Um indicador de carregamento mostra que o aplicativo está carregando normalmente e que o usuário deve esperar até que o carregamento seja concluído.

Blazor Web App indicador de carga

O indicador de carregamento usado em Blazor WebAssembly aplicativos não está presente em um aplicativo criado a partir do Blazor Web App modelo de projeto. Normalmente, um indicador de carregamento não é desejável para componentes interativos do WebAssembly porque Blazor Web Apppré-renderizam componentes do lado do cliente no servidor para tempos de carregamento iniciais rápidos. Para situações de modo de renderização misto, a estrutura ou o código do desenvolvedor também deve ter cuidado para evitar os seguintes problemas:

  • Mostrando vários indicadores de carregamento na mesma página renderizada.
  • Descartando inadvertidamente conteúdo pré-renderizado enquanto o runtime do .NET WebAssembly está a carregar.

Uma versão futura do .NET pode fornecer um indicador de carregamento baseado em estrutura. Enquanto isso, podes adicionar um indicador de carregamento personalizado a um Blazor Web App.

Renderização interativa de WebAssembly para cada componente com pré-renderização

Este cenário se aplica à renderização Interactive WebAssembly por componente (@rendermode InteractiveWebAssembly aplicada a componentes individuais).

Crie um componente ContentLoading na pasta Layout da aplicação .Client que chama OperatingSystem.IsBrowser:

  • Quando false, exiba um indicador de carga.
  • Quando true, renderize o conteúdo do componente solicitado.

Para carregar estilos CSS para o indicador, adicione os estilos ao conteúdo <head> com o componente HeadContent. Para obter mais informações, consulte Controlar o conteúdo do cabeçote em aplicativos ASP.NET CoreBlazor.

Layout/ContentLoading.razor:

@if (!RendererInfo.IsInteractive)
{
    <!-- OPTIONAL ...
    <HeadContent>
        <style>
            ...
        </style>
    </HeadContent>
    -->
    <progress id="loadingIndicator" aria-label="Content loading…"></progress>
}
else
{
    @ChildContent
}

@code {
    [Parameter]
    public RenderFragment? ChildContent { get; set; }
}
@if (!OperatingSystem.IsBrowser())
{
    <!-- OPTIONAL ...
    <HeadContent>
        <style>
            ...
        </style>
    </HeadContent>
    -->
    <progress id="loadingIndicator" aria-label="Content loading…"></progress>
}
else
{
    @ChildContent
}

@code {
    [Parameter]
    public RenderFragment? ChildContent { get; set; }
}

Se você ainda não tiver uma Layout pasta no .Client projeto, adicione o namespace da Layout pasta ao _Imports.razor arquivo. No exemplo a seguir, o namespace do projeto é BlazorSample.Client:

@using BlazorSample.Client.Layout

Num componente que adota a renderização WebAssembly Interactivo, envolva a marcação de Razor com o componente ContentLoading. O exemplo a seguir demonstra a abordagem com o Counter componente de um aplicativo criado a partir do Blazor Web App modelo de projeto.

Pages/Counter.razor:

@page "/counter"
@rendermode InteractiveWebAssembly

<PageTitle>Counter</PageTitle>

<ContentLoading>
    <h1>Counter</h1>

    <p role="status">Current count: @currentCount</p>

    <button class="btn btn-primary" @onclick="IncrementCount">Click me</button>
</ContentLoading>

@code {
    private int currentCount = 0;

    private void IncrementCount()
    {
        currentCount++;
    }
}

Renderização Global e Interativa de WebAssembly com pré-renderização

Este cenário aplica-se à renderização global do Interactive WebAssembly com pré-renderização (@rendermode="InteractiveWebAssembly" nos componentes HeadOutlet e Routes no componente App).

Crie um componente ContentLoading na pasta Layout da aplicação .Client que chama RendererInfo.IsInteractive:

  • Quando false, exiba um indicador de carga.
  • Quando true, renderize o conteúdo do componente solicitado.

Para carregar estilos CSS para o indicador, adicione os estilos ao conteúdo <head> com o componente HeadContent. Para obter mais informações, consulte Controlar o conteúdo do cabeçote em aplicativos ASP.NET CoreBlazor.

Layout/ContentLoading.razor:

@if (!RendererInfo.IsInteractive)
{
    <!-- OPTIONAL ...
    <HeadContent>
        <style>
            ...
        </style>
    </HeadContent>
    -->
    <progress id="loadingIndicator" aria-label="Content loading…"></progress>
}
else
{
    @ChildContent
}

@code {
    [Parameter]
    public RenderFragment? ChildContent { get; set; }
}
@if (!OperatingSystem.IsBrowser())
{
    <!-- OPTIONAL ...
    <HeadContent>
        <style>
            ...
        </style>
    </HeadContent>
    -->
    <progress id="loadingIndicator" aria-label="Content loading…"></progress>
}
else
{
    @ChildContent
}

@code {
    [Parameter]
    public RenderFragment? ChildContent { get; set; }
}

Se você ainda não tiver uma Layout pasta no .Client projeto, adicione o namespace da Layout pasta ao _Imports.razor arquivo. No exemplo a seguir, o namespace do projeto é BlazorSample.Client:

@using BlazorSample.Client.Layout

No componente MainLayout (Layout/MainLayout.razor) do projeto .Client, envolva a propriedade Body (@Body) com o componente ContentLoading:

Em Layout/MainLayout.razor:

+ <ContentLoading>
    @Body
+ </ContentLoading>

Renderização interativa global do WebAssembly sem pré-renderização

Este cenário aplica-se à renderização global de WebAssembly interativo sem pré-renderização (nos componentes @rendermode="new InteractiveWebAssemblyRenderMode(prerender: false)" e HeadOutlet, e no componente Routes do App).

Adicione um inicializador JavaScript ao aplicativo. No exemplo de nome de arquivo do módulo JavaScript a seguir, o espaço reservado {ASSEMBLY NAME} é o nome do assembly do projeto do servidor (por exemplo, BlazorSample). A wwwroot pasta onde o módulo é colocado é a wwwroot pasta no projeto do lado do servidor, não o .Client projeto.

O exemplo a seguir usa um progress indicador que não indica o progresso real da entrega de recursos de inicialização do lado do cliente para o cliente, mas serve como uma abordagem geral para desenvolvimento adicional se você quiser que o indicador de progresso mostre o progresso real do carregamento dos recursos de inicialização do aplicativo.

wwwroot/{ASSEMBLY NAME}.lib.module.js:

export function beforeWebStart(options) {
  var progress = document.createElement("progress");
  progress.id = 'loadingIndicator';
  progress.ariaLabel = 'Blazor loading…';
  progress.style = 'position:absolute;top:50%;left:50%;margin-right:-50%;' +
    'transform:translate(-50%,-50%);';
  document.body.appendChild(progress);
}

export function afterWebAssemblyStarted(blazor) {
  var progress = document.getElementById('loadingIndicator');
  progress.remove();
}

Devido a um bug de estrutura no .NET 8 e 9 (dotnet/aspnetcore #54049), o Blazor script deve ser iniciado manualmente. Se o aplicativo de servidor ainda não iniciou Blazor manualmente com uma configuração WebAssembly (webAssembly: {...}), atualize o componente App no projeto de servidor com o seguinte.

No Components/App.razor, remova a tag existente Blazor<script> :

- <script src="_framework/blazor.web.js"></script>

Substitua a tag <script> pela seguinte marcação iniciando Blazor manualmente com uma configuração de WebAssembly (webAssembly: {...}):

<script src="_framework/blazor.web.js" autostart="false"></script>
<script>
    Blazor.start({
        webAssembly: {}
    });
</script>

Se você notar um pequeno atraso entre a remoção do indicador de carregamento e a renderização da primeira página, poderá garantir a remoção do indicador após a renderização chamando a remoção do indicador no método de ciclo de vida dos componentes OnAfterRenderAsync ou . Para obter mais informações e um exemplo de código, consulte Documentar uma abordagem para um indicador de carregamento que funciona com o Interactive WebAssembly global sem pré-renderização (dotnet/AspNetCore.Docs #35111).

Blazor WebAssembly progresso do carregamento do aplicativo

O modelo de projeto contém SVG (Scalable Vetor Graphics) e indicadores de texto que mostram o progresso do carregamento do aplicativo.

Os indicadores de progresso são implementados com HTML e CSS usando duas propriedades personalizadas CSS (variáveis) fornecidas por Blazor:

  • --blazor-load-percentage: A percentagem de ficheiros da aplicação carregados.
  • --blazor-load-percentage-text: A percentagem de ficheiros da aplicação carregados, arredondada para o número inteiro mais próximo.

Usando as variáveis CSS anteriores, você pode criar indicadores de progresso personalizados que correspondam ao estilo do seu aplicativo.

No exemplo a seguir:

  • resourcesLoaded é uma contagem instantânea dos recursos carregados durante a inicialização do aplicativo.
  • totalResources é o número total de recursos a carregar.
const percentage = resourcesLoaded / totalResources * 100;
document.documentElement.style.setProperty(
  '--blazor-load-percentage', `${percentage}%`);
document.documentElement.style.setProperty(
  '--blazor-load-percentage-text', `"${Math.floor(percentage)}%"`);

O indicador de progresso da rodada padrão é implementado em HTML no wwwroot/index.html arquivo:

<div id="app">
    <svg class="loading-progress">
        <circle r="40%" cx="50%" cy="50%" />
        <circle r="40%" cx="50%" cy="50%" />
    </svg>
    <div class="loading-progress-text"></div>
</div>

Para revisar a marcação e o estilo do modelo de projeto para os indicadores de progresso padrão, consulte a fonte de referência ASP.NET Core:

Observação

Os links de documentação para a fonte de referência do .NET geralmente carregam a ramificação padrão do repositório, que representa o desenvolvimento atual para a próxima versão do .NET. Para selecionar uma tag para uma versão específica, use a lista suspensa Alternar entre ramificações ou tags. Para obter mais informações, consulte Como selecionar uma marca de versão do código-fonte do ASP.NET Core (dotnet/AspNetCore.Docs #26205).

Em vez de usar o indicador de progresso de rodada padrão, o exemplo a seguir mostra como implementar um indicador de progresso linear.

Adicione os seguintes estilos a wwwroot/css/app.css:

.linear-progress {
    background: silver;
    width: 50vw;
    margin: 20% auto;
    height: 1rem;
    border-radius: 10rem;
    overflow: hidden;
    position: relative;
}

.linear-progress:after {
    content: '';
    position: absolute;
    inset: 0;
    background: blue;
    scale: var(--blazor-load-percentage, 0%) 100%;
    transform-origin: left top;
    transition: scale ease-out 0.5s;
}

Uma variável CSS (var(...)) é usada para passar o valor de --blazor-load-percentage para a propriedade scale de um pseudoelemento azul que indica o progresso do carregamento dos arquivos do aplicativo. À medida que o aplicativo carrega, --blazor-load-percentage é atualizado automaticamente, o que altera dinamicamente a representação visual do indicador de progresso.

No wwwroot/index.html, remova o indicador redondo padrão do SVG em <div id="app">...</div> e substitua-o pela seguinte marcação:

<div class="linear-progress"></div>

Configurar o tempo de execução do .NET WebAssembly

Em cenários de programação avançada, a função configureRuntime com o construtor de host de execução dotnet é usada para configurar o tempo de execução do .NET WebAssembly. Por exemplo, dotnet.withEnvironmentVariable define uma variável de ambiente que:

  • Configura o tempo de execução do .NET WebAssembly.
  • Altera o comportamento de uma biblioteca C.

Observação

Uma solicitação de documentação está pendente no dotnet/runtime repositório GitHub para obter mais informações sobre variáveis de ambiente que configuram o tempo de execução do .NET WebAssembly ou afetam o comportamento das bibliotecas C. Embora a solicitação de documentação esteja pendente, mais informações e links cruzados para recursos adicionais estão disponíveis na solicitação, Pergunta/solicitação de documentação sobre o .NET WASM runtime env vars (dotnet/runtime #98225).

A configureRuntime função também pode ser usada para permitir a integração com um criador de perfil do navegador.

Para os marcadores nos exemplos a seguir que definem uma variável de ambiente:

  • O espaço reservado {BLAZOR SCRIPT} é o caminho e o nome do ficheiro do script Blazor. Para consultar a localização do script, veja a estrutura do projeto do ASP.NET Core Blazor.
  • O {NAME} marcador é o nome da variável de ambiente.
  • O {VALUE} marcador de posição é o valor da variável de ambiente.

Blazor Web App:

<script src="{BLAZOR SCRIPT}" autostart="false"></script>
<script>
  Blazor.start({
    webAssembly: {
      configureRuntime: dotnet => {
        dotnet.withEnvironmentVariable("{NAME}", "{VALUE}");
      }
    }
  });
</script>

Blazor WebAssembly: independente

<script src="{BLAZOR SCRIPT}" autostart="false"></script>
<script>
  Blazor.start({
    configureRuntime: dotnet => {
      dotnet.withEnvironmentVariable("{NAME}", "{VALUE}");
    }
  });
</script>

Observação

A instância de runtime do .NET pode ser acedida usando a API do runtime do .NET WebAssembly (Blazor.runtime). Por exemplo, a configuração de compilação do aplicativo pode ser obtida usando Blazor.runtime.runtimeBuildInfo.buildConfiguration.

Para obter mais informações sobre a configuração de tempo de execução do .NET WebAssembly, consulte o arquivo de definição TypeScript do tempo de execução (dotnet.d.ts) no dotnet/runtime repositório GitHub.

Observação

Os links de documentação para a fonte de referência do .NET geralmente carregam a ramificação padrão do repositório, que representa o desenvolvimento atual para a próxima versão do .NET. Para selecionar uma tag para uma versão específica, use a lista suspensa Alternar entre ramificações ou tags. Para obter mais informações, consulte Como selecionar uma marca de versão do código-fonte do ASP.NET Core (dotnet/AspNetCore.Docs #26205).

Desativar a navegação avançada e o tratamento de formulários

Esta seção aplica-se a Blazor Web Apps.

Para desativar a navegação aprimorada e o tratamento de formulários, defina disableDomPreservation como true para Blazor.start.

<script src="{BLAZOR SCRIPT}" autostart="false"></script>
<script>
  Blazor.start({
    ssr: { disableDomPreservation: true }
  });
</script>

No exemplo anterior, o marcador {BLAZOR SCRIPT} é o caminho de script Blazor e o nome do ficheiro. Para consultar a localização do script, veja a estrutura do projeto do ASP.NET Core Blazor.

Recursos adicionais