Thursday, May 23, 2024

Sitecore JSS Dictionary performance

 Sitecore JSS Dictionary performance tuning


We implemented a headless site with NextJS and a Sitecore 10.2 with SXA - headless SXA. The code generated by Sitecore when creating the project included all we needed to work with the SXA dictionary in a dictionary-service-factory.ts. In combination with the i18n setup this allows us to easily create and use translatable labels in our application. It works fine. 

But.. would someone please take a look at the logs...

Always watch the search logs

After a while we checked the logs to see if anything fishy was found - always a good practice, even during development cycles and when you think everything is smooth. And we noticed a lot of identical queries:

INFO  Solr Query - ?q=(((path6d119245ea284770a401ee68458abfc5) AND _language"en")) AND _templates6d1cd89719364a3aa511289a94c2a7b1)) AND _path0de95ae441ab4d019eb067441b7c2450)) AND _val:_boost&start=30&rows=10&fl=*,score&fq=_indexname:(sitecore_web_index)&wt=xml&sort=_smallcreateddate_tdt desc,_group asc

It didn't ring a bell immediately but when we executed this query in the solr admin it was very clear that this was related to the dictionary. Apparently our next app was fetching the dictionary data quite often. And in small pieces. The combination of both settings leads to a lot of queries. Even though they are probably very fast, I still thought it could be improved as the labels in our dictionary will not change frequently. 


Tweaking the DictionaryService

In the dictionary-service-factory.ts file, check for the GraphQLDictionaryService instance creation (we are using the GraphQL version):
new GraphQLDictionaryService({
      endpoint: config.graphQLEndpoint,
      apiKey: config.sitecoreApiKey,
      siteName: config.jssAppName,
      ...

Looking at the options available for this service, we found we could set a pageSize and a cacheTimeout. There is also a parameter cacheEnabled but that is true by default.  Note that the cacheTimeout has a default of 60 (seconds) and the pageSize has a default of 10 (as seen in the rows parameter in the solr query). 

For our implementation and with the number of dictionary items we have that is inefficient. We need a larger pageSize and a larger timeout. 

  new GraphQLDictionaryService({
          endpoint: config.graphQLEndpoint,
          apiKey: config.sitecoreApiKey,
          siteName: config.jssAppName,
          rootItemId: '....',
          pageSize: 150,
          cacheEnabled: true,
          cacheTimeout: Number(process.env.DICTIONARY_CACHE_TIMEOUT),

With this adjustments our dictionary was still working fine - but we had a lot less queries to solr. Note that we decided to get the timeout from an environment variable so we could tweak that between environments. You could do the same for the page if you want.


Enjoy the tips and happy dictionaring 🙂 

No comments:

Post a Comment