You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
These calculations are because of vue-router dynamic routes (routes can have params), and will likely to map all routes to find a matching one 6 times at least in production (even more in dev for devtools)
While all the links are rendered by router-link in pages, and all internal links in navbar and sitebar all based on router-link, which means we probably have a lot of router-link initialized or recalculated when opening and switching pages.
The are also 3 things to get even worse.
The first thing is that vue-router is not efficiency designed for large amount of routes. Usually people should use dynamic routes when rendering lots of contents from database, so VueRouter won't need to map a looooong routes array to find a matching route. But in VuePress, all routes are static, and to provide redirects for /a/b and /a/b.md to /a/b.html, we are writing 3 routes for one page into vue-router.
The second one is #1290. With this issue, when scrolling pages, plugin-active-hash will trigger the whole route object to update (including hashpathfullPathparams and others. So every router-link is recalculated to update state, with 18N (3 for similar routes of 1 page and 6 for use link) maps of all routes object. So on mobile devices, frames may lose when scrolling and people will feel stuck.
We are not using <router-view>, instead we are loading and mounting the page async on router.beforeResolve. This means the page is changed BEFORE route. Path is updated, so when rendering new page(and mounting its components), old route data is used and then a new route data needs to be recalculated at ones. We are supposed to focusing rerendering page layout components as fast as possible, while we did twice job here.
See https://docs.innenu.com/ as a reproduction, this website has NO additional components in page (plain HTML generated from markdown), while it has 1274 pages and nearly 4000 routes.
The MDLink and VPLink do little work comparing with the original <router-link>, and if more aggressively, if we think that using the original link as anchor href is ok (at least I think so), we can even render the component with no cost:
Since we are using single instance and trigger route path change and "await" the application render job done to do SSG work, this can also speed up SSG process greatly
The text was updated successfully, but these errors were encountered:
With 6x slowdown, the expensive job of router.resolve can be easily seen. So though for small sites route meta is ok, for large sites, we may still need to avoid getting information from router as the behavior is mapping array.
@meteorlxy With #1360#1353#1357#1361, performance on my theme docs (304 pages) has up to 500% on scrolling with hash changes and 70% in switching pages
Clear and concise description of the problem
Currently vue-router has serious performance impact on sites with more than 500 pages.
See vue-router source code here: https://github.com/vuejs/router/blob/main/packages/router/src/RouterLink.ts
Each router-link called
useLink
inside it:https://github.com/vuejs/router/blob/941b2131e80550009e5221d4db9f366b1fea3fd5/packages/router/src/RouterLink.ts#L211
And in
useLink
heavy calculations are running based on routes object athttps://github.com/vuejs/router/blob/941b2131e80550009e5221d4db9f366b1fea3fd5/packages/router/src/RouterLink.ts#L98-L138
just to solve the
isActive
andisExactActive
.These calculations are because of vue-router dynamic routes (routes can have params), and will likely to map all routes to find a matching one 6 times at least in production (even more in dev for devtools)
While all the links are rendered by router-link in pages, and all internal links in navbar and sitebar all based on router-link, which means we probably have a lot of router-link initialized or recalculated when opening and switching pages.
The are also 3 things to get even worse.
The first thing is that vue-router is not efficiency designed for large amount of routes. Usually people should use dynamic routes when rendering lots of contents from database, so VueRouter won't need to map a looooong routes array to find a matching route. But in VuePress, all routes are static, and to provide redirects for
/a/b
and/a/b.md
to/a/b.html
, we are writing 3 routes for one page into vue-router.The second one is #1290. With this issue, when scrolling pages,
plugin-active-hash
will trigger the wholeroute
object to update (includinghash
path
fullPath
params
and others. So every router-link is recalculated to update state, with 18N (3 for similar routes of 1 page and 6 for use link) maps of all routes object. So on mobile devices, frames may lose when scrolling and people will feel stuck.The third thing is the worse one: #1249
We are not using
<router-view>
, instead we are loading and mounting the page async onrouter.beforeResolve
. This means the page is changed BEFORE route. Path is updated, so when rendering new page(and mounting its components), old route data is used and then a new route data needs to be recalculated at ones. We are supposed to focusing rerendering page layout components as fast as possible, while we did twice job here.See https://docs.innenu.com/ as a reproduction, this website has NO additional components in page (plain HTML generated from markdown), while it has 1274 pages and nearly 4000 routes.
Suggested solution
<router-link
, for static paths, all we need is to resolve the string link withrouter. resolve(link)
and compareresolveRoute.path
withcurrentRoute.path
, only 1 mapping of routes should be done while callingrouter. Resolve
,https://github.com/vuejs/router/blob/941b2131e80550009e5221d4db9f366b1fea3fd5/packages/router/src/RouterLink.ts#L98-L138
The above lines are not needed, so we should provide a
<VPLink>
in@vuepress/client
and encourage to use this link when developing themes and plugins.Also we should use a simple link with NO active state to render markdown anchor links:
The MDLink and VPLink do little work comparing with the original
<router-link>
, and if more aggressively, if we think that using the original link as anchor href is ok (at least I think so), we can even render the component with no cost:Alternative
No response
Additional context
The text was updated successfully, but these errors were encountered: