-
Notifications
You must be signed in to change notification settings - Fork 10
Caching, Cache Dependencies, Async
Caching (both data and rendering) is an important step to optimizing your site's performance. It is also important to be able to clear caches when related data changes.
In order to track all dependencies that impact a given web section, the dependencies need to be stored and retrieved. The ICacheDependenciesScope.Begin()
method starts tracking any dependencies that are added (using the ICacheDependenciesStore
), and then when ICacheDependenciesScope.End()
is called, an array of the dependencies is returned. This allows you to properly pass dependency keys to your <cache-dependency cache-keys=@CacheScope.End()/>
parameter within a <cache></cache>
tag.
Since most data retrieval occurs in the Controller/View Component, while the <cache></cache>
tags are in the view, you often need to split your ICacheDependenciesStore.Begin()
in your class, and call ICacheDependenciesStore.End()
in the View.
YOU SHOULD ADD CACHE DEPENDENCIES ON ALL DATA RETRIEVAL OPERATIONS FROM THE API
The Baseline uses a custom class CacheDependencyKeysBuilder
to easily add Cache Dependency Keys to the ICacheDependenciesStore
. Each data retrieval function you call should create a new instance of this CacheDependencyKeysBuilder
and add any dependencies applicable.
var builder = new CacheDependencyKeysBuilder(_siteRepository, _cacheDependenciesStore);
builder.PagePath(path, PathTypeEnum.Children);
Data caching also needs the same Dependency Keys when caching data calls (such as in the IPageRetriever
or IProgressiveCache
). You can pass the keys to these data functions from the CacheDependencyKeysBuilder
as needed.
For IPageRetriever
, see this example from TabRepository.cs
var retriever = await _pageRetriever.RetrieveAsync<Tab>(
query => query
.Path(path, PathTypeEnum.Children)
.Columns(new string[] {
nameof(Tab.DocumentID),
nameof(Tab.TabName)
})
.OrderBy(nameof(TreeNode.NodeLevel), nameof(TreeNode.NodeOrder)),
cacheSettings => cacheSettings
.Dependencies((items, csbuilder) => builder.ApplyDependenciesTo(key => csbuilder.Custom(key)))
.Key($"GetTabsAsync|{path}")
.Expiration(TimeSpan.FromMinutes(60))
);
For IProgressiveCache
, see this example from BreadcrumbRepository.cs
_progressiveCache.Load(cs =>
{
if (cs.Cached)
{
cs.CacheDependency = builder.GetCMSCacheDependency();
}
return new Breadcrumb()
{
LinkText = ResHelper.LocalizeExpression("generic.default.breadcrumbtext"),
LinkUrl = ResHelper.LocalizeExpression("generic.default.breadcrumburl"),
};
}, new CacheSettings(1440, "GetDefaultBreadcrumb", _repoContext.CurrentCulture()))
For a Widget caching, you simply set the widgetProperties.CacheDependencies.CacheKeys = ICacheDependenciesStore.End();
to set the widget's cache dependencies.
- Solution architecture
- Feature Folders
- Page Template View Component
- Interface Model Implementation Map
- Cache Dependency Building and Async
- Post Redirect Get
- Front End Asset (CSS/JS Parsing
- Navigation
- Page Builder Header/Footer
- SEO Meta Data
- Navigation Redirection
- Page Types
- Partial Widget Page / ShareableContent
- Widgets
- Account Management
- External Authentication/Two Factor Authentication
- Ecommerce Ready
- Error Pages
- Sitemap
- Robots.txt
- Form Bootstrapification
- Bundling css/javascript + Gzip
- Bootstrap and Containers