Sitecore Development 101: Optimizing Your Sitecore Serialization
A small change you can make to your Sitecore serialization modules to heavily improve performance by lowering run time
Start typing to search...
When working with Sitecore serialization, especially in the early stages of a project, performance will often be put on the back burner. However, as the project grows and solutions scale, the time it takes to serialize and deserialize items can increase significantly, creating bottlenecks that slow down your development workflow. While there are many optimizations that can be made at a higher level, sometimes it’s the smallest tweaks that yield the biggest gains.
In this blog, we’ll explore a simple yet impactful change you can make to your Sitecore serialization modules to improve performance. This adjustment requires minimal effort but can have a noticeable effect on your productivity and deployment speed. Let me show you how a little fine-tuning can make a big difference in your serialization process.
First let’s paint the picture, let’s say we have a site setup that has a Data folder and inside that Data folder we have 2 child folders, “Articles” and “Config”. Articles is a bucket where the Content Authors will create articles to put on their site and Config is just a folder to hold configuration settings such as rendering options.
When we setup the serialization for this example, since typically you serialize items that are structural or items that won’t be changed by Content Authors, we would want to serialize the parent Data folder, the Article folder but not it’s children and the entire Config folder, item and descendants.
If you were to actually implement the serialization described above, and had a small project that wouldn’t run you into any performance issues, it would look something like this in your module file:
{
"namespace": "Content.FakeProject",
"references": ["Content"],
"items": {
"includes": [
{
"name": "$Content/Site",
"path": "/sitecore/content/FakeProject",
"scope": "ItemAndDescendants",
"allowedPushOperations": "createAndUpdate",
"rules": [
{
"path": "/Data",
"scope": "SingleItem",
"allowedPushOperations": "CreateOnly"
},
{
"path": "/Data/Articles",
"scope": "SingleItem",
"allowedPushOperations": "CreateOnly"
},
{
"path": "/Data/Config",
"scope": "ItemAndDescendants",
"allowedPushOperations": "CreateOnly"
},
{
"path": "/*",
"scope": "ignored"
}
]
}
]
}
}
With this configuration, serialization will absolutely work and there isn’t anything explicitly wrong with it. It will iterate through the entire FakeProject site creating a single Data item, single Data/Article item and all the Data/Config items. With small datasets, it is a great setup.
The issue with this setup is, as datasets increase and more and more items get added, it can easily become a performance issue. Imagine as time goes on, the Authors start adding Articles and before you know it there are 10,000 articles sitting inside buckets organized by year and month. With the above configuration, it has to iterate through all items checking their paths against all the configured rules. Even though we set it up that /Data/Articles should be a single item and all other sub paths ignored, it still has to check those paths to ensure they should be ignored. This results in a serialization that has to check 10,000 articles that could and should be skipped altogether. So how do we configure it to do so?
To set up the serialization module to ensure that we are truly ignoring the Sitecore items we do not want serialized and not bog down the process we would have a configuration module that looks like this:
{
"namespace": "Content.FakeProject",
"references": ["Content"],
"items": {
"includes": [
{
"name": "$Content/FakeProject/Root",
"path": "/sitecore/content/FakeProject",
"scope": "SingleItem",
"allowedPushOperations": "createAndUpdate"
},
{
"name": "$Content/FakeProject/Data",
"path": "/sitecore/content/FakeProject/Data",
"scope": "SingleItem",
"allowedPushOperations": "createAndUpdate"
},
{
"name": "$Content/FakeProject/Data-Articles",
"path": "/sitecore/content/FakeProject/Data/Articles",
"scope": "SingleItem",
"allowedPushOperations": "createAndUpdate"
},
{
"name": "$Content/FakeProject/Data-Config/",
"path": "/sitecore/content/FakeProject/Data/Config",
"scope": "ItemAndDescendants",
"allowedPushOperations": "createAndUpdate"
}
]
}
}
With this approach, you will notice a minor difference. Instead of having one single include object with the Root project as the path and rules to determine which items to include or ignore, we have it now setup with various includes for the specific items (and possibly their children). This approach is better for 2 reasons.
This setup can also be further broken down into more includes if sub folders begin to get to large. You could break the config down into a single item config folder and then add includes for sub folders of the config path if any of those became item dense.
The upside and downside of the Sitecore Serialization modules is that it is fully customizable to your needs, but you can quickly configure yourself into a runtime nightmare if you are not careful. With this better approach to your configuration setup you are now headed in the right direction to have a more efficiently organized and scalable serialization process.
Thanks for reading! If you found this helpful, you can also check out my other blogs in the Sitecore Development 101 series:
Sitecore Development 101: Creating a Custom Rendering Contents Resolver
Sitecore Development 101: Creating an Interactive PowerShell Script
Sitecore Development 101: The Ultimate Beginner’s Sitecore PowerShell Cheat Sheet