Skip to content

Commit

Permalink
fix: don't make wheel events passive by default (#13322)
Browse files Browse the repository at this point in the history
This was done previously to align with browser behavior, but the browser behavior actually only makes them passive on window/document/body. Since wheel events are not delegated, we can revert their passive-by-default setting. Closes #13318

For touchstart/touchmove we're not changing it because these events are delegated, which means they happen a lot more often on a target higher up the tree, which may cause jank.
  • Loading branch information
dummdidumm authored Sep 19, 2024
1 parent 0ef14b5 commit 5dbe763
Show file tree
Hide file tree
Showing 3 changed files with 16 additions and 2 deletions.
5 changes: 5 additions & 0 deletions .changeset/new-baboons-fetch.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
'svelte': patch
---

fix: don't make wheel events passive by default
2 changes: 1 addition & 1 deletion documentation/docs/02-template-syntax/02-basic-markup.md
Original file line number Diff line number Diff line change
Expand Up @@ -112,7 +112,7 @@ Because events are just attributes, the same rules as for attributes apply:

Timing-wise, event attributes always fire after events from bindings (e.g. `oninput` always fires after an update to `bind:value`). Under the hood, some event handlers are attached directly with `addEventListener`, while others are _delegated_.

When using `onwheel`, `onmousewheel`, `ontouchstart` and `ontouchmove` event attributes, the handlers are [passive](https://developer.mozilla.org/en-US/docs/Web/API/EventTarget/addEventListener#using_passive_listeners) to align with browser defaults. This greatly improves responsiveness by allowing the browser to scroll the document immediately, rather than waiting to see if the event handler calls `event.preventDefault()`.
When using `ontouchstart` and `ontouchmove` event attributes, the handlers are [passive](https://developer.mozilla.org/en-US/docs/Web/API/EventTarget/addEventListener#using_passive_listeners) for better performance. This greatly improves responsiveness by allowing the browser to scroll the document immediately, rather than waiting to see if the event handler calls `event.preventDefault()`.

In the very rare cases that you need to prevent these event defaults, you should use [`on`](https://svelte-5-preview.vercel.app/docs/imports#svelte-events) instead (for example inside an action).

Expand Down
11 changes: 10 additions & 1 deletion packages/svelte/src/utils.js
Original file line number Diff line number Diff line change
Expand Up @@ -222,7 +222,16 @@ export function is_dom_property(name) {
return DOM_PROPERTIES.includes(name);
}

const PASSIVE_EVENTS = ['wheel', 'mousewheel', 'touchstart', 'touchmove'];
/**
* Subset of delegated events which should be passive by default.
* These two are already passive via browser defaults on window, document and body.
* But since
* - we're delegating them
* - they happen often
* - they apply to mobile which is generally less performant
* we're marking them as passive by default for other elements, too.
*/
const PASSIVE_EVENTS = ['touchstart', 'touchmove'];

/**
* Returns `true` if `name` is a passive event
Expand Down

0 comments on commit 5dbe763

Please sign in to comment.