LibrarySites.Banner

Screenshot Settings for Content Testing

There are various settings and features to control how screenshots of pages are generated for Content Testing in Sitecore 8. This article will take you through these settings and features to give you a better understanding about what's available.

Let me just say this. Generating screenshots of web pages is not as simple as you think it should be.

As part of the Content Testing features which we introduced in Sitecore 8.0, we often need to show screenshots of the web page to the user. The screenshots are used to help describe which component / content on the page is under test and show the different variations.

Now, on the surface, generating a screenshot is easy right? Use a 3rd party library or the WebBrowser control and just call an API with the URL of the page you want to generate the screenshot of. And mechanically that's all we need to do. What causes a lot of issues is the time it takes to generate the screenshot, and the volume of screenshots we need to generate. And compounding all of that is how fast the website underneath is. If we just generated the screenshots sequentially on demand, the user would be left hanging thinking the UI has frozen until the images are all finally generated and shown.

To overcome these issues we've employed several techniques and provided options for developers.

Multi-threaded and async

When generating screenshots for the UI we use multiple threads which are by nature asynchronous. The UI uses a callback technique to check with the server when the screenshot images are available. We also need to avoid usage of SessionState and tweak the request configuration to allow the requests for the screenshots to be run in parallel.

PhantomJS

Content Testing in Sitecore uses the Phantom JS tool for generation of the screenshot image files. In case you didn't know, Sitecore has had screenshot generation features for quite some time. We use it to generate icons for items that you'll be listing in the UI like renderings. These icon generation features are based on the System.Windows.Forms.WebBrowser control built into .net. So why did we not use the existing screenshot features for Content Testing? In early testing we found discrepancies with the WebBrowser control. WebBrowser uses Internet Explorer installed on the server where Sitecore is running. But the specific version that it uses isn't always the latest. There are registry updates one can make to force the appropriate IE version, but this seemed like a big ask of users. This was one of the reasons we chose to use Phantom JS instead.

GenerateScreenshots Setting

So let's start with the first option: the ContentTesting.GenerateScreenshots setting. This setting is defined in the App_Config\Include\ContentTesting\Sitecore.ContentTesting.config file. This setting controls which types of screenshot are shown in the test creation dialog and "create page test" page of the Experience Optimization app from the Launch Pad. This setting can have one of the following values:

  • all: This is the default option. Screenshots will always be shown.
  • limited: Screenshots will only be shown for content change tests.
  • none: Screenshots will not be shown.

This option is of great use when your users don't care for the screenshots and you want to speed up the UI.

But what if your users like the screenshots and also like to speed up the UI? In that case you'll want to use the pre-emptive screenshot generation handler.

Pre-emptive Screenshot Generation

Generating a single screenshot takes time, as mentioned above. Generating screenshots on demand means making the users wait while each screenshot image is generated. The biggest performance boost we can make to screenshot generation is to generate the files ahead of time before they're needed. This is what the pre-emptive screenshot generation event handler does.

As the name suggests, this is an event handler which generates the screenshots as the change is made so the image file is available when required and we don't have to wait while the image is generated. In Sitecore 8.0, Update 1 and Update 2 this event handler was present and enabled in the configuration patch file App_Config\Include\ContentTesting\Sitecore.ContentTesting.config. However we disabled the event handler from Update 3 and onwards by default by commenting out the event handler declaration in the config file. We decided to disable the event handler by default due to the potential performance impact. This was a hard call; Do we ensure the features all work with minimal input from the user or remove an embellishment to ensure performance. And performance won out in the end. If you'd like to enable the handler, just uncomment it in the config patch file.

The pre-emptive screenshot generation generates screenshots for test candidates when the item is saved. If the item doesn't have any test candidates then no screenshot will be generated. The screenshots are generated asynchronously so as not to delay the UI. The test candidates we inspect for are:

  • Content changes: Items with multiple versions will yield this test candidate.
  • Component (Multivariate) tests: Tests configured on a rendering.
  • Personalization Rules: Renderings with personalization rules.

Not all content changes need to be tested, so the event handler includes configuration to exclude changes in fields from generating updated screenshot images. Developers can add additional fields in the <excludeFields hint="list:ExcludeFieldFromComparison"> node to have them ignored.

There are separate handlers for local events raised on the local server (single Content Management (CM) server) and for remote events raised on a separate CM server. So if you're going to use the event handler, make sure you enabled all the handlers required for your setup.

Screenshot Disabler

If you've enabled the pre-emptive screenshot handler and have programmatic tasks making edits to many items, all that additional overhead of screenshot generation on every item save can have an impact on performance. In these cases developers can use the ScreenshotGenerationDisabler to temporarily disable the event handler. The ScreenshotGenerationDisabler works in the same way as the SecurityDisabler.

using(new Sitecore.ContentTesting.Configuration.ScreenshotGenerationDisabler())
{
  // editing lots of items
}

Operations performed inside the using will now not generate screenshots and won't impact performance.

PhantomJS Settings

There are also several settings in the config file to control how PhantomJS runs.

  • ContentTesting.PhantomJS.EnableDiskCache: Allows PhantomJS to store web resources such as images and CSS on disk. Saves network time for the same web resource and speeds up future requests.
  • ContentTesting.PhantomJS.EnableJavaScript: Allows Javascript on the page to run.
  • ContentTesting.PhantomJS.IgnoreSSLErrors: Ignores SSL errors when accessing the site over HTTPS.
  • ContentTesting.PhantomJS.LoadImages: Allows PhantomJS to load images for the page.
  • ContentTesting.PhantomJS.LockNavigation: Prevents resources from other URLs to be loaded including iframes.
  • ContentTesting.PhantomJS.SSLProtocol: Instructs PhantomJS which SSL protocol to use.
  • ContentTesting.PhantomJS.Timeout: The timeout allowed for PhantomJS to complete it's work, given in milliseconds.

Screenshot Caching

Whenever a screenshot image is generated it's saved to disk under the /temp/screenshot folder. This saves from having to generate the same screenshot again for another request.

Conclusion

With these options in hand you can now tweak the screenshot settings to get your balance between performance and convenience.

Alistair Deneys
Content Testing Project Team