Deciphering User Engagement Measurement in Google Analytics 4
One of the most notorius changes in Google Analytics 4 was the removal of the Bounce Rate
Metric in benefit of the Engaged Sessions
/ Engagement Time
. ( yes, I know they ended bringing it back with some slight differences ).
First one will define if the current session has been engaged by the user, second one defined the “amount” of engagement involved with the visit. The combination of these 2 metrics will provide a better view of users behaviour in our site, rather than checking a simple “did they bounce” boolean parameter without any further context.
Engaged Session
Google Analytics 4 will consider ( and accordingly mark ) a session as engaged , is any of the following conditions are met:
- The session last longer than 10 seconds (this can be configured)
- The session has at least 1 conversion event
- The session has at least 2 or more
page_view
orscreen_view
Then the engagement rate will report the percentage of sessions that meaningfully interacted with your site, based on the condition listed above.
In the other side the “Bounce Rate
” will report the sessions where there was not engagement.
The session engagment is reported back to GA4
using a shared payload key (ie: it’s shared accross all the events in the current hit ).
Engagement Time Metric
The way the engagement time is track may confuse the people, despite it may include a lot of rules inside, it ends being pretty simple, Google Analytics will only count the time the user is really “engaged” (huh!) with your site, and for deciding this there are 3 page state that needs to be enabled.
- Page MUST be visible
- Page MUST be active
- Page MUST have the Focus
If you’re not a developer this may be easy to understand, let me try to explain.
The current document (page) has to visible, if for some reason the current page document is not visibile on for the users, no time will be counted. This is detected using the visibilitychange API
and checking for the document.hidden
value.
Also the current page needs to be active, this is measured using the pageshow
and pagehide
events. If you don’t know that this means, let’s say that we have a SPA page we press the Back button
the counter will be stoped on the pagehide and will start counting again whe the page is shown.
Lastly, the current window needs to have the focus. Let’s say that you’re using my Analytics Debugger Extension, the time you’re interacting with the extension the focus it’s on the extension, not on the page. Google Analytics 4
will stop the counter and that time won’t be counted.
In any case some of these rules my not work all the times because of the different browser behaviors, race conditions, so it uses some more signals to enable or disable the counter, for example checking if the document.hasFocus
is true, or starting the counter of each gtag event push as long as the event name is not a get call ( "gtag.get"
)
The user_engagement
event
There’s some extra point to have in mind about how Google Analytics 4
measures the engagement time. Each time that we click on any self-domain link, or any of the domains configured on the linker. the user_engagement
is fired. (There may some more conditions to be meet, or some extra conditions that may trigger it at some point)
The main reason for this auto-fired event to exist seems to be measuring the current time on page, that’s why it gets fired just before user leaves the current page. And this will trigger if there’re no other events pending on the queue (I think, need to test this deeply), for example if you have an click event at some point, that even will hold the engagement time
, so this even will not be needed.
You’ll likely need to check the “preserve log” check to see these hits ( which are also available on Big Query ), and that which basically hold the engagement time value (&et
) . You may see these hits showing an unknown status on the network tab, nothing to worry about. All hits on GA4
are sent using the sendBeacon API
, which basically means that they are fired and the browser doesn’t wait for any responde from the receiving endpoint. Since
Are these Metrics Reliable
I was chatting with @CharlesFarina about this, and related to the reliability of the engagment time it came to my head that there were some studies mentioning some issues with he sendBeacon usage.
The people of Volument, found some 40% discrepancies while using sendBeacon
along with the unbeforeUnload event here: https://volument.com/blog/sendbeacon-is-broken . According to MDN documentation should be use along with the visibilitychange
( I didn’t check on which one GA4 triggers the data, since no events are fired on my visibilities changes, we may guess to be fired on the pagehide, or page unload … ) . In any case, this study was ran 2 years ago, so as today we should expect this gap not to be as big.
Still even if this event is not finally tracked some times, it really helps on adding even some more value to the engagement time
metric on Google Analytics 4.
Working demonstration Gif:
And that basically how it works, I may be missing some smalls details and rules, but it’s not the point of the post to replicate the funcionality , but providing some details so we know why some events don’t attach the event engagement_time ( &_et
) value, or why sometimes event if we spent more than 10 seconds the session has not been marked as engaged
.
One thing that I may be missing is having the option to set an event as a “non-interactional“, as we used to have on the old analytics, but rather that non spawning a session this would just skip passing the engagement_time to the current event, which may be useful for people tracking some backend or automatic event without any use interactions.