I'm working on a project using Umbraco CMS where I need to create a large number of nodes (content items) programmatically using the ContentService. However, I'm facing performance issues, as there are many database commands executed during SaveAndPublish and Delete operations. The time taken for the node creation and deletion process is becoming a significant concern.
I've tried using scopes with the IScopeProvider to batch the operations, but it didn't provide the expected performance improvement.
I'm looking for advice on how to optimize the database connection and improve the performance when creating and deleting a large number of nodes in Umbraco CMS. I would like to know if there are any best practices or alternative approaches that I can use to speed up these operations.
Specifically, I'm interested in understanding how to:
Here's my methods(I'm giving only vital parts, if you need more, endpoints or other stuff, I will edit and add it)
private void DeleteProducts(int count)
{
var productFolder = _umbracoHelper.GetNodeUnderRootByAlias(ContentTypeAlias.ProductsFolder);
var productsNamesForDeletion = Enumerable.Range(0, count).Select(i => $"Product {i} SV");
var products = GetProducts(productFolder.Id);
var productsToDelete = products.Where(p => productsNamesForDeletion.Contains(p.Name));
using var scope = _scopeProvider.CreateScope(isolationLevel: IsolationLevel.Serializable, repositoryCacheMode: RepositoryCacheMode.Default, autoComplete: true);
foreach (var product in productsToDelete)
{
_contentService.Delete(product);
}
scope.Complete();
}
private void CreateProducts(int count, (int productFolderId, IEnumerable<LanguageModel> languages, IContentBase productPage) setupData)
{
using var scope = _scopeProvider.CreateScope(autoComplete: true);
Enumerable.Range(0, count)
.ForEach(i => CreateAndPublishProduct(i, setupData));
scope.Complete();
}
private void CreateAndPublishProduct(int index, (int productFolderId, IEnumerable<LanguageModel> languages, IContentBase productPage) setupData)
{
var product = CreateProduct(index, setupData);
_contentService.SaveAndPublish(product);
}
Any code examples or suggestions on improving the current implementation will be greatly appreciated. Thank you in advance for your help!
Umbraco recommends using the ContentService for node creation, update or deletion, so your approach is correct. To reduce the impact on your Front-end server and website, you should consider using Hangfire and running Hangfire jobs in the background to handle your content.
Here are 5 steps to achieve this - you can find more details in my Skrift article about "Performance and Availability Improvements of Umbraco Websites with Hangfire Jobs";
Following my steps, Paul Seal created a Proof of Concept GitHub repo, which should help you further.
https://github.com/prjseal/Hangfire-Import-Proof-Of-Concept/