A Blazor page can become slow even when the page itself is not doing anything complicated.
Sometimes the problem is just one component.
For example, an application may have a dashboard containing a sales chart, a product summary, a list of popular products, and a small statistics panel. Most of the page may be cheap to render, while one component performs an expensive database query or generates a large amount of markup.
Caching the complete page may solve the performance problem, but it can also create another one: parts of the page that should remain fresh may become cached as well.
This is where CacheView can be useful.
CacheView allows a portion of a Blazor application's rendered output to be cached instead of caching the entire page. In .NET 11, Blazor includes the CacheView component for caching rendered component content and supports configuration such as expiration and cache keys.
The idea is simple:
Page
|
+-- Header -> Always render
|
+-- User information -> Always render
|
+-- Expensive summary -> Cache
|
+-- Live notifications -> Always render
|
+-- Footer -> Always render
Instead of caching everything, we cache only the expensive part.
This article explains how CacheView works, where it fits, how to configure it, and what to consider before using it in a production application.
What Is CacheView?
CacheView is a Blazor component designed to cache the rendered output of its child content.
A simplified example looks like this:
<CacheView>
<ExpensiveReport />
</CacheView>
The first time the component needs to render, the content is generated normally.
The cached result can then be reused for subsequent renders while it remains valid.
Conceptually:
First request
|
v
Render component
|
v
Store rendered result
|
v
Return result
Later request
|
v
Cache exists?
/ \
Yes No
| |
v v
Return Render
cache again
The important distinction is that CacheView operates at the component content level rather than requiring the entire page to be cached.
That gives developers more control over what should be reused.
Why Not Cache the Entire Page?
Imagine a dashboard like this:
<DashboardHeader />
<UserProfile />
<DailySales />
<RecentNotifications />
<CacheView>
<PopularProducts />
</CacheView>
Suppose PopularProducts requires an expensive query.
You might be tempted to cache the entire dashboard.
But that could cause problems.
The user profile may need to be current.
Notifications may need to update quickly.
Some parts may depend on the current user.
Only the popular-products component may actually need caching.
Component-level caching lets you isolate the expensive part.
A Simple CacheView Example
Suppose we have a component that displays popular products.
<CacheView>
<PopularProducts />
</CacheView>
The rest of the page remains outside the cache.
For example:
<h2>Sales Dashboard</h2>
<UserSummary />
<CacheView>
<PopularProducts />
</CacheView>
<RecentOrders />
<Notifications />
Here, PopularProducts can reuse cached output while UserSummary, RecentOrders, and Notifications continue to render normally.
This is particularly useful when the expensive component does not need to change on every request.
Caching Has to Match the Data
Caching is not simply a performance switch.
Before caching a component, ask:
How often can this data safely become stale?
Suppose a product recommendation component changes every hour.
Caching it for five minutes may be reasonable.
But a payment status component should not normally use the same strategy.
For example:
Product statistics
-> Can tolerate some staleness
Marketing content
-> Can tolerate some staleness
Current account balance
-> Usually needs fresh data
Payment status
-> Usually needs fresh data
The correct cache duration depends on the application's requirements.
Cache Duration
Cache expiration is one of the important controls when using CacheView.
A simplified configuration can specify how long the content should remain cached.
For example:
<CacheView Duration="TimeSpan.FromMinutes(5)">
<PopularProducts />
</CacheView>
The exact available parameters and behavior should be checked against the version of the Blazor APIs used by your application.
The important design idea is to choose an expiration period based on how frequently the underlying information changes.
A five-minute cache is not automatically better than a one-hour cache.
Cache Keys
A cache becomes more complicated when the rendered content depends on different inputs.
Consider:
/dashboard?region=india
and:
/dashboard?region=europe
If both requests use exactly the same cache entry, users could receive the wrong content.
The cache needs a key that represents the data that makes the output different.
Conceptually:
Cache Key
|
+-- Component
+-- Region
+-- User-specific context
+-- Other relevant parameters
For example:
<CacheView Key="@($"popular-products-{Region}")">
<PopularProducts Region="Region" />
</CacheView>
Now the application can maintain separate cached content for different regions.
The exact keying API should follow the CacheView API available in the target .NET version.
User-Specific Content Needs Extra Care
This is one of the most important production considerations.
Suppose a component renders:
Welcome, Baibhav
and the same cache entry is accidentally reused for another user.
That creates a serious data-isolation problem.
Before caching a component, determine whether its output depends on:
Current user
User roles
Permissions
Tenant
Region
Account
Language
Feature flags
If the answer is yes, those differences must be reflected in the caching strategy.
For highly sensitive or user-specific information, caching should be designed very carefully or avoided entirely.
Example With a Tenant
Consider a multi-tenant application.
A dashboard component displays statistics for the current tenant.
<CacheView Key="@($"dashboard-stats-{TenantId}")">
<TenantStatistics TenantId="TenantId" />
</CacheView>
The tenant identifier is part of the cache key.
Without tenant-specific separation, the cache could return data belonging to another tenant.
The general rule is:
Different data
=
Different cache identity
CacheView vs Application Data Caching
It is important to understand that rendered-output caching and data caching are not the same thing.
Consider a component:
Database
|
v
Service
|
v
Component
|
v
Rendered HTML
A data cache stores something closer to:
Product statistics
A rendered-output cache stores the result of rendering the component.
These approaches solve different problems.
Approach | What Is Cached? | Useful When |
|---|---|---|
Data caching | Data or service result | Multiple consumers need the same data |
Rendered-content caching | Component output | Rendering itself is expensive |
Full-page caching | Complete response/page | Most of the page can tolerate caching |
No caching | Nothing | Data must remain fresh |
Sometimes the best solution is to cache the data rather than the rendered component.
When CacheView Makes Sense
CacheView is a good candidate when:
A component is expensive to render.
Its output does not need to change on every request.
The same output can be reused safely.
The component is only one expensive part of a larger page.
Full-page caching would make other parts of the page too stale.
For example:
Dashboard
|
+-- Current user information
|
+-- Real-time alerts
|
+-- Expensive analytics
|
+-- Recent activity
If only analytics are expensive and can tolerate a small amount of staleness, caching that component makes sense.
When CacheView Is Not a Good Fit
Avoid caching a component simply because it performs a database query.
Not every database query needs caching.
Caching may be a poor choice when:
Data changes constantly.
Users must always see the latest value.
Content is highly personalized.
The component depends on rapidly changing authorization.
The rendering cost is already negligible.
Cache invalidation is more complicated than the original problem.
A cache that creates incorrect behavior is worse than a slightly slower component.
Measuring Before Adding CacheView
Before adding caching, measure the actual problem.
For example, suppose a component takes 300 ms to generate.
Ask:
How often is it rendered?
How expensive is the underlying query?
How many users request it?
How frequently does the data change?
If the component is rendered once and the data is rarely requested, caching may not provide much value.
If thousands of requests repeatedly generate the same expensive result, caching can be much more useful.
A Practical Example
Suppose an analytics component calculates sales statistics.
Without caching:
<SalesStatistics />
The component might execute:
var sales = await _dbContext.Orders
.Where(x => x.CreatedAt >= startDate)
.GroupBy(x => x.Category)
.Select(group => new SalesSummary
{
Category = group.Key,
Total = group.Sum(x => x.Amount)
})
.ToListAsync();
If the calculation is expensive and the values can remain unchanged for a short period, you could cache the rendered component:
<CacheView Duration="TimeSpan.FromMinutes(5)">
<SalesStatistics />
</CacheView>
Now the application does not need to regenerate the same rendered output every time while the cached result remains valid.
However, if the underlying data must be current to the second, this strategy would be inappropriate.
CacheView and Database Caching Are Different
A common mistake is thinking:
CacheView
=
Database query caching
It does not.
CacheView concerns the rendered component content.
If the same database data is needed by five different components, caching the data at the service layer may be a better approach.
For example:
public async Task<SalesSummary> GetSalesSummaryAsync()
{
// Data caching can be implemented here
// when multiple parts of the application need the same result.
return await _repository.GetSalesSummaryAsync();
}
Then different components can reuse the same cached data.
Use rendered-content caching when the rendered output itself is what you want to reuse.
Choosing Between CacheView and Data Caching
Question | CacheView | Data Cache |
|---|---|---|
Need to cache rendered markup? | Yes | No |
Multiple components use same data? | Less suitable | Better |
Rendering is expensive? | Good candidate | May help indirectly |
Database query is expensive? | May help | Often better |
Personalized output | Requires careful keying | Requires careful keying |
Data reused by APIs/services | No | Yes |
Simple component output reuse | Good | Not always necessary |
The two strategies can also be used together, but only when there is a clear reason to do so.
Common Mistakes
Caching Everything
Adding CacheView around every expensive-looking component can make application behavior harder to understand.
Cache only where measurement shows a meaningful benefit.
Ignoring Cache Invalidation
If data changes, cached content can become outdated.
Always decide what should happen when the underlying data changes.
Using the Same Key for Different Data
Different tenants, users, regions, or parameters may require different cache identities.
Caching Sensitive Information
Do not casually cache content containing private or security-sensitive data.
Choosing an Arbitrary Expiration
A one-hour cache is not automatically appropriate.
The expiration should match the business requirement.
Assuming Caching Always Improves Performance
Caching itself has overhead.
There can be memory usage, cache lookups, serialization or storage costs, and invalidation complexity.
Measure the result.
Troubleshooting CacheView
Changes Are Not Appearing Immediately
The component may still be serving cached content.
Check the configured expiration and cache key.
If the application requires immediate updates, consider whether this component should be cached at all.
One User Sees Another User's Content
Treat this as a serious cache-key or isolation problem.
Check whether user, tenant, role, or other identity-dependent values are included in the cache identity where required.
Cache Is Not Reducing Database Load
Remember that rendered-content caching and data caching solve different problems.
If the expensive operation occurs before the content is cached or is performed by another component, CacheView may not address the actual bottleneck.
Profile the complete request path.
Memory Usage Increases
Caching more content means retaining more cached data.
Review:
Cache duration
Number of unique cache keys
Component size
Number of tenants or users
Overall cache configuration
Avoid generating unlimited unique cache entries.
Advantages
CacheView provides several useful benefits:
Allows caching at the component level.
Avoids caching an entire page unnecessarily.
Can reduce repeated rendering work.
Works well for components whose output changes less frequently.
Allows other parts of the page to remain dynamic.
Can make expensive dashboard components more efficient.
Provides a focused caching boundary.
Disadvantages
There are also trade-offs:
Cached content can become stale.
Cache invalidation needs careful design.
User-specific content requires careful isolation.
Too many cache keys can increase cache usage.
Caching does not automatically solve expensive database operations elsewhere.
Debugging cached output can be confusing during development.
Incorrect caching can cause functional or security problems.
Best Practices
Measure the component before adding caching.
Cache only content that can safely become stale.
Keep cache duration aligned with business requirements.
Use distinct cache identities when output depends on different inputs.
Be especially careful with user and tenant-specific content.
Avoid caching sensitive information without a clear isolation strategy.
Use data caching when the underlying data needs to be reused by multiple components.
Keep cache keys predictable and controlled.
Monitor cache size and hit behavior in production.
Test expiration and invalidation behavior.
Do not use caching as a substitute for fixing an inefficient database query.
Remove caching if it adds more complexity than performance benefit.
When Full-Page Caching Is Better
CacheView is not intended to replace every other caching strategy.
Full-page caching may be more appropriate when:
The complete page
|
v
Can safely be reused
|
v
For most users
|
v
Without becoming unacceptable stale
For example, a mostly static documentation page may not need component-level caching at all.
The correct choice depends on the page.
A Simple Decision Process
Use this approach before adding CacheView:
Is the component expensive?
|
No
|
v
Don't cache
Yes
|
v
Can the output safely become stale?
|
No
|
v
Consider another optimization
Yes
|
v
Does the output depend on user/tenant context?
|
Yes
|
v
Design cache identity carefully
No
|
v
CacheView may be a good fit
This keeps caching focused on an actual performance problem.
Production Checklist
Before deploying a cached component, verify:
[ ] The component is actually expensive
[ ] Cache duration is intentional
[ ] Stale data is acceptable
[ ] Cache identity is correct
[ ] Tenant isolation is preserved
[ ] User-specific content is handled safely
[ ] Cache growth is controlled
[ ] Expiration behavior has been tested
[ ] Database performance has also been reviewed
[ ] Monitoring is available where appropriate
This checklist helps prevent a common mistake: solving a performance problem while accidentally introducing a correctness problem.
Summary
CacheView is useful when only one part of a Blazor page is expensive and that part does not need to be regenerated every time.
Instead of caching the entire page, you can place the expensive component inside a CacheView and allow the rest of the page to continue rendering normally.
For example:
<UserSummary />
<CacheView Duration="TimeSpan.FromMinutes(5)">
<SalesStatistics />
</CacheView>
<RecentNotifications />
The main thing to remember is that caching is a trade-off. You are exchanging some freshness and memory for less repeated work.
Before using CacheView, check whether the component is actually a performance bottleneck, decide how much stale data is acceptable, and make sure the cache identity keeps different users, tenants, and other contexts separated.
For database-heavy applications, also consider whether data caching is a better solution than caching rendered output. CacheView is most useful when the component's rendered result itself is worth reusing.
Used carefully, component-level caching gives Blazor developers a way to improve expensive parts of a page without making the entire page stale.

Join the conversation! Your thoughts help the community grow.