Open Closed

ABP Performance Issue #10106


User avatar
0
FurkanSetur created

Hello ABP Team,

We are using ABP framework in one of our projects. This project was built in 2022.

Technical information: Target Framework is net8.0 ABP Framework libraries are 8.0.0 (Volo.Abp.*) LeptonX version is 3.0.0

We have a major problem about page redirections and page loads which composed with ABP components. Average page load time is between 40 and 100 seconds. There are also some javascript files which are loading around 30-40 seconds. (Redis is installed.)

Our team didn’t build this application from scratch. It has been transferred from another team which is not exists in our company now. So we have a limited information about the ABP Framework and how the FW has been used by the previous team.

We installed a profiler library to see page results based on loading time. Here are some examples:

If you need any further information please do not hesitate to contact us. We need your support in order to fix this performance problem urgently.

Best regards,


1 Answer(s)
  • User Avatar
    0
    AI-Bot created
    Support Team ABP Agent
    1. Solution Below is a focused checklist to diagnose and fix extreme page-load/redirect delays in an ABP MVC app (v8.0, LeptonX 3.0). The highlighted slow endpoints in your screenshot (/Abp/AbpApplicationConfigurationScript/Get, /Abp/AbpApplicationLocalizationScript/Get, AbpServiceProxyScript/GetAll, and your MVC pages) point to server-side latency during application configuration/localization generation, and potentially heavy DB/permission/localization work happening per request. Follow these steps in order and keep each change under version control so you can measure impact.

    A) Verify environment, build, and middleware

    • Run in Release and enable response compression and caching:
    // Program.cs
      var builder = WebApplication.CreateBuilder(args);
    
      builder.Services.AddResponseCompression(options =>
      {
          options.EnableForHttps = true;
          options.Providers.Add<BrotliCompressionProvider>();
      });
      builder.Services.AddResponseCaching();
    
      var app = builder.Build();
    
      if (!app.Environment.IsDevelopment())
      {
          app.UseExceptionHandler("/Error");
          app.UseHsts();
      }
    
      app.UseResponseCompression();
      app.UseResponseCaching();
    
    • Publish with Release and ready-to-run:
      • dotnet publish -c Release
    • Ensure there are no “developer-only” middlewares running in production (e.g., heavy logging, debug exception page).

    B) Optimize ABP’s application configuration and localization endpoints These endpoints generate JSON or JS payloads used by the MVC UI and can be slow if:

    • Hundreds of localization resources/strings are aggregated on each request
    • Permissions/feature/setting providers hit the DB without caching
    • Large dynamic JavaScript proxies are generated per request

    Actions:

    1. Cache ABP application-configuration responses at ASP.NET layer (safe for most apps):
    using Microsoft.AspNetCore.Mvc;
      using Microsoft.AspNetCore.OutputCaching;
    
      // Add once
      builder.Services.AddOutputCache();
    
      // Use
      app.UseOutputCache();
    
      // Then decorate ABP configuration controller via options (global)
      Configure<AbpAspNetCoreMvcOptions>(options =>
      {
          options.ConventionalControllers.Create(typeof(YourApplicationModule).Assembly);
      });
    
      // Add a filter for caching ApplicationConfiguration
      Configure<MvcOptions>(options =>
      {
          options.Filters.Add(new OutputCacheAttribute
          {
              PolicyName = "ConfigPolicy"
          });
      });
    
      builder.Services.AddOutputCache(o =>
      {
          o.AddPolicy("ConfigPolicy", b => b
              .Expire(TimeSpan.FromMinutes(10))
              .SetVaryByHeader("Accept-Language")
              .Tag("abp-appconfig"));
      });
    

    Alternatively, if you prefer ResponseCaching:

    [ResponseCache(Duration = 600, Location = ResponseCacheLocation.Client, NoStore = false)]
      public override Task<ApplicationConfigurationDto> GetAsync(...)
    
    1. Reduce localization payload:

      • Ensure you’re not loading unnecessary resources. Remove unused localization resources from your module dependencies or mark only the modules you actually use.
      • If you have custom code that enumerates all resources via IStringLocalizer.GetAllStrings() for every request, back it with an in-memory/distributed cache and only rebuild on app start or when language files change.
      • Consider serving localization to JS via the JSON endpoint (api/abp/application-localization) and cache it the same way (OutputCache/ResponseCache) with vary-by culture.
    2. Static JavaScript proxies

      • Prefer Static JavaScript Client Proxies instead of dynamic script endpoints (AbpServiceProxyScript/GetAll). Static proxies are generated at build-time and served as static files, eliminating per-request generation cost. In MVC UI:
        • Enable static proxies and include the generated file in your bundles.
      • If you must use dynamic proxies, cache their responses with long durations and vary by version.

    C) Turn off or scope auditing and logging for hot paths

    • Excessive auditing on every read can add a lot of overhead.
    Configure<AbpAuditingOptions>(options =>
      {
          // Disable auditing for MVC views and configuration endpoints if not needed
          options.IsEnabledForAnonymousUsers = false;
          options.IsEnabled = true; // keep overall on, but
          options.Contributors.Add(new MySelectiveAuditingContributor());
      });
    
    • Temporarily disable auditing for the configuration/localization endpoints to compare timings.
    • Reduce log level to Information or Warning in production and exclude heavy categories (EF detailed logs).

    D) Validate distributed cache/Redis configuration

    • Ensure Redis connectivity is low latency and the serializer is efficient (System.Text.Json is default in v8). Misconfigured Redis (DNS, TLS, network path) can add tens of seconds.
    • If you enabled distributed cache for permissions/localization, confirm cache hits occur after first call:
      • Watch logs for “Not found in the cache” only on first request. Repeated misses indicate wrong cache keys or tenant/provider context issues.
    • If Redis is remote/high-latency, try placing it in the same network zone or test in-memory cache to compare. If in-memory is fast and Redis is slow, you likely have network or serialization overhead.

    E) EF Core and permission checks

    • Slow AbpApplicationConfigurationScript/Get often correlates with heavy permission/feature/setting aggregation on each request.
      • Ensure PermissionStore/Feature providers are cached (ABP does this by default when configured; verify you didn’t bypass it).
      • For read operations, use AsNoTracking and read-only repositories where applicable (ABP v8 supports ReadOnly repositories).
      • Profile DB with Application Insights/EF logging for N+1 queries during configuration generation.

    F) Bundling/Minification and static files

    • Use ABP’s bundling/minification to reduce JS/CSS requests and size in MVC. Ensure bundles are pre-built and served as static files.
    • Enable long cache headers for static files and use a versioned query string or file version provider.

    G) Check for blocking calls or thread starvation

    • Avoid sync-over-async in application services and controllers (e.g., .Result/.Wait()) which can cause long request stalls under load.
    • Ensure ThreadPool is not starved (look for many long-running blocking operations).

    H) Quick measurements to isolate the culprit

    • Hit these endpoints directly and measure server time:
      • /api/abp/application-configuration?includeLocalizationResources=false
      • /api/abp/application-localization?cultureName=en&onlyDynamics=false
      • /Abp/AbpApplicationConfigurationScript/Get
      • /Abp/AbpApplicationLocalizationScript/Get
    • Compare cold vs warm requests. If the first is slow and the second is fast, caching isn’t persisting or vary keys differ; if both are slow, generation itself is heavy or DB/cache is slow.

    I) Optional: trim localization at runtime If you have very large localization sets, restrict what goes to the client:

    • Override AbpApplicationLocalizationController to return only required resources (or only dynamic ones), then cache the result per culture.

    J) Production optimizations

    • Host close to DB/Redis.
    • Enable HTTP/2 on reverse proxy.
    • Consider CDNs for static assets.
    1. Sources
    • https://abp.io/docs/latest/framework/architecture/modularity/basics
    • https://abp.io/docs/latest/framework/architecture/multi-tenancy
    • https://abp.io/docs/latest/framework/api-development/standard-apis/localization
    • Community guidance on production/performance practices:
      • https://abp.io/community/articles/pmdwhwxc
      • https://abp.io/community/articles/wa24j28e

    This response was generated by AI. If it didn’t solve your problem, feel free to post a new answer — our support team will jump in to help you soon.

Boost Your Development
ABP Live Training
Packages
See Trainings
Mastering ABP Framework Book
The Official Guide
Mastering
ABP Framework
Learn More
Mastering ABP Framework Book
Made with ❤️ on ABP v10.1.0-preview. Updated on November 11, 2025, 06:29
1
ABP Assistant
🔐 You need to be logged in to use the chatbot. Please log in first.