Skip to content
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

feat: Add new rule to guarantee events are tracked as passive #1689

Merged
merged 8 commits into from
Jan 29, 2025

Conversation

rafaeelaudibert
Copy link
Member

We'll never call preventDefault on our events and, for that reason, it's smarter to tag our events as passive: true letting the browser know that it can continue processing the event, it doesn't need to wait for us.

This should improve performance on lower-end devices.

I've released this for scroll events which are more critical - called hundreds of times a second - and I'm monitoring to see if we'll decrease event ingestion count or not. If I don't see a decrease, I'll ship this as well :)

We'll never call `preventDefault` on our events and, for that reason, it's smarter to tag our events as `passive: true` letting the browser know that it can continue processing the event, it doesn't need to wait for us.

This should improve performance on lower-end devices.
@rafaeelaudibert rafaeelaudibert added the bump patch Bump patch version when this PR gets merged label Jan 24, 2025
@rafaeelaudibert rafaeelaudibert requested a review from a team January 24, 2025 19:40
Copy link

vercel bot commented Jan 24, 2025

The latest updates on your projects. Learn more about Vercel for Git ↗︎

Name Status Preview Updated (UTC)
posthog-js ✅ Ready (Inspect) Visit Preview Jan 27, 2025 5:14pm

Copy link

github-actions bot commented Jan 24, 2025

Size Change: -6.39 kB (-0.19%)

Total Size: 3.27 MB

Filename Size Change
dist/all-external-dependencies.js 209 kB +17 B (+0.01%)
dist/array.full.es5.js 265 kB -654 B (-0.25%)
dist/array.full.js 370 kB -729 B (-0.2%)
dist/array.full.no-external.js 369 kB -729 B (-0.2%)
dist/array.js 181 kB -611 B (-0.34%)
dist/array.no-external.js 180 kB -611 B (-0.34%)
dist/dead-clicks-autocapture.js 14.5 kB +67 B (+0.47%)
dist/main.js 182 kB -611 B (-0.33%)
dist/module.full.js 370 kB -729 B (-0.2%)
dist/module.full.no-external.js 369 kB -729 B (-0.2%)
dist/module.js 181 kB -611 B (-0.34%)
dist/module.no-external.js 180 kB -611 B (-0.34%)
dist/surveys-preview.js 67.6 kB +89 B (+0.13%)
dist/surveys.js 64.2 kB +61 B (+0.1%)
ℹ️ View Unchanged
Filename Size
dist/customizations.full.js 13.8 kB
dist/exception-autocapture.js 9.48 kB
dist/external-scripts-loader.js 2.64 kB
dist/recorder-v2.js 117 kB
dist/recorder.js 117 kB
dist/tracing-headers.js 1.76 kB
dist/web-vitals.js 10.4 kB

compressed-size-action

Copy link
Member

@robbie-c robbie-c left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM!

Is the bundle size smaller if you make a { passive: true} object somewhere and import it?

//
})
},
{ passive: true }
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

can i be precious and we not change this... changes in here can really break customers' sites so i change it very carefully 🙈

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ah good catch

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm happy not to change it here, I agree this is the finickiest :)

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

yep, just needs way more careful testing
i'm being too cautious but the last time we broke this was very painful 🙈

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

so, best to avoid entirely :)

It's slightly more performant to have these in our events, see previous commit for rationale
@@ -236,7 +236,7 @@ export const registerEvent = (function () {
}

if (element.addEventListener && !oldSchool) {
element.addEventListener(type, handler, !!useCapture)
element.addEventListener(type, handler, { capture: !!useCapture, passive: true })
} else {
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

So, I was trying to understand what this function is for, and it's intended to support extremely old browsers. If you check https://caniuse.com/?search=addEventListener you'll see this is only ever useful for IE 6-8 which we supposedly don't support

"browserslist": [
    "> 0.5%, last 2 versions, Firefox ESR, not dead, IE 11"
]

Of course, we have the oldSchool flag which triggers this code for window.load when trying to initialize posthog-js. https://github.com/PostHog/posthog-js/blob/make-all-event-listeners-passive/src/posthog-core.ts#L2315-L2318

That's only triggered, however, if document.addEventListener doesn't exist which, again, is only if you're running IE6-8. Anything against removing this code?

I'll instead replace it with a generic addEventListener function intended to avoid having to repeat passive: true everywhere and reduce our bundle size slightly.

@pauldambra @robbie-c

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nope... that's super early code for sure...

we should check the ES5 bundle still works but hopefully CI just covers that.

This is ancient code, and it's only ever used for IE6-8 - which we don't support.

```
"browserslist": [
    "> 0.5%, last 2 versions, Firefox ESR, not dead, IE 11"
]
```

Of course, we have the oldSchool flag which triggers this code for window.load when trying to initialize posthog-js. make-all-event-listeners-passive/src/posthog-core.ts#L2315-L2318

That's only triggered, however, if document.addEventListener doesn't exist which, again, is only if you're running IE6-8.

I'll instead replace it with a generic addEventListener function intended to avoid having to repeat passive: true everywhere and reduce our bundle size slightly.
This helper is intended to save us some bytes by avoiding having to repeat `passive: true` everywhere
Comment on lines +40 to +44
// Add import if needed (note: this is a basic implementation, it won't always work)
const importFix = fixer.insertTextBefore(
context.getSourceCode().ast,
"import { addEventListener } from './utils'\n"
)
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Wondering if this makes any sense. Most often than not it'll be correct, but it will be a broken import sometimes

Maybe we shouldn't be autofixing this at all?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

yeah, I'd leave the fix (if we can't detect the correct path). most folks' editors should be able to create the import on demand anyway

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'll see if eslint allows me to detect what file I'm in, if so, I'll keep it

@rafaeelaudibert
Copy link
Member Author

@robbie-c @pauldambra Added a couple of new commits to reduce bundle size, and saved some bytes everywhere - even compared to before!

Copy link
Member

@robbie-c robbie-c left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What @pauldambra said about the ES5 bundle still working for people. Do you still have your IE11 setup? Can you make sure that we're still tracking scrolls correctly?

(I'm 99% confident we will be, just... you know.. changes with a large impact if something goes wrong)

Copy link
Member

@pauldambra pauldambra left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

yep, running locally I still see heatmaps and scrolls and things being captured

CI is green 👍

@rafaeelaudibert
Copy link
Member Author

@pauldambra's tests are reassuring, and scroll still works on my IE11 from the change last week, I'll try the changes here locally, let's hope my IE11 installation is trustworthy

@rafaeelaudibert
Copy link
Member Author

Hmm, I can't run the demo NextJS app on IE11 because it uses react-refresh and that doesn't support IE11. Trying something else, testing IE11 sucks

@rafaeelaudibert
Copy link
Member Author

Ok, found a way, e1e109f (#1689), but it's hacky, it does work, though! 🎉

@rafaeelaudibert
Copy link
Member Author

Will be merging this tomorrow morning, more time to monitor before I leave for the day

@rafaeelaudibert rafaeelaudibert merged commit 2c3eb70 into main Jan 29, 2025
28 checks passed
@rafaeelaudibert rafaeelaudibert deleted the make-all-event-listeners-passive branch January 29, 2025 12:43
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bump patch Bump patch version when this PR gets merged
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants