-
Notifications
You must be signed in to change notification settings - Fork 10.3k
[ResponseCache] for Blazor static server rendering #49130
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Comments
We've moved this issue to the Backlog milestone. This means that it is not going to be worked on for the coming release. We will reassess the backlog following the current release and consider this item at that time. To learn more about our issue management process and to have better expectation regarding different types of issues you can read our Triage Process. |
This useful especially in the context of using server-side rendering (SSR) to gain performance. Adding support for caching components would server those who are building apps relying on parts if a web page being cached due to high-load. E-commerce sites and sites selling tickets to concerts etc. Also worth mentioning: In MVC Razor and Razor Pages, you can cache certain portions of a view using a tag helper. So apart from attributes you can have a special <Cache ExpiresAfter="@TimeSpan.FromSeconds(120)">
@DateTime.Now
</Cache> Modeled after: https://learn.microsoft.com/en-us/aspnet/core/mvc/views/tag-helpers/built-in/cache-tag-helper?view=aspnetcore-7.0 |
We've moved this issue to the Backlog milestone. This means that it is not going to be worked on for the coming release. We will reassess the backlog following the current release and consider this item at that time. To learn more about our issue management process and to have better expectation regarding different types of issues you can read our Triage Process. |
I think this already works, we use the |
@DamianEdwards Do you maybe have a link? I'm interested to try this! |
@DamianEdwards Thanks, I'm gonna check it out! |
This is a simplified version of CacheTagHelper for Blazor SSR which can be used to cache the content of a given component: CacheComponent.razor @using Microsoft.Extensions.Caching.Memory
@typeparam TComponent where TComponent : IComponent
@if (_cachedContent != null)
{
@((MarkupString)_cachedContent)
}
@code{
private const string CacheKeyPrefix = $"__{nameof(CacheComponent<TComponent>)}__";
private readonly TimeSpan _defaultExpiration = TimeSpan.FromSeconds(30);
private string? _cachedContent;
[Inject] internal HtmlRenderer HtmlRenderer { set; get; } = null!;
[Inject] internal IMemoryCache MemoryCache { get; set; } = null!;
/// <summary>
/// Parameters for the component.
/// </summary>
[Parameter]
public IDictionary<string, object?>? Parameters { set; get; }
/// <summary>
/// Gets or sets the exact <see cref="DateTimeOffset" /> the cache entry should be evicted.
/// </summary>
[Parameter]
public DateTimeOffset? ExpiresOn { get; set; }
/// <summary>
/// Gets or sets the duration, from the time the cache entry was added, when it should be evicted.
/// </summary>
[Parameter]
public TimeSpan? ExpiresAfter { get; set; }
/// <summary>
/// Gets or sets the duration from last access that the cache entry should be evicted.
/// </summary>
[Parameter]
public TimeSpan? ExpiresSliding { get; set; }
/// <summary>
/// Gets or sets the <see cref="CacheItemPriority" /> policy for the cache entry.
/// </summary>
[Parameter]
public CacheItemPriority? Priority { get; set; }
/// <summary>
/// Gets or sets the key of the cache entry.
/// </summary>
[Parameter, EditorRequired]
public required string CacheKey { get; set; }
private string CacheEntryKey => $"{CacheKeyPrefix}{CacheKey}";
protected override Task OnInitializedAsync()
=> ProcessAsync();
public void InvalidateCache()
=> MemoryCache.Remove(CacheEntryKey);
private async Task ProcessAsync()
{
if (!MemoryCache.TryGetValue(CacheEntryKey, out _cachedContent))
{
_cachedContent = await HtmlRenderer.Dispatcher.InvokeAsync(async () =>
{
var output = await HtmlRenderer.RenderComponentAsync<TComponent>(Parameters is null ? ParameterView.Empty : ParameterView.FromDictionary(Parameters));
return output.ToHtmlString();
});
_ = MemoryCache.Set(CacheEntryKey, _cachedContent, GetMemoryCacheEntryOptions());
}
}
private MemoryCacheEntryOptions GetMemoryCacheEntryOptions()
{
var hasEvictionCriteria = false;
var options = new MemoryCacheEntryOptions();
options.SetSize(1);
if (ExpiresOn != null)
{
hasEvictionCriteria = true;
options.SetAbsoluteExpiration(ExpiresOn.Value);
}
if (ExpiresAfter != null)
{
hasEvictionCriteria = true;
options.SetAbsoluteExpiration(ExpiresAfter.Value);
}
if (ExpiresSliding != null)
{
hasEvictionCriteria = true;
options.SetSlidingExpiration(ExpiresSliding.Value);
}
if (Priority != null)
{
options.SetPriority(Priority.Value);
}
if (!hasEvictionCriteria)
{
options.SetSlidingExpiration(_defaultExpiration);
}
return options;
}
} Requirements: builder.Services.AddMemoryCache();
builder.Services.AddScoped<HtmlRenderer>(); Usage: <CacheComponent TComponent="MySidebarComponent"
ExpiresAfter="TimeSpan.FromMinutes(1)"
CacheKey="side-bar-menu-1"/> |
Did you manage to cache Blazor SSR page with or without .Net Aspire? Thank you in advance for your response. |
@javiercn , I was wondering if there are any plans to add support for Blazor SSR pages anytime soon. I appreciate your time and efforts. |
@zubairkhakwani Unfortunately, this work isn't planned for Blazor in .NET 9 due to competing priorities. We are open to community contributions for designing and implementing this feature. |
@zubairkhakwani Output caching should already work with Blazor static SSR pages. You can set up that output caching middleware and add |
I've opened #55520 to separately track adding a Blazor Cache component as an analog to the existing cache tag helper used in MVC & Razor Pages apps. |
I have registered the middleware just like I do it in MVC app
and on my SSR component page I used it like to check if cache is working I am using @DateTime.Now.ToString("F") in the same component/Page but on every refresh the time is changed by one second. I really appreciate your comment & please let me know if I am missing something or it is a bug. I am using dotnet 8.0.204 I am adding a GIF below to showcase the issue. |
@zubairkhakwani app.UseStaticFiles();
app.UseSession();
app.UseRouting();
app.UseAntiforgery();
app.UseOutputCache();
app.MapRazorComponents<App>();
app.MapControllers();
app.Run(); |
Thank you @VahidN putting
worked like a charm. I had tried putting it before
Thank you again, and have a good day. |
I renamed this because, as noted in the previous comments, |
In MVC & Razor Pages we have attributes, like
ResponseCacheAttribute
andOutputCacheAttribute
, for configuring response & output caching on a page or action. We should consider having similar support for Blazor server-side rendering.The text was updated successfully, but these errors were encountered: