Skip to content

Proposal: asynchronous event listeners #1308

Open
@domfarolino

Description

@domfarolino

What is the issue with the DOM Standard?

I've heard chatterings in a few different places about interest in asynchronous event listeners on the platform, so I figured I'd file a bug here for some more centralized discussion. The problem: When some action happens on the web platform that results in firing events, all event listeners for that event are immediately, right then & there on the spot, without regard to the priority of the listener relative to surrounding tasks. It's entirely possible that developers wish to know about/respond to some events at a much lower priority than other competing tasks at around the same time. Currently there is no way to signal to the platform, that an event listener should be invoked asynchronously after the platform would ordinarily do so, saving the event listener's invocation for a less-busy/contentious time, in terms of task scheduling and execution.

Enabling this would let developers extend their existing task scheduling / prioritization logic to their event listeners as well. Something very rough along these lines can already be done today:

button.addEventListener('click', e => {
  if (mustDefer) {
    setTimeout(realClickHandler, kTimeout);
    // or…
    requestAnimationFrame(realClickHandler);
  }
});

…but it's pretty limited. First, it still involves immediately invoking user script in response to the event, so we don't actually avoid a big part of that cost. The fact that the queueing / deferral logic is handled immediately in userland is a missed performance opportunity — perhaps a large one? Second, it's not all that ergonomic, and is perhaps harder to schedule the readClickHandler relative to other userland tasks that follow a certain scheduling dynamic.

I wonder if there is an opportunity to integrate the Prioritized Task Scheduling API here. One option would be doing something as simple as passing in a task priority to addEventListener():

button.addEventListener('click', e => {
    // Do real stuff asynchronously…
    // e.preventDefault() does not work here❗
}, {priority: "user-visible"});

Related discussion: WICG/observable#74.

@chrishtr @mmocny @shaseley @mfreed7

Metadata

Metadata

Assignees

No one assigned

    Labels

    needs concrete proposalMoving the issue forward requires someone to figure out a detailed planneeds implementer interestMoving the issue forward requires implementers to express interesttopic: events

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions