BLOG

Sathish Balakrishnan Author's Perspective
4 Minute read

Sitecore Performance Best Practices

As we know, Sitecore is one of the most powerful and flexible content management systems available today. It can help to create top-notch brand experiences and serve personalized content that users love. Here are some of the best practices brands must follow to leverage its full potential:

To begin with, website performance is the backbone of a successful business. As a visitor, if I browse your website and there is a delay in loading the webpage, I would like to browse your competitor website. And if for the uninitiated, based on website performance, Google ranks it.

Below are the key points which a developer/architect should follow to improve website performance. We can divide this into different categories:

Coding Practices

Let's look at some of the most significant practices:

Limit the use of GetAncestors and/or GetDescendants API calls - Sitecore recommends limiting the use of GetAncestors and/or GetDescendants API calls as they are known to have performance issues under load.

Limit the use of Sitecore Query - If performance issues occur on controls that use Sitecore query, update the code to use the search index.

Handle Unmanaged Objects - For unmanaged objects, using a loop approach is good for the items below. HtmlTextWriter,MemoryStream, StreamWriter, StringWriter, StreamReader, FileStream ,DbConnection, Stream, HttpWebResponse and WebClient etc

Minimise writing log info - Use log.info only for specific purposes. Also, instead of using log.info, use log.debug and enable the below-mentioned debug mode configuration if required in Sitecore.Logging.config.

<configuration xmlns:patch="http://www.sitecore.net/xmlconfig/">
	<sitecore>
		<log4net>
			<root>
			<priority value="DEBUG" />
			</root>
		</log4net> 
	</sitecore>
</configuration>
  • Data caching - Data Caching increases the performance by storing copies of data accessed frequently from external systems, in a high-performance subsystem. Sitecore provides caching that works on top and beyond other caching systems provided by IIS, ASP.NET, database servers and by the internet infrastructure in general. To check the data cache, you can load the hostname/Sitecore/admin/cache.aspx on the CM instance. The cache size should be between 70-80%.
  • Minified & Compressed CSS and JS - This helps to boost the performance of the application by reducing the page requests to the server.
  • Avoid too Many CSS Files - Having too many CSS and JS files creates issues. Combine custom CSS to one or two CSS files.
  • Inline CSS and Style Tags - Inline styles and style tags should be moved to CSS, which will allow the browser to cache these styles and improve performance.

Sitecore Content Tree

  • Presentation Caching -Besides data caching, Sitecore provides presentation output caching to improve performance. The layout engine implements caching by retrieving the output that is previously generated by a component, under similar conditions, instead of invoking the component again.
  • By default, the layout engine executes each presentation component for each HTTP request, without any output caching

  • Limit the number of versions of any item - Sitecore recommends keeping the fewest possible versions of any item, which helps in better editing and publishing performance.
  • Limit the number of items under the same parent -Sitecore recommends limiting the number of items under any Sitecore node which share the same parent item, and it should be only up to 100 items.
  • Use TreeListEx instead of TreeList field type - Use TreelistEx instead of Treelist to improve content tree load time.
  • Optimize Sitecore caches - Increase and tune the size of the data, items, and prefetch caches. Bigger caches = better performance
Ebook
Sitecore CMS for Multi-site implementation

IIS Settings

Enable Static/Dynamic content compression - This helps to boost the performance of the application by reducing the page requests to the server, or by browsing the pages. One can utilize static and dynamic compression in IIS.

When you enable 'IIS static content compression', static responses get compressed and cached on the disk across multiple requests, and without degrading CPU resources. By default, static content compression is enabled in IIS.

Sitecore Search Coding Best Practices-

  • GetItem() - Never get the object from SearchResultItem like below. Try to get all fields from the index. This impacts the performance badly.

    var result = query.Select(x => x.GetItem());

  • Select Statement - Use select statement to get specific fields from the search query. Do not get all the results. It increases IIS payload if we get all the results. i.e. var result = searchContext.GetQueryable()
    .Where(expression)
    .Select(x => new { x.ItemId })
    .GetResults();
  • FilterQuery and Query Expression- For Solr search, you should use FilterQuery instead of Query to filter results. Below is an example.
    Where => q -> searchContext.GetQueryable<searchResultItem>().Where(expression)
    Filter => fq ->searchContext.GetQueryable<searchResultItem>().Filter(expression)
    "fq" stands for Filter Query.
    Since filterquery is cached from the main query and doesn't participate in scoring, it improves the performance.
  • Paging - Always use pagination to get results from the query. Do not get all results once.
  • Computed Field - Utilize computed field feature. Don't execute a complex business logic to get field value after getting search results.
  • Indexed vs Stored Fields in Solr Schema - You should review your Solr schema and decide whether you have to set Indexed="true", Stored="true" with custom fields.
    Indexed="true" => means this field will be used for filtering results or for sorting results.
    stored="true" => means we can retrieve this field from the result and use it anywhere for any logic.
    If you have any custom field which you are using only for sorting, you can set stored="false" like below.
    <field name=”namesort” type=”alphaOnlySort” indexed=”true” stored=”false” />
  • Inbound and Outbound Index Filters - Use inbound and outbound index filters pipeline to filter unwanted documents from index which reduces index size.

    public class ApplyInboundIndexStandardValuesFilter : InboundIndexFilterProcessor

    {

    public override void Process(InboundIndexFilterArgs args)

    {

    var item = args.IndexableToIndex as SitecoreIndexableItem;

    if (item.Item.Name == "__Standard Values")

    {

    args.IsExcluded = true;

    }

    }

    }

    public class ApplyInboundIndexVersionFilter : InboundIndexFilterProcessor

    {

    public override void Process(InboundIndexFilterArgs args)

    {

    var item = args.IndexableToIndex as SitecoreIndexableItem;

    if (!item.Item.Versions.IsLatestVersion())

    {

    args.IsExcluded = true;

    }

    }

    }

    public class ApplyOutboundNullItemFilter : OutboundIndexFilterProcessor

    {

    public override void Process(OutboundIndexFilterArgs args)

    {

    if (args.IndexableUniqueId == null)

    {

    return;

    }

    if (args.IndexableDataSource == "sitecore")

    {

    try

    {

    var uri = new ItemUri(args.IndexableUniqueId);

    var database = Factory.GetDatabase(uri.DatabaseName);

    var item = database.GetItem(uri.ItemID, Sitecore.Context.Language);

    if (item == null)

    {

    args.IsExcluded = true;

    }

    }

    catch (Exception ex)

    {

    }

    }

    }

    }

    Sitecore Configuration -
    <indexing.filterIndex.inbound>
    <processor type="MyWebsite.Search.Pipelines.ApplyInboundIndexVersionFilter, MyWebsite.Search"></processor>
    <processor type="MyWebsite.Search.Pipelines.ApplyInboundIndexStandardValuesFilter, MyWebsite.Search"></processor>
    </indexing.filterIndex.inbound>
     
    <indexing.filterIndex.outbound>
    <processor type="MyWebsite.Search.Pipelines.ApplyOutboundNullItemFilter , MyWebsite.Search" />
    </indexing.filterIndex.outbound>

  • Crawlers -You should use multiple location crawlers in configuration to index if there is no need to index all content, to reduce index size. Below is the example-
  • <locations hint="list:AddCrawler">
    <crawler type="Sitecore.ContentSearch.SitecoreItemCrawler, Sitecore.ContentSearch">
    <Database>web</Database>
    <Root>/sitecore/content/Events</Root>
    </crawler>
    </locations>
    <locations hint="list:AddCrawler">
    <crawler type="Sitecore.ContentSearch.SitecoreItemCrawler, Sitecore.ContentSearch">
    <Database>web</Database>
    <Root>/sitecore/content/People</Root>
    </crawler>

    </locations>

  • IndexAllFields - You should avoid indexAllFields =“true". Instead of this, you should add all fields which are being used in search like below.
  • <include hint="list:AddIncludedField">
    <BlogTitle>{C56BBA6B-6A5A-4A31-B80F-A3ED88801E54}</BlogTitle>
    </include>

Infrastructure

From an infrastructure point of view, we should consider the below best practices to get better site performance.

  • Separate Content Management and Content Delivery Servers
  • Use Load Balancer with 2 or more Content Delivery servers
  • Separate Solr Master and Solr Slave Servers
  • Use Load Balancer with 2 or more Solr Slave servers

All in all, follow these best practices and see how your website performance is enhanced in no time!

Sathish
Sathish Balakrishnan VP-Technology and Delivery


Browse Topics

Talk to our Experts

Talk to us about how we bring together 1:1 personalisation, deep Martech Expertise, CX & Demand Gen Strategy, Engagement Analytics & Cross-Channel Orchestration to drive award winning experiences that convert

Get in touch for a complimentary consultation or a demo today.

Expert Workshops

Free workshops, expert advice & demos- to help your realize value with Sitecore

Register

Session Presentations

  • Sitecore + SFMC= Marketing Success
  • Transforming The Future Of eCommerce
Meet Us

Giveaways:

Participate in our event survey , meet us at our booth , get free giveaways & a chance to win an iPhone 11

Let’s go