Flicker & Flicker Control

Headline flicker explained — why it occurs, and how to prevent it on sites that are optimized for very fast first paint.

What is flicker?

Flicker or "headline flicker" is how we refer to the visitor experience of witnessing the very brief appearance of your site's CMS' headline before it quickly changes to a different headline from your active Chartbeat headline test.

Our default implementations detailed on the previous page of this guide include initializing the flickerControl variable to false and subsequently calling mab.js with the async attribute in your site's header. This setting disables our "flicker control" code contained within chartbeat_mab.js, which would otherwise automatically hide all elements contained within the <body> tags of your website until our code has completed changing headline text in your HTML (in order to prevent the possibility of your visitors experiencing headline flicker).

We recommend this implementation (flickerControl set to false) because headline flicker is unlikely to occur or be detectable by the naked eye for most websites running headline tests with Chartbeat as long as mab.js loads early in the header. This way, our script does not briefly set the <body> visibility to hidden (“flicker control” as we call it), which may be perceived by visitors as decreased page speed, and you can experiment with our flicker control options detailed below only if necessary.

Flicker control explained

We offer a few different implementation options that allow you to fine-tune how you’re making tradeoffs between fastest page render and possible flash-of-original-headline (“flicker”) for your visitors. If the flickerControl variable is not set to false when ​chartbeat_mab.js loads, we will look for a style tag on the page with id ​#chartbeat-flicker-control-style and if it doesn't exist, we will immediately add a style tag to the page with that id, with one rule that sets the <body> visibility to hidden. Once we’ve loaded our strategy from the CDN and replaced headlines in the document, we remove any style tag on the page with id ​#chartbeat-flicker-control-style​​.This causes a perceived increase to your page's load time since the <body> is hidden temporarily, which may not be ideal.

For this reason, we recommend adding the below code to your Chartbeat <head> snippet only if you need to implement flicker control. It allows you to adjust the ​#chartbeat-flicker-control-style style tag to target something other than the entire body — for instance, you could target ​#main_content if you have a content container that contains all headlines that would be tested, or target something like ​h1 or ​.headline to only make the actual headline text itself invisible until the text is updated by chartbeat_mab.js​​. The details will depend on how your HTML and CSS are structured, but fine-tuning ​#chartbeat-flicker-control-style may allow you to avoid flash-of-original-headline while allowing most of the page to render even if headlines haven’t been replaced yet. This is an advanced implementation, and we only recommend it if your site is optimized for an extremely fast first paint, making flicker more likely to occur. We’ve found that for most sites using our default implementation, headlines are replaced fast enough that there is no noticeable impact to the visitor experience.

Implementing flicker control

If implementing flicker control on your site, the flickerControl configuration variable should instead be set to true, and the following code should be added to your site's <head> snippet prior to the chartbeat_mab.js script tag:

<script type='text/javascript'>
(function() {
// Change below from "body" to a CSS selector that selects only your headlines
var css = 'body { visibility: hidden; }';
var head = document.head || document.querySelector('head');
var style = document.createElement('style');
style.id = 'chartbeat-flicker-control-style';
head.appendChild(style);
style.type = 'text/css';
if (style.styleSheet) {
// This is required for IE8 and below.
style.styleSheet.cssText = css;
} else {
style.appendChild(document.createTextNode(css));
}
window.setTimeout(function () {
var hider = document.getElementById('chartbeat-flicker-control-style');
if (hider) {
hider.parentNode.removeChild(hider);
}
}, 1000);
})();
</script>

The setTimeout function in this script script above is just a failsafe; in case ​chartbeat_mab.js doesn’t load for any reason, it will make sure the body does not remain hidden. The expected behavior is that ​chartbeat_mab.js is either already in the visitor’s browser cache or loads from our CDN very quickly, updates any headlines under test, and removes the #chartbeat-flicker-control-style​​ tag much much faster than the 1-second timeout included here (line 24 above).

Here's what that looks like altogether, included directly below our default tracking code snippet:

<script type='text/javascript'>
(function() {
/** CONFIGURATION START **/
var _sf_async_config = window._sf_async_config = (window._sf_async_config || {});
_sf_async_config.uid = #####; //CHANGE THIS
_sf_async_config.domain = 'YourDomain.com'; //CHANGE THIS
_sf_async_config.flickerControl = true;
_sf_async_config.useCanonical = true;
_sf_async_config.useCanonicalDomain = true;
_sf_async_config.sections = ''; //CHANGE THIS TO YOUR SECTION NAME(s)
_sf_async_config.authors = ''; //CHANGE THIS TO YOUR AUTHOR NAME(s)
/** CONFIGURATION END **/
function loadChartbeat() {
var e = document.createElement('script');
var n = document.getElementsByTagName('script')[0];
e.type = 'text/javascript';
e.async = true;
e.src = '//static.chartbeat.com/js/chartbeat.js';
n.parentNode.insertBefore(e, n);
}
loadChartbeat();
})();
</script>
<script type='text/javascript'>
(function() {
// Change below from "body" to a CSS selector that selects only your headlines
var css = 'body { visibility: hidden; }';
var head = document.head || document.querySelector('head');
var style = document.createElement('style');
style.id = 'chartbeat-flicker-control-style';
head.appendChild(style);
style.type = 'text/css';
if (style.styleSheet) {
// This is required for IE8 and below.
style.styleSheet.cssText = css;
} else {
style.appendChild(document.createTextNode(css));
}
window.setTimeout(function () {
var hider = document.getElementById('chartbeat-flicker-control-style');
if (hider) {
hider.parentNode.removeChild(hider);
}
}, 1000);
})();
</script>
<script async src="//static.chartbeat.com/js/chartbeat_mab.js"></script>

Tip: Remember to changebodyin the code above (line 28) to a CSS selector that targets only your page headlines in order to avoid temporarily hiding all elements in your site body. Also, feel free to adjust the 1000 millisecond timeout (line 47) to allow more time for our JS to finish loading (only relevant for users of your site with slow network connections).

Next steps

The next article in this guide details resources requested by mab.js and the (very minimal) effect this script has on page load time if implemented as our documentation suggests with the async attribute in your site's header.

For those ready to implement our code as detailed in the first page of this guide, feel free to skip ahead to our integration QA instructions article to review your work.