How is Google analytics gtag supposed to work in a SPA?
Asked Answered
T

2

7

From what I can tell, how google recommends to set up gtag, it's a function that is always pushing more variables onto an array:

window.dataLayer = window.dataLayer || [];
function gtag(){dataLayer.push(arguments);}

Following the docs on how to use it in a SPA, it seems I'm actually creating a memory leak.

gtag('config', 'GA_TRACKING_ID', {'page_path': '/new-page.html'});
console.log('window.dataLayer', window.dataLayer);

My console shows that every time I navigate to a new page the window.dataLayer array gets larger.

I'm assuming there's something I'm not understanding, because I doubt that Google wants me to create a memory leak in my app, but I'm stumped now.

Turfy answered 7/7, 2018 at 1:35 Comment(0)
M
5

The size of the dataLayer is capped at 300 (FIFO style) currently.

That's not currently documented and likely to change in the future. But the limit is there exactly to avoid blowing up memory in case repeated events happen inside the same page.

Mayflower answered 10/7, 2018 at 1:36 Comment(3)
Ok, thanks, interesting. How come I don't see the array being cleared out even though I have the script loaded from googletagmanager.com/gtag/js (I assume it should be cleared as soon as the data gets sent to google)? And what happens if the google script fails to load or doesn't work for some reason. Then this array will grow until the page potentially crashes?Turfy
The design of dataLayer is to keep all mutations if possible. Right now it doesn't seem to make much sense but gtag is a recent tag addition and that design will come handy in the future. Yes if the Google tag doesn't load this array will grow, it's unlikely to get big enough as to break your page but I guess it's possible depending on how many hits a user can fire without leaving a page. You can trim it manually if you want to avoid this.Mayflower
I see that it does indeed max out at 300 items. Thanks.Turfy
P
0

I do not know thoroughly but I assume this is just a normal array initialized before gtag is loaded. If the sole concern is to prevent this array from getting larger, then can't we create an array that prevents itself from getting larger than a set limit? Something like this?:

function createDL(limit){
    var dL = [],//the array
        iCounts = [];//the log of arg. length every time push is called
    dL.push = function(){
        if(this.length >= limit) {
            return (
                !!iCounts[1] 
                && 
                (
                    this.splice(iCounts[0],iCounts[1]),
                    iCounts.splice(1,1),
                    this.push.apply(this,arguments)
                )
            );
        }
        this.constructor.prototype.push.apply(this,arguments);
        iCounts.push(arguments.length);
        return this;
    }
    return dL;
}

Usage:

window.dataLayer = dataLayer || createDL(5);
dataLayer.push(1,2,3);//1,2,3
dataLayer.push(4,5);//1,2,3,4,5
dataLayer.push(6);//1,2,3,6
dataLayer.push(8,9,10,11);//1,2,3,6,8,9,10,11
dataLayer.push("aaa");//1,2,3,"aaa"

I did not touch the first things pushed to dataLayer since they contain the "config" directive and some optional arguments. If the first things pushed to array are larger than the limit, obviously it will always return false and you can't push any longer.

In your case a limit would be 300.

Or am I missing something?

Preeminence answered 16/7, 2018 at 15:1 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.