Analyze performance patterns and caching in Sitecore 10.x projects
Analyzes Sitecore 10.x projects for performance anti-patterns, caching issues, and optimization opportunities.
/plugin marketplace add twofoldtech-dakota/claude-marketplace/plugin install twofoldtech-dakota-sitecore-classic-analyzer-plugins-sitecore-classic-analyzer@twofoldtech-dakota/claude-marketplaceIdentify performance anti-patterns, caching issues, and optimization opportunities.
Detect slow Sitecore.Query usage that should be Content Search:
// Anti-pattern (slow tree traversal)
item.Axes.SelectItems(".//*[@@templateid='{...}']")
item.Axes.SelectSingleItem("ancestor::*[@@templatename='Home']")
Database.SelectItems("fast:/sitecore/content//*")
// Better (Content Search)
using (var context = index.CreateSearchContext())
{
var results = context.GetQueryable<SearchResultItem>()
.Where(x => x.TemplateId == templateId)
.ToList();
}
Detect unbounded tree traversal:
// Anti-pattern (loads entire subtree into memory)
var allItems = rootItem.GetDescendants();
var children = parentItem.GetChildren();
// Better (use Content Search with pagination)
context.GetQueryable<SearchResultItem>()
.Where(x => x.Paths.Contains(rootId))
.Take(100)
.ToList();
Check rendering cache settings in items and configs:
<!-- Rendering item fields to verify -->
<Caching>
<Cacheable>true</Cacheable>
<VaryByData>true</VaryByData>
<VaryByDevice>false</VaryByDevice>
<VaryByLogin>false</VaryByLogin>
<VaryByParm>false</VaryByParm>
<VaryByQueryString>false</VaryByQueryString>
<VaryByUser>false</VaryByUser>
</Caching>
Verify Content Search queries use pagination:
// Anti-pattern (loads all results)
var results = context.GetQueryable<SearchResultItem>()
.Where(x => x.TemplateId == templateId)
.ToList();
// Better (paginated)
var results = context.GetQueryable<SearchResultItem>()
.Where(x => x.TemplateId == templateId)
.Skip(pageIndex * pageSize)
.Take(pageSize)
.ToList();
Check for optimization opportunities:
<index id="sitecore_web_index">
<configuration>
<documentOptions>
<!-- Check for computed fields -->
<fields hint="raw:AddComputedIndexField">
<field fieldName="navigation_title">...</field>
</fields>
<!-- Check for excluded fields to reduce index size -->
<exclude hint="list:AddExcludedField">
<field>__Revision</field>
</exclude>
</documentOptions>
</configuration>
</index>
Check for proper custom cache usage:
// Good pattern
public class NavigationCache : CustomCache
{
public NavigationCache(string name, long maxSize)
: base(name, maxSize) { }
}
Check for optimized media handling:
// Check for CDN usage
Sitecore.Resources.Media.MediaManager.GetMediaUrl(item)
// Check for responsive images
<img src="@MediaManager.GetMediaUrl(item, new MediaUrlOptions { Width = 800 })" />
Analyze custom pipeline processors:
public class MyProcessor : HttpRequestProcessor
{
public override void Process(HttpRequestArgs args)
{
// Check for early exit conditions
if (Context.Item == null) return;
if (Context.PageMode.IsExperienceEditor) return;
// Processor logic
}
}
| Code | Severity | Issue | Detection |
|---|---|---|---|
| PERF-001 | Critical | Sitecore.Query in loop | Axes.SelectItems or Axes.SelectSingleItem inside foreach/for |
| PERF-002 | Critical | Unbounded GetDescendants | GetDescendants() without Take/limit |
| PERF-003 | Warning | Rendering without cache | Rendering definitions missing Cacheable=true |
| PERF-004 | Warning | Missing VaryBy params | Cached rendering without appropriate VaryBy |
| PERF-005 | Warning | Content Search no pagination | .ToList() without .Take() |
| PERF-006 | Warning | No Solr computed fields | Index config without computed fields |
| PERF-007 | Info | No custom cache | High-traffic component without caching |
| PERF-008 | Info | Media without CDN | Direct media URLs without CDN prefix |
Grep: \.Axes\.Select
Grep: Database\.SelectItems
Grep: fast:/
Grep: \.GetDescendants\(
Grep: \.GetChildren\(
Grep: \.Children
Grep: CreateSearchContext
Grep: GetQueryable
Check for .Take() usage
Glob: **/*.yml (SCS files)
Grep: Cacheable
Glob: **/App_Config/**/*index*.config
Check for computed fields and excluded fields
## Performance Analysis
### Performance Score: B
### Critical Issues
#### [PERF-001] Sitecore.Query in Loop
**Location**: `src/Feature/Navigation/code/Services/NavigationService.cs:67`
**Code**:
```csharp
foreach (var section in sections)
{
var children = section.Axes.SelectItems("./*[@@templateid='{...}']");
}
Impact: O(n) database queries, severe performance degradation Fix: Use Content Search with single query and filter in memory
Location: src/Feature/Search/code/Indexing/ContentCrawler.cs:34
Code:
var allContent = rootItem.GetDescendants().ToList();
Impact: Memory pressure, potential OutOfMemoryException Fix: Use Content Search with pagination
Location: src/Feature/Navigation/serialization/Renderings/Main Navigation.yml
Issue: Main Navigation rendering has Cacheable=false
Impact: Renders on every page request
Fix: Enable caching with VaryByData=true