tgoop.com/csharpproglib/6270
Create:
Last Update:
Last Update:
Включите EventPipe/PerfView/dotnet-trace для старта: какие сборки грузятся, на что тратится время.
Снимите таймлайны: «вход в Main → готовность endpoint'ов / UI».
Измеряйте Release-сборку, без отладчиков и без «горячих» кэшей.
• ReadyToRun (R2R)
Компилирует IL в машинный код при публикации:
<!-- Directory.Build.props или csproj -->
<PropertyGroup>
<PublishReadyToRun>true</PublishReadyToRun>
<PublishTrimmed>true</PublishTrimmed>
<TrimMode>partial</TrimMode> <!-- для библиотек и DI -->
</PropertyGroup>
• PGO (Profile-Guided Optimization) + R2R
Соберите профиль и примените при crossgen2 (даёт лучший порядок/инлайнинг для «горячего» пути старта).
• NativeAOT
Полностью нативный бинарь, почти мгновенный старт. Подходит для CLI/служб с ограниченным набором фич и для «узких» сервисов или edge-эндпоинтов в вебе.
Уберите всё, что не нужно при старте: тяжёлые клиенты (БД, кеши, внешние SDK) создавайте лениво, после поднятия хостинга.
Прогружайте конфигурацию минимально: уберите лишние провайдеры, большие JSON-файлы, многократные AddJsonFile.
Логи на старте — только консоль/минимальный уровень, позже можно расширить.
Уберите неиспользуемые пакеты, объедините внутренние пакеты, избегайте древовидных зависимостей ради одной функции.
Встроенный контейнер быстрый, но следите за графом:
• Регайте Singleton/Scoped только когда нужно.
• Избегайте «сервисов-глобов» с большим конструктором на десятки зависимостей.
• Используйте фабрики/Lazy для тяжёлых зависимостей.
Минимальный хостинг и только нужные middleware:
var builder = WebApplication.CreateBuilder(args);
// Оставьте только то, что нужно для старта
builder.Services.AddRouting();
var app = builder.Build();
// Критичный middleware – ближе к началу конвейера
app.MapGet("/healthz", () => "OK");
app.Run();
Отключите всё, что делает работу на старте: избыточная авто-дискавери Swagger, отражение в валидации, сканирование сборок.
Разнесите готовность принимать трафик и полную готовность всех подсистем:
• Быстрый
/healthz
сразу.• Прогрев кэшей/метаданных — в фоне
IHostedService
с низким приоритетом.• В оркестраторе задайте
readinessProbe
после минимального старта, а «тяжёлый прогрев» делайте уже на фоне.PublishTrimmed=true
+ TrimMode=partial
часто снижает размер и ускоряет загрузку.Обязательно добавляйте
DynamicDependency
/UnconditionalSuppressMessage
/RD.XML
для сохранения типов, которые нужны через рефлексию (DI/JSON/ORM).💬 А у вас сколько секунд уходит на холодный старт .NET сервиса?
#буст