Lazy-loading widgets is a common practice to minimize API calls for low-visibility widgets, such as those that appear near the footer of your pages. The default behavior of the $p("fetch") function does not support lazy-loading, so you will need to enable a special config via the $p("init") function.
Enabling multiFetch
The $p("init") function has many configuration options available. The multiFetch configuration option allows for multiple register/fetch cycles on the same pageview, but at separate times (i.e., only one fetch cycle can be in progress at a given time). For multiFetch, you'll need to add the following to your beacon snippet:
var customConfig = { sdk: { multiFetch: true } }
When $p("init") is called, make sure to include the customConfig argument in order to have multiFetch enabled.
Full Beacon Snippet Example
<script type="text/javascript"> if (typeof $igniter_var === 'undefined') { !function n(t,c,o,r,a,i,e,s,f){f=null!=t[o]&&"function"==typeof t[o].now?t[o].now():null,t.$igniter_var=i,t[i]=t[i]||function(){(t[i].q=t[i].q||[]).push(arguments)},e=c.getElementsByTagName(r)[0],(s=c.createElement(r)).async=1,"//cdn"==a?(t[i].s=f,s.onerror=function(e){t[i].e=e,n(t,c,o,r,a+"-fallback",i)}):t[i].r=f,s.src=a+".petametrics.com/{YOUR_JS_KEY}.js?ts="+(new Date/36e5|0),e.parentNode.insertBefore(s,e)}(window,document,"performance","script","//cdn","$p"); var customConfig = { sdk: { multiFetch: true } } $p("init", "YOUR_JS_KEY", customConfig); $p("send", "pageview"); } </script>
Enabling allowLazyRegister or registering some widget lazily
Another useful configuration for the $p("init") function is the allowLazyRegister configuration.
Without the allowLazyRegister config, any register or fetch call made while an existing fetch is ongoing (usually, because the network request is in progress) fails. This can be a problem in some cases if users scroll very rapidly from one widget to another, causing the lazy-load fetch for the second widget to complete while the lazy-load for the first widget is ongoing.
allowLazyRegister queues up all registers and fetches done while an existing fetch is in progress. This may still not be ideal, as it means that the new register/fetch is delayed till the old one completes, but it does make sure that the new register/fetch does occur eventually rather than get blocked. If you want a solution that gives the new register/fetch precedence over any existing fetches, it is better to not use allowLazyRegister and to instead use abortActiveRequests.
var customConfig = { sdk: { multiFetch: true, allowLazyRegister: true } }
Full Beacon Snippet Example
<script type="text/javascript"> if (typeof $igniter_var === 'undefined') { !function n(t,c,o,r,a,i,e,s,f){f=null!=t[o]&&"function"==typeof t[o].now?t[o].now():null,t.$igniter_var=i,t[i]=t[i]||function(){(t[i].q=t[i].q||[]).push(arguments)},e=c.getElementsByTagName(r)[0],(s=c.createElement(r)).async=1,"//cdn"==a?(t[i].s=f,s.onerror=function(e){t[i].e=e,n(t,c,o,r,a+"-fallback",i)}):t[i].r=f,s.src=a+".petametrics.com/{YOUR_JS_KEY}.js?ts="+(new Date/36e5|0),e.parentNode.insertBefore(s,e)}(window,document,"performance","script","//cdn","$p"); var customConfig = { sdk: { multiFetch: true, allowLazyRegister: true } } $p("init", "YOUR_JS_KEY", customConfig); $p("send", "pageview"); } </script>
It is also possible to execute specific registers and fetches lazily even if you don't want to globally use lazy register/fetch. You can selectively execute registers and fetches lazily by passing in a "lazy" at the end of the register or fetch call, as follows:
$p("register", {args for register}, "lazy") $p("fetch", {args for fetch}, "lazy")