A Small Change Makes a Huge Difference When It Comes to Optimizing Your Sitecore Serialization
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.
The Setup
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.
The Simple Approach to Serialization
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
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?
The Better Approach to Serialization
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.
- It solves the initial issue of wasted checks on items we know should be ignored. In this setup, we specify an include for the /Data/Articles path, set it to item only and end the configuration there. We then skip to the /Data/Config include and specify item and descendants. This means it grabs the single item for the Article folder and moved on, it does not check all the children of the Article folder as it did in the last setup.
- Each include has its own name, which means when you run the serialization, it puts those items in a folder with that name. This approach, of having multiple includes instead of one include with multiple rules, results in a more organized item structure in your project and makes it easier to find items later if you ever need to reference them or delete them.
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.
A Small but Noticeable Change
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