Поделиться через


ASP.NET Core Blazor запуск

Примечание.

Это не последняя версия этой статьи. В текущем выпуске см. версию этой статьи на .NET 9.

Предупреждение

Эта версия ASP.NET Core больше не поддерживается. Дополнительные сведения см. в политике поддержки .NET и .NET Core. В текущем выпуске см . версию .NET 9 этой статьи.

Внимание

Эта информация относится к предварительному выпуску продукта, который может быть существенно изменен до его коммерческого выпуска. Майкрософт не предоставляет никаких гарантий, явных или подразумеваемых, относительно приведенных здесь сведений.

В текущем выпуске см. статью о версии .NET 9.

В этой статье объясняется Blazor конфигурация запуска приложения.

Общие рекомендации по настройке приложений ASP.NET Core для разработки на стороне сервера см. в разделе "Конфигурация" в ASP.NET Core.

Процесс запуска и настройка

Процесс запуска Blazor осуществляется автоматически и асинхронно с помощью скрипта Blazor (blazor.*.js), где плейсхолдер *:

  • web для a Blazor Web App
  • server Blazor Server для приложения
  • webassembly для Blazor WebAssembly приложения

Процесс Blazor запуска является автоматическим и асинхронным с помощью скрипта Blazor (blazor.*.js), где * заполнитель:

  • server Blazor Server для приложения
  • webassembly для Blazor WebAssembly приложения

Сведения о расположении скрипта см. в разделе Blazor проекта Core.

Чтобы запустить Blazorвручную:

Blazor Web App:

  • autostart="false" Добавьте атрибут и значение в Blazor<script> тег.
  • Разместите скрипт, который вызывает Blazor.start(), после тега Blazor<script> и внутри закрывающего тега </body>.
  • Поместите параметры статической серверной отрисовки (SSR) в свойство ssr.
  • Поместите серверные Blazor—SignalR параметры контура в свойство circuit.
  • Поместите параметры клиентской WebAssembly в свойство webAssembly.
<script src="{BLAZOR SCRIPT}" autostart="false"></script>
<script>
  ...
  Blazor.start({
    ssr: {
      ...
    },
    circuit: {
      ...
    },
    webAssembly: {
      ...
    }
  });
  ...
</script>

Автономные Blazor WebAssembly и Blazor Server:

  • autostart="false" Добавьте атрибут и значение в Blazor<script> тег.
  • Разместите скрипт, который вызывает Blazor.start(), после тега Blazor<script> и внутри закрывающего тега </body>.
  • Дополнительные параметры можно указать в параметре Blazor.start() .
<script src="{BLAZOR SCRIPT}" autostart="false"></script>
<script>
  ...
  Blazor.start({
    ...
  });
  ...
</script>

В предыдущем примере заполнитель {BLAZOR SCRIPT} — это путь к скрипту и имя файла Blazor. Смотрите информацию о расположении скрипта в разделе структура проекта ASP.NET Core.

Инициализаторы JavaScript

Инициализаторы JavaScript (JS) выполняют логику до и после загрузки приложения Blazor. Инициализаторы JS полезны в следующих сценариях:

  • Настройка загрузки приложения Blazor.
  • Инициализация библиотек перед запуском Blazor.
  • Настройка параметров Blazor.

JS инициализаторы обнаруживаются в процессе сборки и импортируются автоматически. При использовании инициализаторов JS часто не приходится вручную активировать функции скриптов из приложения, если используются библиотеки классов Razor (RCL).

Чтобы определить инициализатор JS, добавьте в проект модуль JS с именем {NAME}.lib.module.js, где заполнитель {NAME} — это имя сборки, имя библиотеки или идентификатор пакета. Поместите файл в корневой каталог проекта. Обычно это папка wwwroot.

Для Blazor Web Apps:

  • beforeWebStart(options): вызывается перед началом Blazor Web App. Например, beforeWebStart используется для настройки процесса загрузки, уровня ведения журнала и других параметров. Blazor Получает веб-параметры (options).
  • afterWebStarted(blazor): Вызывается после разрешения всех beforeWebStart обещаний. Например, afterWebStarted можно использовать для регистрации прослушивателей событий Blazor и настраиваемых типов событий. Экземпляр Blazor передается в качестве аргумента afterWebStarted (blazor).
  • beforeServerStart(options, extensions): вызывается до запуска первой среды выполнения сервера. SignalR Получает параметры запуска канала () и любые расширения (optionsextensions), добавленные во время публикации.
  • afterServerStarted(blazor): вызывается после запуска первой интерактивной среды выполнения сервера.
  • beforeWebAssemblyStart(options, extensions): Вызывается до запуска среды выполнения WebAssembly в интерактивном режиме. Получает Blazor параметры (options) и любые расширения (extensions), добавленные во время публикации. Например, параметры могут определять использование настраиваемого загрузчика ресурсов.
  • afterWebAssemblyStarted(blazor): вызывается после запуска интерактивной среды выполнения WebAssembly.

Примечание.

Устаревшие инициализаторы JS (beforeStart, afterStarted) не вызываются по умолчанию в Blazor Web App. Вы можете включить устаревшие инициализаторы с помощью параметра enableClassicInitializers, чтобы они работали. Однако выполнение инициализатора прежних версий непредсказуемо.

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

Из-за ошибки платформы в .NET 8 и 9 (dotnet/aspnetcore #54049)Blazor скрипт должен быть запущен вручную при beforeWebAssemblyStart(options, extensions) вызове или afterWebAssemblyStarted(blazor) вызове. Если серверное приложение еще не запускается вручную Blazor с конфигурацией WebAssembly (webAssembly: {...}), обновите компонент App в серверном проекте следующим образом.

В Components/App.razorудалите существующий Blazor<script> тег:

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

Замените <script> тег следующей разметкой, которая начинается Blazor вручную, используя конфигурацию WebAssembly (webAssembly: {...}).

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

Для Blazor Server, Blazor WebAssemblyи Blazor Hybrid приложений:

  • beforeStart(options, extensions): вызывается до запуска Blazor. Например, beforeStart используется для настройки процесса загрузки, уровня ведения журнала и других параметров, относящихся к модели размещения.
    • На стороне клиента, beforeStart получает параметры Blazor (options) и любые расширения (extensions), добавленные во время публикации. Например, параметры могут определять использование настраиваемого загрузчика ресурсов.
    • Сервер beforeStart получает SignalR параметры запуска цепи (options).
    • В BlazorWebView параметры не передаются.
  • afterStarted(blazor): вызывается после того, как Blazor будет готов к получению вызовов из JS. Например, afterStarted используется для инициализации библиотек с помощью выполнения межъязыковых вызовов JS и регистрации пользовательских элементов. Экземпляр Blazor передается в afterStarted в качестве аргумента (blazor).

Дополнительные обратные вызовы среды выполнения .NET WebAssembly:

  • onRuntimeConfigLoaded(config): вызывается при получении конфигурации загрузки. Позволяет приложению изменять параметры (конфигурацию) перед запуском среды выполнения (параметр из MonoConfigdotnet.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 }): вызывается после запуска среды выполнения .NET WebAssembly (параметр RuntimeAPI из 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();
    }
    

Оба обратных вызова могут возвращать Promise, и обещание ожидается до продолжения запуска.

Имя файла:

  • JS Если инициализаторы используются в качестве статического ресурса в проекте, используйте формат{ASSEMBLY NAME}.lib.module.js, в котором {ASSEMBLY NAME} заполнитель — имя сборки приложения. Например, назовите файл BlazorSample.lib.module.js для проекта с именем сборки BlazorSample. Поместите файл в папку wwwroot приложения.
  • Если инициализаторы используются из RCL, используйте формат {LIBRARY NAME/PACKAGE ID}.lib.module.js, в котором {LIBRARY NAME/PACKAGE ID} плейсхолдер является именем библиотеки проекта или идентификатором пакета. Например, присвойте файлу имя RazorClassLibrary1.lib.module.js для RCL с идентификатором пакета RazorClassLibrary1. Поместите файл в папку wwwroot библиотеки.

Для Blazor Web Apps:

В следующем примере показаны JS инициализаторы, загружающие пользовательские скрипты до и после Blazor Web App запуска, добавляя их в <head>beforeWebStart и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);
}

В примере выше beforeWebStart гарантируется, что пользовательский скрипт загружается до начала Blazor. Это не гарантирует, что ожидаемые обещания в скрипте завершают выполнение перед Blazor началом работы.

Для Blazor Server, Blazor WebAssemblyи Blazor Hybrid приложений:

В следующем примере показаны JS инициализаторы, которые загружают пользовательские скрипты до и после старта Blazor, добавляя их в <head>, в beforeStart и 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);
}

В предыдущем beforeStart примере гарантируется, что пользовательский скрипт загружается до Blazor запуска. Это не гарантирует, что ожидаемые обещания в скрипте успешно завершены до начала выполнения Blazor.

Примечание.

Приложения MVC и Razor Pages не загружают инициализаторы JS автоматически. Однако код разработчика может включать сценарий для выборки манифеста приложения и запуска загрузки инициализаторов JS.

Примеры инициализаторов JS см. в следующих ресурсах:

Примечание.

По ссылкам в документации на справочные материалы по .NET обычно загружается ветвь репозитория по умолчанию, которая представляет текущую разработку для следующего выпуска .NET. Чтобы выбрать тег для определенного выпуска, используйте раскрывающийся список Switch branches or tags (Переключение ветвей или тегов). Дополнительные сведения см. в статье Выбор тега версии исходного кода ASP.NET Core (dotnet/AspNetCore.Docs #26205).

Убедитесь, что библиотеки загружаются в определенном порядке

Добавьте пользовательские скрипты в <head>, beforeStart и afterStarted в том порядке, в каком они должны загружаться.

Пример ниже загружает script1.js перед script2.js и script3.js перед 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);
}

Импорт дополнительных модулей

Используйте инструкции верхнего уровня import в JS файле инициализаторов для импорта дополнительных модулей.

additionalModule.js:

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

JS В файле инициализаторов (.lib.module.js):

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

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

  logMessage();
}

Карта импорта

Карты импорта поддерживаются ASP.NET Core и Blazor.

Инициализация Blazor при готовности документа

Следующий пример запускает Blazor, когда документ готов к работе.

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

В предыдущем примере {BLAZOR SCRIPT} заполнитель обозначает путь к скрипту и имя файла Blazor. Сведения о расположении скрипта см. в разделе структура проекта ASP.NET Core.

Цепочка к Promise, образованная в результате инициированного вручную запуска

Для выполнения дополнительных задач, таких как инициализация взаимодействия JS, используйте then для привязки к объекту Promise, полученному в результате запуска приложения Blazor вручную.

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

В предыдущем примере {BLAZOR SCRIPT} заполнитель представляет собой путь к скрипту и имя файла Blazor. Для информации о расположении скрипта см. структуру проекта ASP.NET Core.

Примечание.

Чтобы библиотека автоматически выполняла дополнительные задачи после Blazor запуска, используйте инициализатор JavaScript. Использование JS инициализатора не требует от потребителя библиотеки цепочки вызовов JS для ручного запуска Blazor.

Загрузка ресурсов загрузки на стороне клиента

Когда приложение загружается в браузере, приложение загружает ресурсы загрузки с сервера:

  • Код JavaScript для начальной загрузки приложения
  • Среда выполнения и сборки .NET
  • Данные конкретного регионального стандарта

Настройте способ загрузки этих загрузочных ресурсов с помощью API loadBootResource. Функция loadBootResource переопределяет встроенный механизм загрузки загрузочных ресурсов. Используйте loadBootResource в следующих сценариях.

  • Загружайте статические ресурсы, такие как данные о часовом поясе или dotnet.wasm, с CDN.
  • Загрузить сжатые сборки с помощью HTTP-запроса и распаковать их на клиенте для узлов, которые не поддерживают получение сжатого содержимого с сервера.
  • Создать псевдоним для ресурсов, перенаправляя каждый запрос fetch на другое имя.

Примечание.

Внешние источники должны возвращать необходимые заголовки совместного использования ресурсов между источниками (CORS), чтобы браузеры могли разрешить загрузку ресурсов между источниками. CDN обычно предоставляют необходимые заголовки.

Параметры loadBootResource приведены в следующей таблице.

Параметр Описание
type Тип ресурса. Допустимые типы: assembly, pdb, dotnetjs, dotnetwasmи timezonedata. Необходимо указать только типы для пользовательских поведений. Типы, не указанные в loadBootResource, загружаются платформой в соответствии с поведением при загрузке по умолчанию. dotnetjs ресурс загрузки (dotnet.*.js) должен либо возвращать null для поведения загрузки по умолчанию, либо URI источника ресурса dotnetjs загрузки.
name Имя ресурса.
defaultUri Относительный или абсолютный URI ресурса.
integrity Строка целостности, представляющая ожидаемое содержимое в ответе.

Функция loadBootResource может вернуть строку URI для переопределения процесса загрузки. В следующем примере файлы из bin/Release/{TARGET FRAMEWORK}/wwwroot/_framework обслуживаются из сети CDN в https://cdn.example.com/blazorwebassembly/{VERSION}/:

  • dotnet.*.js
  • dotnet.wasm
  • Данные часового пояса

Заполнитель {TARGET FRAMEWORK} — это моникер целевой платформы (например, net7.0). Заполнитель {VERSION} — это общая версия платформы (например, 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:

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

В предыдущем примере заполнитель {BLAZOR SCRIPT} — это путь к скрипту и имя файла Blazor. Сведения о расположении скрипта см. в разделе Структура проекта ASP.NET CoreBlazor.

Чтобы настроить не только URL-адреса для загрузочных ресурсов, но и другие объекты, функция loadBootResource может вызвать fetch напрямую и вернуть результат. В следующем примере в исходящие запросы добавляется пользовательский заголовок HTTP. Передайте параметр integrity, чтобы сохранить поведение проверки целостности по умолчанию.

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:

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

В предыдущем примере заполнитель {BLAZOR SCRIPT} обозначает путь и имя файла скрипта Blazor. Сведения о расположении скрипта см. в разделе Blazor проекта Core.

Когда функция loadBootResource возвращает null, Blazor использует поведение загрузки по умолчанию для ресурса. Например, предыдущий код возвращает null для загрузочного ресурса (dotnetjs), так как загрузочный ресурс dotnet.*.js должен возвращать dotnetjs для поведения загрузки по умолчанию или URI для источника загрузочного ресурса dotnetjs.

Функция loadBootResource также может возвращать Response обещание. Пример см. в статье Размещение и развертывание ASP.NET Core Blazor WebAssembly.

Дополнительные сведения см. в разделе ASP.NET Кэширование пакетов .NET Core Blazor WebAssembly и сбои проверки целостности.

Управление заголовками в коде C#

Управлять заголовками при запуске в коде C# можно с помощью следующих подходов.

В следующих примерах Политика безопасности содержимого (CSP) применяется к приложению через заголовок CSP. Заполнитель {POLICY STRING} является строкой политики CSP. Дополнительные сведения о CSP см. в статье Применение политики безопасности содержимого для ASP.NET Core Blazor.

Сценарии на стороне сервера и предопределенные клиентские сценарии

Используйте по промежуточному поверх ASP.NET Core для управления коллекцией заголовков.

В файле Program:

В методе Startup.Configure в файле Startup.cs:

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

В предыдущем примере используется встроенное ПО промежуточного слоя, но вы также можете создать пользовательский класс ПО промежуточного слоя и вызвать ПО промежуточного слоя с помощью метода расширения в Program файле. Дополнительные сведения см. в разделе Создание пользовательского ПО промежуточного слоя ASP.NET Core.

Разработка на стороне клиента без предварительной подготовки

Передайте StaticFileOptions в MapFallbackToFile, который задает заголовки ответа на этапе OnPrepareResponse.

В серверном Program файле:

В Startup.Configure из Startup.cs:

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

...

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

Индикаторы загрузки на стороне клиента

Индикатор загрузки показывает, что приложение загружается обычно и что пользователь должен ждать завершения загрузки.

Blazor Web App Индикатор загрузки

Индикатор загрузки, используемый в Blazor WebAssembly приложениях, отсутствует в приложении, созданном на основе шаблона проекта Blazor Web App. Обычно, индикатор загрузки не желателен для интерактивных компонентов WebAssembly, так как Blazor Web Appклиентские компоненты предварительно отрисовываются на сервере для быстрой первоначальной загрузки. Для ситуаций в смешанном режиме отрисовки код платформы или разработчика также должен быть осторожным, чтобы избежать следующих проблем:

  • Отображение нескольких индикаторов загрузки на одной отрисованной странице.
  • Непреднамеренно отменяя предварительно созданное содержимое во время загрузки среды выполнения .NET WebAssembly.

Будущий выпуск .NET может предоставить индикатор загрузки в рамках платформы. В то же время можно добавить настраиваемый индикатор загрузки в Blazor Web App.

Интерактивная отрисовка WebAssembly для каждого компонента с предварительной отрисовкой

Этот сценарий применяется к интерактивной отрисовке WebAssembly для каждого компонента (@rendermode InteractiveWebAssembly применяется к отдельным компонентам).

Создайте компонент ContentLoading в папке Layout приложения .Client, который вызывает OperatingSystem.IsBrowser:

  • Когда false, отображайте индикатор загрузки.
  • Когда true, отрисуйте содержимое запрошенного компонента.

Чтобы загрузить стили CSS для индикатора, добавьте стили внутрь содержимого <head>, используя компонент HeadContent. Дополнительные сведения см. в статье Управление содержимым head в приложениях ASP.NET Core Blazor.

Layout/ContentLoading.razor:

@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; }
}

В компоненте, который использует интерактивную отрисовку WebAssembly, оберните разметку компонента Razor с помощью компонента ContentLoading. В следующем примере демонстрируется подход с компонентом Counter приложения, созданного на основе шаблона проекта Blazor Web App.

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++;
    }
}

Глобальная интерактивная визуализация WebAssembly с предварительным рендерингом

Этот сценарий применяется к глобальной интерактивной отрисовке WebAssembly без предварительной отрисовки (@rendermode="InteractiveWebAssembly" на компонентах HeadOutlet и Routes в компоненте App).

Создайте компонент ContentLoading в папке Layout приложения .Client, который вызывает RendererInfo.IsInteractive.

  • Когда false, отобразите индикатор загрузки.
  • Если true, отрисовывайте содержимое запрошенного компонента.

Чтобы загрузить стили CSS для индикатора, добавьте стили в содержимое <head> с использованием компонента HeadContent. Дополнительные сведения см. в статье Управление содержимым head в приложениях ASP.NET Core Blazor.

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

В компоненте MainLayout (Layout/MainLayout.razor) проекта .Client оберните свойство Body (@Body) компонентом ContentLoading.

В Layout/MainLayout.razor:

+ <ContentLoading>
    @Body
+ </ContentLoading>

Глобальная интерактивная отрисовка WebAssembly без предварительной отрисовки

Этот сценарий применяется к глобальной интерактивной отрисовке WebAssembly без предварительной отрисовки (@rendermode="new InteractiveWebAssemblyRenderMode(prerender: false)" на компонентах HeadOutlet и Routes, расположенных в компоненте App).

Добавьте инициализатор JavaScript в приложение. В следующем примере имени файла модуля JavaScript, заполнитель {ASSEMBLY NAME} представляет собой имя сборки проекта сервера (например, BlazorSample). Папка wwwroot, в которой размещается модуль, является wwwroot папкой в серверном проекте, а не .Client папкой в проекте.

В следующем примере используется progress индикатор, который не указывает фактический ход доставки клиентских ресурсов загрузки клиенту, но он служит общим подходом для дальнейшей разработки, если вы хотите, чтобы индикатор хода выполнения отображал фактический ход загрузки ресурсов загрузки приложения.

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();
}

Из-за ошибки платформы в .NET 8 и 9 (dotnet/aspnetcore#54049)Blazorскрипт должен быть запущен вручную. Если серверное приложение еще не запускается Blazor вручную с конфигурацией WebAssembly (webAssembly: {...}), обновите компонент App в серверном проекте следующим образом.

В Components/App.razorудалите существующий Blazor<script> тег:

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

Замените <script> тег следующей разметкой, которая начинается Blazor вручную с конфигурацией WebAssembly (webAssembly: {...}):

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

Если вы заметили небольшую задержку между удалением индикатора загрузки и первой отрисовкой страницы, вы можете гарантировать удаление индикатора после отрисовки, вызвав его удаление в OnAfterRenderAsync методе жизненного цикла компонентов MainLayout или Routes. Дополнительные сведения и пример кода см. в разделе «Документирование подхода для индикатора загрузки, который работает с глобальным интерактивным WebAssembly без предварительной отрисовки (dotnet/AspNetCore.Docs #35111)».

Blazor WebAssembly Ход загрузки приложения

Шаблон проекта содержит индикаторы масштабируемой векторной графики (SVG) и текстовые индикаторы, показывающие ход загрузки приложения.

Индикаторы хода выполнения реализуются с помощью HTML и каскадных таблиц стилей (CSS) с использованием двух настраиваемых свойств CSS (переменных), которые предоставляются с помощью Blazor:

  • --blazor-load-percentage — процент загруженных файлов приложения.
  • --blazor-load-percentage-text — процент загруженных файлов приложения, округленный до ближайшего целого числа.

Используя вышеупомянутые переменные CSS, вы можете создать пользовательские индикаторы прогресса, соответствующие стилю вашего приложения.

В следующем примере :

  • resourcesLoaded — это текущее число ресурсов, загруженных во время запуска приложения.
  • totalResources — общее количество ресурсов для загрузки.
const percentage = resourcesLoaded / totalResources * 100;
document.documentElement.style.setProperty(
  '--blazor-load-percentage', `${percentage}%`);
document.documentElement.style.setProperty(
  '--blazor-load-percentage-text', `"${Math.floor(percentage)}%"`);

Индикатор хода выполнения по умолчанию реализуется в HTML-файле wwwroot/index.html :

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

Разметку шаблона проекта и стили для индикаторов прогресса по умолчанию можно найти в справочном источнике ASP.NET Core.

Примечание.

По ссылкам в документации на справочные материалы по .NET обычно загружается ветвь репозитория по умолчанию, которая представляет текущую разработку для следующего выпуска .NET. Чтобы выбрать тег для конкретного выпуска, используйте раскрывающийся список в меню Switch branches or tags (Переключение ветвей или тегов). Дополнительные сведения см. в статье Выбор тега версии исходного кода ASP.NET Core (dotnet/AspNetCore.Docs #26205).

Вместо использования индикатора хода выполнения по умолчанию в следующем примере показано, как реализовать линейный индикатор хода выполнения.

Добавьте следующие стили к 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;
}

Переменная CSS (var(...)) используется для передачи значения --blazor-load-percentagescale свойству синего псевдо-элемента, указывающего ход загрузки файлов приложения. В процессе загрузки приложения --blazor-load-percentage обновляется автоматически, что динамически изменяет визуальное представление индикатора хода выполнения.

В wwwroot/index.html удалите SVG индикатор раунда по умолчанию и замените его следующей разметкой:

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

Настройка среды выполнения .NET WebAssembly

В расширенных сценариях configureRuntime программирования функция с dotnet построителем узлов среды выполнения используется для настройки среды выполнения .NET WebAssembly. Например, задает переменную среды, dotnet.withEnvironmentVariable которая:

  • Настраивает среду выполнения .NET WebAssembly.
  • Изменяет поведение библиотеки C.

Примечание.

Запрос документации ожидается в dotnet/runtime репозитории GitHub для получения дополнительных сведений о переменных среды, которые настраивают среду выполнения .NET WebAssembly или влияют на поведение библиотек C. Хотя запрос на документацию находится в ожидании, дополнительные сведения и перекрестные ссылки на дополнительные ресурсы доступны в запросе, вопрос/запрос документации о переменных среды времени выполнения .NET WASM (dotnet/runtime #98225).

Функцию configureRuntime также можно использовать для включения интеграции с профилировщиком браузера.

Для замещающих элементов в следующих примерах, которые устанавливают переменную среды:

  • Заполнитель {BLAZOR SCRIPT} — это путь к скрипту Blazor и имя файла. Сведения о расположении скрипта см. в разделе Blazor проекта Core.
  • Заполнитель {NAME} — это имя переменной среды.
  • Заполнитель {VALUE} — это значение переменной среды.

Blazor Web App:

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

Автономное устройство Blazor WebAssembly:

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

Примечание.

Доступ к экземпляру среды выполнения .NET можно получить с помощью API среды выполнения .NET WebAssembly (Blazor.runtime). Например, конфигурацию сборки приложения можно получить с помощью Blazor.runtime.runtimeBuildInfo.buildConfiguration.

Для получения дополнительной информации о конфигурации среды выполнения .NET WebAssembly см. TypeScript-файл определения среды выполнения (dotnet.d.ts) в репозитории GitHub dotnet/runtime.

Примечание.

Ссылки в документации на справочные материалы по .NET обычно открывают ветвь по умолчанию репозитория, представляющую текущую разработку для следующего выпуска .NET. Чтобы выбрать тег для определенного выпуска, используйте раскрывающийся список Switch branches or tags (Переключение ветвей или тегов). Дополнительные сведения см. в статье Выбор тега версии исходного кода ASP.NET Core (dotnet/AspNetCore.Docs #26205).

Отключение расширенной навигации и обработки форм

Этот раздел относится к Blazor Web Apps.

Чтобы отключить расширенную навигацию и обработку форм, установите disableDomPreservation на true для Blazor.start:

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

В предыдущем примере заполнитель {BLAZOR SCRIPT} представляет собой путь к скрипту и имя файла Blazor. Сведения о расположении скрипта см. в разделе Blazor проекта Core.

Дополнительные ресурсы