Skip to content

turbo:load fires very late when Turbo is loaded with defer (misses interactive state) #1492

@amohamed97

Description

@amohamed97

When Turbo is loaded using defer, the turbo:load event can fire very late (close to window.onload) because Turbo only triggers it in response to readystatechange transitions.
If Turbo initializes after the document has already reached readyState = "interactive", it misses that transition and waits until "complete" instead.

This causes JS that depends on turbo:load to be delayed until all deferred/async scripts finish loading, which can block page interactivity.


Why this matters

We migrated from Turbolinks → Turbo, and this regression started appearing after the migration.

  • turbolinks:load fired on DOMContentLoaded
  • It worked reliably even when Turbolinks itself was deferred
  • With Turbo, deferring the script can unintentionally tie turbo:load to readyState = "complete" / window.onload

In real production cases, this has caused:

  • Frozen or non-interactive UI
  • Navigation blocked for users

Root cause (as I understand it)

Turbo triggers turbo:load only when it observes readystatechange changes (interactive or complete).
It does not check the current document.readyState when initializing.

So if Turbo loads after interactive, it will always wait for complete.


Questions

  1. Is this behavior intentional / expected when Turbo is deferred?
  2. Is Turbo expected to work correctly when loaded using defer, or is synchronous loading assumed?
  3. Is there a recommended event for “DOM ready + Turbo-safe initialization” that doesn’t depend on readyState = "complete"?
  4. Would it make sense for Turbo to trigger turbo:load immediately if document.readyState is already "interactive"?

Thanks for the great work on Turbo 🙏

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions