Skip to content

mousemove event listener is being attached in setup_preload even if I am not using data-sveltekit-preload-[x]="hover" #12664

@kran6a

Description

@kran6a

Describe the bug

It can be seen here that the listener is attached inconditionally whenever the setup_preload function is called

function setup_preload() {
/** @type {NodeJS.Timeout} */
let mousemove_timeout;
container.addEventListener('mousemove', (event) => {
const target = /** @type {Element} */ (event.target);
clearTimeout(mousemove_timeout);
mousemove_timeout = setTimeout(() => {
preload(target, 2);
}, 20);
});

The functions is always called unless navigator.connection.saveData is true

While the annoyance is minor, its effects are perceptible as I found it because moving the mouse on sveltekit sites induce static noise in my loudspeakers and in my wired headphones, a sound I already relate with a cry for help from the event loop as it is also induced by other common but bad JS practices that clog the event loop with very short but periodic tasks like driving (usually clunky) animations by using setTimeout(fn, 10).

This is a devtool recording of ~3s of moving my mouse over the website. There is no JS activity on that page other than that generated by the mousemove event listener.
image

While I don't think this is the most important thing in the world to change I don't think inconditionally attaching an event listener that serves no purpose if you don't use the feature it is meant for and causes subtle but visible audible side-effects on a page whose only JS is the routing/preloading code is the right thing to do, specially on a framework using Svelte, which is usually picked because it has the "you don't pay for what you don't use" philosophy of most compilers.

Personally I would like a way to opt-out of this behavior by being able to specify which ways of preloading can be used within the app and defaulting to all of them.

Another option for those who want to preload on hover but do not want to attach a global mousemove event would be being able to choose different strategies at compile time for data-sveltekit-preload-[x]="hover". An alternative stategy would be attaching listeners to the elements with the data-sveltekit-preload-[x]="hover" attribute themselves. Maybe using requestIdleCallback() (unsupported by Safari) can be helpful with performance so that other JS is not slowned down if there are lots of element to attach to. This way you can even use self-removing mouseenter listeners if the data-sveltekit-preload-[x]="hover" is on the link itself.

Reproduction

https://kit.svelte.dev (happens on any svelte-kit website unless csr is disabled)

Logs

No response

System Info

Not important

Severity

annoyance

Additional Information

No response

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels
    No fields configured for Feature.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions