Skip to content

Ability to disable reactivity to improve performance on destroy - On 2.6.*  #3808

Closed as not planned
@bryarb

Description

@bryarb

What problem does this feature solve?

Destroying N RouterLink at once has a cost of O((N^2)/2) due to all RouterLink depend on the singleton reactive property $route. When removing hundreds or thousands of links from the page, this cost is noticeable, especially on slow devices. The goal is a cost of O(N).

Hundreds or thousands of links might seem too much, but sure there might be some cases where it makes sense, like an infinite scroll or some big grids. In many cases vue-virtual-scroller should solve the general problem, but I think it would be better not to require it as a rule.

Removing the dependency on $route means effectively disabling reactivity for the RouterLink and thus all the related features. At this moment, I think the only affected features are the CSS classes to show a link is active.

Why this cost?

The singleton _route is created for the _routerRoot once. At this moment, Vue instantiates a Dep to track writes and reads on this attribute.

Each time a RouterLink is created, its render Watcher detects the $route is accessed, so that the Watcher adds the Dep to its dependencies (Watcher.deps) and the Dep adds the Watcher to its subscribers (Dep.subs). This means the Dep.subs for _route is, at least, as large as the number of rendered RouterLinks.

When the $route changes, all the RouterLink are updated because they are on the Dep.subs.

When destroying all the RouterLink (page change), all the components teardown their watchers, and each watcher have to remove itself from the Dep.subs. Removing a single RouterLink's Watcher from the Dep.subs costs O(N - i), where N is the number of RouterLink and i the number of RouterLink already removed.

Generally speaking, the cost of removing N RouterLinks at once is O((N^2)/2).

What does the proposed API look like?

Adding a no-reactive prop on RouterLink should be enough.

The meaning of this prop is effectively disabling reactivity on the current route to improve the overall performance, especially when destroying many RouterLink at once.

As a side effect, this flag turns off any feature that depends on the current route. At this moment, I think the only affected features are related to the CSS classes to show if a link is active or not.

ORIGINAL LINK: #3500 (comment)

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