-
Notifications
You must be signed in to change notification settings - Fork 176
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Add reset and cleanup of dataLayer to prevent memory leaks #3475
Conversation
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thank you, @bjester, code changes are looking good to me. Overall, the approach looks similar to what I saw in https://www.voorhoede.nl/en/blog/your-website-probably-has-a-memory-leak/ where they were able to resolve their memory leaks by clearing elements references (they decided to go with a bit different method eventually but the point was the same). I can confirm that elements references are being cleared up.
One question about Google Tag Manager's reset
, do you expect it to clear the dataLayer
? I assumed it should happen, but documentation is minimal, and according to my browser console it doesn't seem to be the case. This is its output after I logged in and navigated to "Content Library" tab:
plugin.js:77 Analytics.trackEvent("channel_list", {"eventLabel":"PUBLIC","eventAction":"Click"})
:8080/en/channels/#/public:1 Autofocus processing was blocked because a document already has a focused element.
plugin.js:77 Analytics.trackEvent("Catalog search", {"eventAction":"","eventLabel":"{\"total\":1,\"matched\":[\"66a31fdbdd745c7c9e499206f3c4cced Published Channel\"]}","total":1,"matched":["66a31fdbdd745c7c9e499206f3c4cced Published Channel"]})
window.dataLayer
(8) [{…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, push: ƒ]0: {gtm.start: 1659525874116, event: 'gtm.js', gtm.uniqueEventId: 1}1: {pageCategory: 'Channel list', currentUser: {…}}2: {event: 'gtm.dom', gtm.uniqueEventId: 11}3: {event: 'gtm.load', gtm.uniqueEventId: 14}4: {event: 'gtm.click', gtm.element: null, gtm.elementClasses: 'v-tabs__item', gtm.elementId: '', gtm.elementTarget: '', …}5: {eventLabel: 'PUBLIC', eventAction: 'Click', event: 'channel_list', gtm.uniqueEventId: 56}6: {event: 'gtm.linkClick', gtm.element: null, gtm.elementClasses: 'v-tabs__item--active v-tabs__item v-tabs__item--active', gtm.elementId: '', gtm.elementTarget: '', …}7: {eventAction: '', eventLabel: '{"total":1,"matched":["66a31fdbdd745c7c9e499206f3c4cced Published Channel"]}', total: 1, matched: Array(1), event: 'Catalog search', …}8: ƒ ()push: ƒ ()length: 9[[Prototype]]: Array(0)
plugin.js:31 Analytics.reset()
window.dataLayer
(9) [{…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, ƒ, push: ƒ]0: {gtm.start: 1659525874116, event: 'gtm.js', gtm.uniqueEventId: 1}1: {pageCategory: 'Channel list', currentUser: {…}}2: {event: 'gtm.dom', gtm.uniqueEventId: 11}3: {event: 'gtm.load', gtm.uniqueEventId: 14}4: {event: 'gtm.click', gtm.element: null, gtm.elementClasses: 'v-tabs__item', gtm.elementId: '', gtm.elementTarget: '', …}5: {eventLabel: 'PUBLIC', eventAction: 'Click', event: 'channel_list', gtm.uniqueEventId: 56}6: {event: 'gtm.linkClick', gtm.element: null, gtm.elementClasses: 'v-tabs__item--active v-tabs__item v-tabs__item--active', gtm.elementId: '', gtm.elementTarget: '', …}7: {eventAction: '', eventLabel: '{"total":1,"matched":["66a31fdbdd745c7c9e499206f3c4cced Published Channel"]}', total: 1, matched: Array(1), event: 'Catalog search', …}8: ƒ ()push: ƒ ()length: 9[[Prototype]]: Array(0)
plugin.js:31 Analytics.reset()
window.dataLayer
(10) [{…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, ƒ, ƒ, push: ƒ]0: {gtm.start: 1659525874116, event: 'gtm.js', gtm.uniqueEventId: 1}1: {pageCategory: 'Channel list', currentUser: {…}}2: {event: 'gtm.dom', gtm.uniqueEventId: 11}3: {event: 'gtm.load', gtm.uniqueEventId: 14}4: {event: 'gtm.click', gtm.element: null, gtm.elementClasses: 'v-tabs__item', gtm.elementId: '', gtm.elementTarget: '', …}5: {eventLabel: 'PUBLIC', eventAction: 'Click', event: 'channel_list', gtm.uniqueEventId: 56}6: {event: 'gtm.linkClick', gtm.element: null, gtm.elementClasses: 'v-tabs__item--active v-tabs__item v-tabs__item--active', gtm.elementId: '', gtm.elementTarget: '', …}7: {eventAction: '', eventLabel: '{"total":1,"matched":["66a31fdbdd745c7c9e499206f3c4cced Published Channel"]}', total: 1, matched: Array(1), event: 'Catalog search', …}8: ƒ ()9: ƒ ()push: ƒ ()length: 10[[Prototype]]: Array(0)
plugin.js:31 Analytics.reset()
plugin.js:31 Analytics.reset()
plugin.js:31 Analytics.reset()
plugin.js:31 Analytics.reset()
plugin.js:31 Analytics.reset()
plugin.js:31 Analytics.reset()
plugin.js:31 Analytics.reset()
plugin.js:31 Analytics.reset()
plugin.js:31 Analytics.reset()
plugin.js:31 Analytics.reset()
plugin.js:31 Analytics.reset()
plugin.js:31 Analytics.reset()
plugin.js:31 Analytics.reset()
plugin.js:31 Analytics.reset()
plugin.js:31 Analytics.reset()
plugin.js:31 Analytics.reset()
window.dataLayer
(26) [{…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, ƒ, ƒ, ƒ, ƒ, ƒ, ƒ, ƒ, ƒ, ƒ, ƒ, ƒ, ƒ, ƒ, ƒ, ƒ, ƒ, ƒ, ƒ, push: ƒ]0: {gtm.start: 1659525874116, event: 'gtm.js', gtm.uniqueEventId: 1}1: {pageCategory: 'Channel list', currentUser: {…}}2: {event: 'gtm.dom', gtm.uniqueEventId: 11}3: {event: 'gtm.load', gtm.uniqueEventId: 14}4: {event: 'gtm.click', gtm.element: null, gtm.elementClasses: 'v-tabs__item', gtm.elementId: '', gtm.elementTarget: '', …}5: {eventLabel: 'PUBLIC', eventAction: 'Click', event: 'channel_list', gtm.uniqueEventId: 56}6: {event: 'gtm.linkClick', gtm.element: null, gtm.elementClasses: 'v-tabs__item--active v-tabs__item v-tabs__item--active', gtm.elementId: '', gtm.elementTarget: '', …}7: {eventAction: '', eventLabel: '{"total":1,"matched":["66a31fdbdd745c7c9e499206f3c4cced Published Channel"]}', total: 1, matched: Array(1), event: 'Catalog search', …}8: ƒ ()9: ƒ ()10: ƒ ()11: ƒ ()12: ƒ ()13: ƒ ()14: ƒ ()15: ƒ ()16: ƒ ()17: ƒ ()18: ƒ ()19: ƒ ()20: ƒ ()21: ƒ ()22: ƒ ()23: ƒ ()24: ƒ ()25: ƒ ()push: ƒ ()length: 26[[Prototype]]: Array(0)
plugin.js:31 Analytics.reset()
Also attaching a screenshot where you can see the final dataLayer
's content better
Notice that dataLayer
keeps growing even though as a user I didn't do any action. It seems that
- It isn't actually reset
- It's getting bigger after each analytics reset as we push the reset function to the array
I tried to google a bit and played around with code but haven't figured out yet what's going on. I agree that ideally, we'd call it but if it doesn't seem to work (and again, I'm not sure what to expect actually, but growing the array even more seems unexpected and potentially problematic), maybe we could try only clearing up the elements' references (that was also the only thing they needed to do in the article I referenced above). Have you seen this? Any thoughts?
@MisRob Sorry I didn't make it clear in my PR description. I experienced the same thing-- I did confirm that what I've done is calling it correctly. The documentation doesn't quite describe that it will empty the the |
Thank you for your clarification. Sounds good. The documentation is really opaque in that sense, so I think it's fine to give it a try if it was intentional. Just a bit concerned over the 30s frequency - the array will grow pretty fast, and it's not very clear to me if all those functions ever get cleared. Do you think it's safe? |
Maybe we could give it a try by leaving the Studio open for half a day or so and see what happens? |
I saw a note somewhere that it should get cleared automatically after couple hundred items are there but if I recall it wasn't from the official documentation, so not sure what to expect. |
That's a good point. Perhaps we should try to clear the old reset functions too. I could also increase the interval to a couple of minutes? What do you think? |
I also saw something that mentioned that there's a cap at 300 items. Perhaps they added that and didn't update the documentation regarding |
Make sense to me, or we could push reset on router navigation, for example. That way, it wouldn't need to run when the page is just open with no new interactions. I think you have better insight into what events we track, so whatever makes more sense to you.
I saw the same number. However, I let the Studio run today for a longer time to watch its behavior and it's not the case. The number could be different, or it never gets cleared. So I think it'd be better to be careful here. |
Summary
Description of the change(s) you made
dataLayer.reset()
according to official documentationgtm.element
sincedataLayer.reset()
doesn't seem to affect it, but should be safe as long as it occurs in a function queued onto the dataLayerManual verification steps performed
References
Fixes #3428
Comments
Again,
dataLayer.reset()
didn't do the trick, so I added a little bit extraContributor's Checklist
PR process:
CHANGELOG
label been added to this PR. Note: items with this label will be added to the CHANGELOG at a later timedocs
label has been added if this introduces a change that needs to be updated in the user docs?requirements.txt
files also included in this PRStudio-specifc:
notranslate
class been added to elements that shouldn't be translated by Google Chrome's automatic translation feature (e.g. icons, user-generated text)pages
,components
, andlayouts
directories as described in the docsTesting:
Reviewer's Checklist
This section is for reviewers to fill out.
yarn
andpip
)