How long does it take to open a Sitecore node?

In Sitecore builds a lot of the focus during development and performance tuning is understandably around the customer facing experience. Recently we’ve needed to investigate performance issues within the CMS itself. If you’ve ever dug into this you’ll know its a tricky application to analyse as a lot of the interactions are client-side.

One metric we wanted to gather was ‘how long does it take to open up a sitecore node’? With the help of support they suggested digging into the js file which glues all this together: ‘\sitecore\shell\applications\content manager\content editor.js’.

If you add in the following log entries the chrome console should reveal all:

and then to finish up:

and

load times

Depending on your findings you have a few options for improving performance. Be sure to check you’ve set the pre-fetch cache sizes (/app_config/prefetch/master.config) and the master db cache sizes.

Customizing the Sitecore Rich Text Editor

You have several options when customizing the Sitecore Rich Text Editor. It’s simple to setup custom sets of buttons and assign to different templates. If you are unsure on doing this I’d suggest googling ‘sitecore custom rich text editor’. This post details how to use the ‘Html Editor Configuration Type’ items.

Within the application there are various global settings which configure things like default tags to use for line breaks, which profile to use as default and a few more:

The problem we ran into was that for certain rich-text-editors we wanted the line breaks to be br tags, elsewhere p tags. This ruled out the setting above.

One hidden feature which is very useful is the ability to setup different configurations for each rte. If you look in the folder in core ‘/sitecore/system/Settings/Html Editor Profiles/Rich Text Default’ you will see an item of type ‘/sitecore/templates/System/Html Editor Profiles/Html Editor Configuration Type’. Here you can define a type, the default mapped to ‘Sitecore.Shell.Controls.RichTextEditor.EditorConfiguration,Sitecore.Client’

If you need to setup specific RTE’s to use br tags instead of p tags:

  • Setup your custom RTE profile in core
  • Create an item of type ‘/sitecore/templates/System/Html Editor Profiles/Html Editor Configuration Type’ called ‘Configuration Type’
  • Create a new class which inherits from ‘Sitecore.Shell.Controls.RichTextEditor.EditorConfiguration’
  • Update the ‘Configuration Type’ item to reference your new class
  • Override the methods you need – I found simply overriding SetupEditor was enough (see below).

An example of the code:

Sitecore parallel publishing

In version 7.2 Sitecore introduced the ability to really crank up the publishing performance of the application. There is a lot more information about how to enable Sitecore parallel publishing at http://www.sitecore.net/Learn/Blogs/Technical-Blogs/Reinnovations/Posts/2014/03/Enabling-Parallel-Publishing.aspx

During testing it was found the time it took to publish was noticeably shortened. See here for some stats.

One uncertainty was exactly what does parallel publishing do behind the scenes? What does ‘parallel’ actually mean?

  • The setting MaxDegreeOfParallelism configures the number of threads to use
  • Languages are published concurrently
  • You don’t get any more publish queues by increasing the number of threads. This means you can only run 1 publish at a time still.
  • Publishing targets are published to in sequence – e.g. if you have 2 targets: web1 & web2 and publish to both, items will appear in web1 first, once complete items will then be pushed to web2
  • Be careful cranking things up too much – you need to ensure the servers in use can cope with the load. The dbs will be under a lot more strain during the publishes
  • For any diagnostics check in the new log file generated specifically for publishing

How to prove the targets run in series?

I ran a simple experiment to prove this:

  1. Create 2 publish targets: web & web2
  2. Create folder structure:
    1. Parallel item (folder)
    2. + item for web (only allowed to publish to web)
    3. + item for web2 (only allowed to publish to web2)
  3. Added custom publish item processor with Thread.Sleep(###)
  4. Run publish with MaxDegreeOfParallelism set as 4
  5. Check web db and check web2 db via dbbrowser

The data arrived:

  • Web 2a
  • Web 2b
  • Web2 2a
  • Web2 2c

The publish logs and the UI also indicate its one target after another.

1048 08:44:27 INFO  Settings.Publishing.MaxDegreeOfParallelism:4

…

8588 08:44:45 INFO  [Publishing]: Starting to process 2 publishing options

8588 08:44:45 INFO  [PublishOptions]: root:{8960D17C-38F1-4DB0-8EBD-FD6B128D9E00}, language:en, targets:Web, database:web, mode:SingleItem, smart:False children:True, related:False

8588 08:44:45 INFO  [PublishOptions]: root:{8960D17C-38F1-4DB0-8EBD-FD6B128D9E00}, language:en, targets:Web2, database:web2, mode:SingleItem, smart:False children:True, related:False

…

7040 08:44:46 INFO  Starting [ParallelPublishing] – ProcessQueue

7040 08:44:46 INFO  Processing queue

7040 08:45:46 INFO  Processing re-try list (count=0)

7040 08:45:46 INFO  Finished [ParallelPublishing] – ProcessQueue in 60354 ms

7040 08:45:46 INFO  Publish Mode : SingleItem

7040 08:45:46 INFO  Created : 2

7040 08:45:46 INFO  Updated : 1

7040 08:45:46 INFO  Deleted : 0

7040 08:45:46 INFO  Skipped : 1

…

10136 08:45:46 INFO  Starting [ParallelPublishing] – ProcessQueue

10136 08:45:46 INFO  Processing queue

10136 08:46:46 INFO  Processing re-try list (count=0)

10136 08:46:46 INFO  Finished [ParallelPublishing] – ProcessQueue in 60101 ms

10136 08:46:46 INFO  Publish Mode : SingleItem

10136 08:46:46 INFO  Created : 2

10136 08:46:46 INFO  Updated : 1

10136 08:46:46 INFO  Deleted : 0

10136 08:46:46 INFO  Skipped : 1

Two submit buttons in Sitecore WFFM

We recently ran into an interesting challenge where the user wanted two submit buttons on their wffm form, the value of which then needed logging in the WFFM database. Note this approach does rely on javascript.

WFFM gives you the ability to setup custom fields (see Sitecore docs). I based this implementation on section 3.7.3

In your solution setup a custom ascx:

and then the code behind:

You then need to create the custom field within Sitecore. This wants to live in ‘/sitecore/system/Modules/Web Forms for Marketers/Settings/Field Types/Custom’. The only field you need to set is the UserControl field. In my example this was /forms/customformitem.ascx.

When you setup your form you can then select:
select the type

In the front end this looks like:
form

And finally, when you submit you get:
report

Sorry mr a@b.com!, you might receive a few test signups 🙂

Summarising the Sitecore log

The Sitecore log analyser is a great tool for viewing patterns in log files over time.

If getting access to log files is slow or you simply want a quick summary of certain log files then hopefully the following might help. You can select the date range, filter terms and then view all log entries which fulfil that pattern.

I’d consider it to live in the same realm as the ‘/sitecore/admin’ pages as it can reveal critical site information (hence the admin check).

The front end isn’t the most glamourous but serves its purpose:

and then the code behind:

GetItem on unpublishable Sitecore items

Consider the following code:

All pretty straight-forwards. It knowingly uses the master db as its only needed within the cms realm.

How about if the item in question in unpublishable? What then happens? You get null!!?? So, how to actually get the item?

If you wanted to expand the idea and make it a bit more reusable you could build a disposable switcher to apply the same changes.

Hopefully this helps as it had me stumped for a while!

Sitecore event handlers

One very useful area of Sitecore is the ability to subscribe to system events. Examples are things like when items are saved (item:saved), items are published etc.

All the out the box events can be seen within the <events> section of the config.

You can subscribe to events via config:

and raise your own custom events via:

One thing to note, events such as item:saved will be run when sometimes you don’t expect it. Examples are package installations.

You can guard against custom event handlers running during package installations if you check for the existence of the current httpContext:

For more info on how to make use of Sitecore events, have a look at http://sdn.sitecore.net/Articles/API/Using%20Events.aspx

Sitecore pipeline groups

Recently we’ve (mvp’s) have been lucky enough to get hold of a copy of the technical preview of Sitecore 8. It’s worth noting that anything within this version is subject to change!

One thing that a few people noticed and asked about during the Symposium was some additional config options around pipelines e.g.:

This group syntax was something I’d not seen before – read on to find out how it works.

If you want to then run the pipeline you simply need to include the “domain” in the call. This example is from the TrackingManager within the new FXM dll’s:

where this.pipeline is:

One of the cool additions to the new Abstractions dll!

Another addition in the Sitecore 8 otb setup is more structure to the app_config folder. It’s all too easy for this to become rather unruly so this form of segmentation is a nice addition.
config folder

Large number of Sitecore items per folder

Sitecore always recommend a limit of around 100 items per folder. After running some tests on 2 versions of a tree I can see why! Below are a few stats to back that up.

Before:
before

And after:
after

Then running some queries over all the descendant items revealed:

Nested folders (after)
Total: 341
Time to read: 639ms

Flat items (before)
Total: 336
Time to read: 1786ms

Its clearly much faster to access all the items even with just some simple nesting (roughly 80 items per folder) rather than 300+ in one folder.

Sitecore – lots of versions or lots of children?

The performance of your site can very quickly deteriorate if you are using a non bucket content structure and either the number of items in a folder bloats or the number of versions of an item bloats.

For a bit more reading on the number of items per folder see: Large number of Sitecore items per folder

These sql scripts allow you to quickly find the number of these offenders:
Children in a folder

Versions of an item