Skip to content

Commit 400065c

Browse files
Sheraffautofix-ci[bot]
authored andcommitted
refactor(router-core): scroll-restoration minor performance cleanup (#4990)
Some minor performance improvements in `scroll-restoration.ts` - in `getCssSelector`: - we can obtain `indexOf` without creating an empty array through `Array.prototype.indexOf` - using `.unshift` in a loop is always bad for performance. To build arrays in reverse, use `.push()` in the loop, and `.reverse()` at the end. - in `restoreScroll`: - we can early exit without creating an IIFE by using a [labeled statement](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/label) - we can avoid creating an array of elements to iterate over since we already have an array - in `onScroll`: - we can avoid accessing the same key twice by using the `||=` operator <!-- This is an auto-generated comment: release notes by coderabbit.ai --> ## Summary by CodeRabbit - New Features - None - Bug Fixes - More reliable scroll restoration after navigation and refresh. - Improved handling of URL hash anchors for accurate in-page scrolling. - Consistent scroll-to-top behavior across configured elements. - Avoids runtime errors when session storage is unavailable or data is invalid. - Refactor - Streamlined scroll handling and state initialization for improved stability and minor performance gains. <!-- end of auto-generated comment: release notes by coderabbit.ai --> --------- Co-authored-by: autofix-ci[bot] <114827586+autofix-ci[bot]@users.noreply.github.com>
1 parent 67ef027 commit 400065c

File tree

1 file changed

+25
-32
lines changed

1 file changed

+25
-32
lines changed

packages/router-core/src/scroll-restoration.ts

Lines changed: 25 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,7 @@ function getSafeSessionStorage() {
2828
return window.sessionStorage
2929
}
3030
} catch {
31-
return undefined
31+
// silent
3232
}
3333
return undefined
3434
}
@@ -85,14 +85,14 @@ export const defaultGetScrollRestorationKey = (location: ParsedLocation) => {
8585

8686
export function getCssSelector(el: any): string {
8787
const path = []
88-
let parent
88+
let parent: HTMLElement
8989
while ((parent = el.parentNode)) {
90-
path.unshift(
91-
`${el.tagName}:nth-child(${([].indexOf as any).call(parent.children, el) + 1})`,
90+
path.push(
91+
`${el.tagName}:nth-child(${Array.prototype.indexOf.call(parent.children, el) + 1})`,
9292
)
9393
el = parent
9494
}
95-
return `${path.join(' > ')}`.toLowerCase()
95+
return `${path.reverse().join(' > ')}`.toLowerCase()
9696
}
9797

9898
let ignoreScroll = false
@@ -120,7 +120,7 @@ export function restoreScroll({
120120

121121
try {
122122
byKey = JSON.parse(sessionStorage.getItem(storageKey) || '{}')
123-
} catch (error: any) {
123+
} catch (error) {
124124
console.error(error)
125125
return
126126
}
@@ -132,7 +132,7 @@ export function restoreScroll({
132132
ignoreScroll = true
133133

134134
//
135-
;(() => {
135+
scroll: {
136136
// If we have a cached entry for this location state,
137137
// we always need to prefer that over the hash scroll.
138138
if (
@@ -157,18 +157,18 @@ export function restoreScroll({
157157
}
158158
}
159159

160-
return
160+
break scroll
161161
}
162162

163163
// If we don't have a cached entry for the hash,
164164
// Which means we've never seen this location before,
165165
// we need to check if there is a hash in the URL.
166166
// If there is, we need to scroll it's ID into view.
167-
const hash = (location ?? window.location).hash.split('#')[1]
167+
const hash = (location ?? window.location).hash.split('#', 2)[1]
168168

169169
if (hash) {
170170
const hashScrollIntoViewOptions =
171-
(window.history.state || {}).__hashScrollIntoViewOptions ?? true
171+
window.history.state?.__hashScrollIntoViewOptions ?? true
172172

173173
if (hashScrollIntoViewOptions) {
174174
const el = document.getElementById(hash)
@@ -177,30 +177,24 @@ export function restoreScroll({
177177
}
178178
}
179179

180-
return
180+
break scroll
181181
}
182182

183183
// If there is no cached entry for the hash and there is no hash in the URL,
184184
// we need to scroll to the top of the page for every scrollToTop element
185-
;[
186-
'window',
187-
...(scrollToTopSelectors?.filter((d) => d !== 'window') ?? []),
188-
].forEach((selector) => {
189-
const element =
190-
selector === 'window'
191-
? window
192-
: typeof selector === 'function'
185+
const scrollOptions = { top: 0, left: 0, behavior }
186+
window.scrollTo(scrollOptions)
187+
if (scrollToTopSelectors) {
188+
for (const selector of scrollToTopSelectors) {
189+
if (selector === 'window') continue
190+
const element =
191+
typeof selector === 'function'
193192
? selector()
194193
: document.querySelector(selector)
195-
if (element) {
196-
element.scrollTo({
197-
top: 0,
198-
left: 0,
199-
behavior,
200-
})
194+
if (element) element.scrollTo(scrollOptions)
201195
}
202-
})
203-
})()
196+
}
197+
}
204198

205199
//
206200
ignoreScroll = false
@@ -294,11 +288,10 @@ export function setupScrollRestoration(router: AnyRouter, force?: boolean) {
294288
const restoreKey = getKey(router.state.location)
295289

296290
scrollRestorationCache.set((state) => {
297-
const keyEntry = (state[restoreKey] =
298-
state[restoreKey] || ({} as ScrollRestorationByElement))
291+
const keyEntry = (state[restoreKey] ||= {} as ScrollRestorationByElement)
299292

300-
const elementEntry = (keyEntry[elementSelector] =
301-
keyEntry[elementSelector] || ({} as ScrollRestorationEntry))
293+
const elementEntry = (keyEntry[elementSelector] ||=
294+
{} as ScrollRestorationEntry)
302295

303296
if (elementSelector === 'window') {
304297
elementEntry.scrollX = window.scrollX || 0
@@ -344,7 +337,7 @@ export function setupScrollRestoration(router: AnyRouter, force?: boolean) {
344337
if (router.isScrollRestoring) {
345338
// Mark the location as having been seen
346339
scrollRestorationCache.set((state) => {
347-
state[cacheKey] = state[cacheKey] || ({} as ScrollRestorationByElement)
340+
state[cacheKey] ||= {} as ScrollRestorationByElement
348341

349342
return state
350343
})

0 commit comments

Comments
 (0)