We are happy to announce that we have released new versions of our recorder (v1.14.1) and player (v1.11.1), mainly focused on the performance improvements listed below.

Faster recorder bootstrapping and processing of nodes

The previous recorder versions required two DOM traversals for processing the document and newly added nodes. The first was a preparation phase, and the second was about cloning and transforming the DOM. The latest recorder version requires a single DOM traversal by merging the two steps mentioned above into one.

Benchmarks show a 5% to 20% improvement over the previous version with a cold browser cache. Surprisingly, the new version shines when using a browser with a warm cache, outperforming the previous version by 50% to 80%.

How are the benchmarks done? After an initial capture for each site to ensure all assets, including stylesheets and custom fonts, were processed and stored on our servers, we measured the time the recorder took to process the whole page using our Chrome extension on an 8-core M1 Pro laptop.

Website v1.13.6 v1.14.1 +/-
cubicast.com (cold cache) 826ms 672ms 18%
cubicast.com (warm cache) 210ms 25ms 88%
microsoft.com (cold cache) 814ms 772ms 5%
microsoft.com (warm cache) 203ms 40ms 80%
cnn.com (cold cache) 817ms 623ms 23%
cnn.com (warm cache) 204ms 79ms 61%
wsj.com (cold cache) 2046ms 1658ms 18%
wsj.com (warm cache) 406ms 205ms 49%
shop.polymer-project.org (cold cache) 207ms 150ms 27%
shop.polymer-project.org (warm cache) 204ms 42ms 78%

Caching the browser fingerprint

The latest recorder stores the browser fingerprint in the session storage. Since fingerprinting is a time-consuming process, the recorder kicks in sooner upon page reloads, having better chances of tracking page views of visitors that close the browser tab shortly after the page is loaded.

Faster rendering of HTML content in the player

Each HTML element, whether the whole document element or an added node, now requires fewer DOM operations. Previously, the recorder inserted separate mutations for stylesheet elements, top-level SVG elements, video elements, and shadow roots. Our newest version requires additional modifications to be applied by the player only for shadow roots.

Better support for the :defined CSS pseudo-class

The recorder will treat all elements whose tag names contain a hyphen (-) as custom elements. We have introduced a new mutation type for the player to define custom elements using the CustomElementRegistry.define() method. Previously, the player was defining custom elements only for the elements that had a shadow root attached, but as it turns out, this is not the case.

Last but not least, these releases also include the subsequent bug fixes:

Player bugfixes
  • Fixed infinite loader when the document contains a LINK pointing to an empty stylesheet.
  • Set the correct aspect ratio for videos that use a non-default object-fit style.
Recorder bugfixes
  • Decoupled chunks from log entries to avoid the edge case of sending duplicate log entries.
  • Process private assets defined in style attributes correctly.
  • Retain video poster attribute to match [poster] CSS selectors.
  • Retain anchors' href link to match possible CSS selectors.
  • Fixed images having data URLs on internal hosts.
  • Skip capturing of unloaded video elements.
  • Make sure @charset CSS rules always stay in the beginning.
  • Keep the original asset URL if the recorder fails to extract it and log a warning.

We have also released new Chrome and Firefox extensions (v1.12.0), including the latest recorder version with all the fixes that come with it. We have also fixed video export on Chrome by adding support for Matroska v4.

As always, we would like to hear your feedback, and of course, if you face any issues, don’t hesitate to contact us.