Yandex metrika tag slowing down site speeds google page speed isights reporting - pagespeed

So on all my web pages i have this code what is used by Yandex metrika for analytics. According to google this script is slowing down my pages and needs something changing in the way it loads to not be render blocking, TTI time to input blocking, FID first input delay blocking, First contentful paint blocking.
<script data-cfasync="false" type="text/javascript">
(function(m,e,t,r,i,k,a){m[i]=m[i]||function(){(m[i].a=m[i].a||[]).push(arguments)};
m[i].l=1*new Date();k=e.createElement(t),a=e.getElementsByTagName(t)[0],k.async=1,k.src=r,a.parentNode.insertBefore(k,a)})
(window, document, "script", "https://mc.yandex.ru/metrika/tag.js", "ym");
ym(XXXXXXXX, "init", {
clickmap:true,
trackLinks:true,
accurateTrackBounce:true,
webvisor:true
});
</script>
Googles page speed reports the following
https://developers.google.com/speed/pagespeed/insights/
What can i modify the Yandex metrika javascript to in order to fix this issue ?

You don't have many options I am afraid as it is a third party script.
One option to improve your score and perceived load times is to wrap the call to the function in a setTimeout set long enough to delay loading the script until the essential content is loaded.
<script data-cfasync="false" type="text/javascript">
setTimeout(function(){
(function(m,e,t,r,i,k,a){m[i]=m[i]||function(){(m[i].a=m[i].a||[]).push(arguments)};
m[i].l=1*new Date();k=e.createElement(t),a=e.getElementsByTagName(t)[0],k.async=1,k.src=r,a.parentNode.insertBefore(k,a)})
(window, document, "script", "https://mc.yandex.ru/metrika/tag.js", "ym");
ym(XXXXXXXX, "init", {
clickmap:true,
trackLinks:true,
accurateTrackBounce:true,
webvisor:true
});
}, 5000); //set this as high as you can without ruining your stats.
</script>
This is definitely a workaround and I would instead advise using a different library that is less bloated if you can find one.

<script data-cfasync="false" type="text/javascript">
(function(){
var a = function() {try{return !!window.addEventListener} catch(e) {return !1} },
b = function(b, c) {a() ? document.addEventListener("load", b, c) : document.attachEvent("onreadystatechange", b)};
b(function(){
(function(m,e,t,r,i,k,a){m[i]=m[i]||function(){(m[i].a=m[i].a||[]).push(arguments)};
m[i].l=1*new Date();k=e.createElement(t),a=e.getElementsByTagName(t)[0],k.async=1,k.src=r,a.parentNode.insertBefore(k,a)})
(window, document, "script", "https://mc.yandex.ru/metrika/tag.js", "ym");
ym(XXXXXXXX, "init", {
clickmap:true,
trackLinks:true,
accurateTrackBounce:true,
webvisor:true
});
}, false);
})();
</script>

One option is to use old Yandex Metrika code (new Ya.Metrika...).
You can view the old code if you set checkbox in advanced settings of the Metrika. Old code has some limitation but it's much smaller and few times faster.

Disabling clickmap and webvisor could help.

Related

Is it possible to make GTM Custom HTML tag not to insert new <script/> tags into the DOM?

There is a Single Page App with Facebook Pixel integrated via Google Tag Manager as Custom HTML tag.
<script>
(function() {
fbq({{Facebook Pixel Track Type}}, {{Facebook Pixel Event Name}});
})()
</script>
This tag is firing on every history change. And on every history change new
<script type="text/javascript" id="">fbq(google_tag_manager["GTM-XXXXXXX"].macro('gtm22'),google_tag_manager["GTM-XXXXXXX"].macro('gtm23'));</script>
is inserted into the DOM.
multiple script tags added to the page
The only way I found just remove executed script tags.
<script id='facebook-pixel-hit'>
(function() {
fbq({{Facebook Pixel Track Type}}, {{Facebook Pixel Event Name}});
setTimeout(function() {
var scriptTag = document.getElementById('facebook-pixel-hit')
if (scriptTag)
scriptTag.remove()
}, 500);
})()
</script>
but it doesn't look like a good solution.
Are there any ways to avoid adding multiple tags into the DOM?

How can I tell if my Google content experiment is running?

I've created a google content experiment without redirects using the docs.
The basic implementation involves a javascript snippet that uses the following code to choose the version of the experiment:
<!-- Load the Content Experiment JavaScript API client for the experiment -->
<script src="//www.google-analytics.com/cx/api.js?experiment=YOUR_EXPERIMENT_ID"></script>
<script>
// Ask Google Analytics which variation to show the user.
var chosenVariation = cxApi.chooseVariation();
</script>
<!-- Load the JQuery library -->
<script src="//ajax.googleapis.com/ajax/libs/jquery/2.0.0/jquery.min.js"></script>
<script>
// Define JavaScript for each page variation of this experiment.
var pageVariations = [
function() {}, // Original: Do nothing. This will render the default HTML.
function() { // Variation 1: Banner Image
document.getElementById('banner').src = 'bay-bridge.jpg';
},
function() { // Variation 2: Sub-heading Text
document.getElementById('heading').innerHTML = 'Look, a Bridge!';
},
function() { // Variation 3: Button Text
document.getElementById('button').innerHTML = 'Learn more';
},
function() { // Variation 4: Button Color
document.getElementById('button').className = 'button button-blue';
}
];
// Wait for the DOM to load, then execute the view for the chosen variation.
$(document).ready(
// Execute the chosen view
pageVariations[chosenVariation]
);
</script>
However, when I visit the page using an incognito window, I only see the first variation of the experiment. When I check chosenVariation in the console, it's always 0. In fact, when I call cxApi.chooseVariation(); in the console, it always returns 0.
Is this because google recognizes my incognito browser windows, or is something broken with cxApi.chooseVariation(); or in my implementation?
I had the same problem, 100% of the sessions were given the original (0) variation. In order to fix the problem, I added the javascript code provided by the experiment. Go to your experiment (edit), click Setting up your experiment code, manually insert the code, copy the code in there.
Now since you (and I) don't want to have a redirect, remove this part at the end of the code <script>utmx('url','A/B');</script>. If your page is templated, you can use a variable and insert your experiment key (not experiment id) where you see var k='########-#'
Now either very few people use the experiments in a client-only fashion or we're totally stupid because it would seem to me that the guide is wrong and there's absolutely no documentation that shows a working client-only setup.

Google Analytics file tracking

I'm using Google Analytics to track my pages, and I've added, last week, this code which I've found to try to track my PDF downloads, but this doesn't work :
Link to PDF :
<a href="pdf/my-pdf.pdf"
onClick="javascript:pageTracker._trackEvent('PDF','Download','My New PDF');
void(0);">
PDF
</a>
GA Tracking Code (minified) :
var _gaq=[['_setAccount','UA-XXXXXXXX-XX'],['_trackPageview']];
(function(d,t){var g=d.createElement(t),s=d.getElementsByTagName(t)[0];
g.src=('https:'==location.protocol?'//ssl':'//www')+'.google-analytics.com/ga.js';
s.parentNode.insertBefore(g,s)}(document,'script'));
Of course, I changed my UA Values for the same of this post.
How can I edit this to allow for file download tracking ?
Edit
PDF
function trackLink(e)
{
e.preventDefault();
_gaq.push(['_trackEvent','Download','PDF', e.target.href]);
window.setTimeout('location.href="'+e.target.href+'"',100);
return false;
}
var _gaq=[['_setAccount','UA-XXXXXXXX-XX'],['_trackPageview']];
(function(d,t){var g=d.createElement(t),s=d.getElementsByTagName(t)[0];
g.src=('https:'==location.protocol?'//ssl':'//www')+'.google-analytics.com/ga.js';
s.parentNode.insertBefore(g,s)}(document,'script'));
Note: XX's have been added for the purpose of the post and are not in the actual code.
Okay so a couple things here. Firstly, as gerl pointed out, you are using the wrong GA syntax for the version of the core code you have. So you need to fix your code according to that answer, regardless. But there is another issue to consider: timing.
First, more often than not, the GA code isn't going to have enough time to execute, before the browser redirects to the target URL. There are 2 ways you can get around this: force a timeout of ~100ms before redirect, or make your pdf open up in a separate tab/window.
Personally, I think the latter is a better solution. Since the pdf is loaded into a separate window, you don't need to worry about delaying the redirect to give GA a chance to execute. Also, most people prefer things like pdfs to open up in a separate tab/window, so that they aren't taken away from the page they are on. To do this, add a `target='_blank' to the link:
PDF
But if you really want to stick with having the pdf open in the same window/tab, then you will need to force a timeout. I don't like this option as much as the first, because what ~100ms is usually enough time to wait, it's not a guarantee that it's enough time. You can increase the timeout, but the more you do, the longer the visitor has to wait before the redirect occurs, which makes for a bad user experience. But this is one way you could do it:
PDF
<script type="text/javascript">
function trackLink(e) {
e.preventDefault();
_gaq.push(['_trackEvent','Download','PDF', e.target.href]);
window.setTimeout('location.href="'+e.target.href+'"',100);
return false;
}
var _gaq=[['_setAccount','UA-XXXXXXXX-XX'],['_trackPageview']];
(function(d,t){var g=d.createElement(t),s=d.getElementsByTagName(t)[0];
g.src=('https:'==location.protocol?'//ssl':'//www')+'.google-analytics.com/ga.js';
s.parentNode.insertBefore(g,s)}(document,'script'));
</script>
Also note that if you upgrade to universal analytics, that version has timeout/callback funcationality built in to link tracking (that article talks about outbound link tracking but the principle of using the callback function to do the redirect is the same).
You have pageTracker instead of _gaq.. Try this instead:
onclick="_gaq.push(['_trackEvent','Download','PDF', 'pdf/my-pdf.pdf']);"
Instead of writing a function, you can just add something into the html of the element... perhaps something like this?
<a href="pdf/my-pdf.pdf" onClick="_gaq.push(['_trackEvent', 'PDF','Download','My New PDF']);">
That ought to do it.
I had a similar problem with this sort of thing when trying to decide which type of GA code to use.
This question I posted might help (using ga vs. _gaq.push):
ga or _gaq.push for Google Analytics event tracking?
pdf
That should do the job! More info here: https://developers.google.com/analytics/devguides/collection/gajs/eventTrackerGuide
Also, you can always test if your event tracking is working by looking in Real Time Analytics.
See this link: https://support.google.com/analytics/answer/1136920?hl=en
It shows how to use the hitCallback to help with the issue of the browser redirecting before the event gets pushed.
I think this would be how to modify your code:
PDF
<script type="text/javascript">
function trackLink(e) {
e.preventDefault();
ga('send', 'event', 'Download', 'click', 'PDF', {'hitCallback':
function () {
document.location = e.target.href;
}
});
return false;
}
(function (i, s, o, g, r, a, m) {
i['GoogleAnalyticsObject'] = r; i[r] = i[r] || function () {
(i[r].q = i[r].q || []).push(arguments)
}, i[r].l = 1 * new Date(); a = s.createElement(o),
m = s.getElementsByTagName(o)[0]; a.async = 1; a.src = g; m.parentNode.insertBefore(a, m)
})(window, document, 'script', '//www.google-analytics.com/analytics.js', 'ga');
ga('create', 'UA-XXXXXXXX-X', 'auto');
ga('send', 'pageview');
</script>

How does google analytics track events when user navigates to other page inside one domain

In Google's documentation it is said that an event can be tracked in the following way:
<a onclick="_gaq.push(['_trackEvent', 'category', 'action', 'opt_label', opt_value]);">click me</a>
or older version:
<a onclick="pageTracker._trackEvent('category', 'action', 'opt_label', opt_value);">click me</a>
I was looking with Firebug to the request that are made when a click on a link and I see there aborted request:
http://www.google-analytics.com/__utm.gif?utmwv=4.7.2&utmn=907737223&....
This happens because browser unload all javascript when user navigates to a new page. How in this case event tracking is performed?
Edit:
Since one picture can be worth a thousand words...
When I click a link firebug shows me this sequence of requests (here are shown first four, after follows requests to fill page content)
The problem is that there isn't enough time for the script to finish running before the user is taken to the next page. What you can do is create a wrapper function for your GA code and in the onclick, call the wrapper function and after the GA code is triggered in your wrapper function, set a time out and update location.href with the link's url. Example:
click me
<script type='text/javascript'>
function wrapper_function(that,category,action,opt_label,opt_value) {
_gaq.push(['_trackEvent', category, action, opt_label, opt_value]);
window.setTimeout("window.location.href='" + that.href + "'", 1000);
}
</script>
code will vary a bit based on your link but hopefully you get the idea - basically it waits a little bit before taking the user to the target url to give the script some time to execute.
Update:
This answer was posted several years ago and quite a lot has happened since then, yet I continue to get feedback (and upvotes) occasionally, so I thought I'd update this answer with new info. This answer is still doable but if you are using Universal Analytics then there is a hitCallback function available. The hitCallback function is also available to their traditional _gaq (ga.js) but it's not officially documented.
This problem is answered in Google's documentation:
use
<script type="text/javascript">
function recordOutboundLink(link, category, action) {
try {
var myTracker=_gat._getTrackerByName();
_gaq.push(['myTracker._trackEvent', ' + category + ', ' + action + ']);
setTimeout('document.location = "' + link.href + '"', 100)
}catch(err){}
}
</script>
or
<script type="text/javascript">
function recordOutboundLink(link, category, action) {
try {
var pageTracker=_gat._getTracker("UA-XXXXX-X");
pageTracker._trackEvent(category, action);
setTimeout('document.location = "' + link.href + '"', 100)
}catch(err){}
}
</script>
This more or less the same as the answer from Crayon Violet, but has a nicer method name and is the official solution recommended by Google.
As above, this is due to the page being unloaded prior to the Async call returning. If you want to implement a small delay to allow gaq to sync, I would suggest the following:
First add a link and add an extra class or data attribute:
My Link
Then add into your Javascript:
$("a[data-track-exit]").on('click', function(e) {
e.preventDefault();
var thatEl = $(this);
thatEl.unbind(e.type, arguments.callee);
_gaq.push( [ "_trackEvent", action, e.type, 'label', 1 ] );
setTimeout(function() {
thatEl.trigger(event);
}, 200);
});
I don't really condone this behavior (e.g. if you are going to another page on your site, try to capture the data on that page), but it is a decent stop-gap. This can be extrapolated not just for click events, but also form submits and anything else that would also cause a page unload. Hope this helps!
I had the same issue. Try this one, it works for me. Looks like that ga doesnt like numbers as a label value. So, convert it to string.
trackEvent: function(category, action, opt_label, opt_value){
if(typeof opt_label === 'undefined') opt_label = '';
if(typeof opt_value === 'undefined') opt_value = 1;
_gaq.push([
'_trackEvent',
String(category),
String(action),
String(opt_label),
opt_value
]);
}

Load an iframe asynchronously

I have a webpage with an <iframe> pointing to another website. I don't want this to block the loading of the rest of the page. Is there a way to load it asyncrounously?
It shouldn't block. If you want the main page to fully load first (eg, main page's images before iframe content) then you'll have to use a bit of javascript to set the url of the iframe, like <body onload="javascript:...">
Using jQuery, this works:
<script type="text/javascript">
$(window).load(function() {
var f = document.createElement('iframe');
f.src = url;
f.width = 1000;
f.height = 500;
$('body').append(f);
});
</script>
where url is some URL.
One problem we had was that while iframes already do load asynchronously, the main page will not fire OnLoad until the iframe has finished loading too.
We worked around this by 'faking' OnLoad by calling the method we wanted in a script element at the bottom of the main page, even outside the closing body tag:
</body>
<script type='text/jscript' language='javascript'>
BodyOnready();
</script>
I think #Coxy is correct that the OnLoad won't fire. At least when running some web page performance tests it seemed to me it is waiting for the iframe to consider the page to be fully loaded. I therefore use this small jQuery snippet to load the iframe:
HTML:
<iframe id="blabla"></iframe>
JS:
$(window).load(function() {
if ($('#blabla').length <= 0) { return; } // to avoid errors in case the element doesn't exist on the page / removed.
$('#blabla').attr('src','//example.com/page');
});
iframes should load asynchronously without any effort on your part.
you can wait until after 'onload' has fired to set the iframe's src:
<body onload="loadFrame">
then something like this:
function loadFrame(){
var myFrame = document.getElementById('myFrame');
myFrame.src = "myURL";
};
Some vanilla JS alternative:
HTML:
<iframe id="YOURID" src="about:blank">Loading...</iframe>
JS:
window.onload = function(){
document.getElementById('YOURID').src = 'https://insertYourUrlHere.com'
};
Although I agree this shouldn't be happening, you could wait for your webpage to be completely loaded, and then load the iframe contents. With jQuery, I think you can do something like this:
Supposing your IFRAME looks like: <iframe name="theOtherPage"></iframe>
$(document).ready(function(){
(window.frames || document.frames)["theOtherPage"].window.location = "http://theotherpage.com/";
});

Resources