Skip to content

refactor(router-core): scroll-restoration minor performance cleanup #4990

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 3 commits into
base: main
Choose a base branch
from

Conversation

Sheraff
Copy link
Contributor

@Sheraff Sheraff commented Aug 18, 2025

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
    • 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

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.

Copy link

coderabbitai bot commented Aug 18, 2025

Walkthrough

Refactors scroll-restoration internals in a single file: adjusts error handling, refines CSS selector building, simplifies restore flow with a labeled block, improves hash parsing and state access, standardizes scroll behavior, and modernizes state initialization using ||=. No public API changes.

Changes

Cohort / File(s) Summary
Scroll Restoration Refactor
packages/router-core/src/scroll-restoration.ts
Silent error handling in getSafeSessionStorage; reworked getCssSelector path assembly and typing; restoreScroll control-flow via labeled block, robust hash split, optional chaining for history state, unified scroll options and per-selector scrolling; setupScrollRestoration and onRendered use

Sequence Diagram(s)

sequenceDiagram
  participant User
  participant Router
  participant ScrollRestoration
  participant History
  participant SessionStorage as SessionStorage
  participant Window as Window/DOM

  User->>Router: Navigate/render
  Router->>ScrollRestoration: restoreScroll()
  ScrollRestoration->>History: read state (__hashScrollIntoViewOptions)
  ScrollRestoration->>SessionStorage: getSafeSessionStorage()
  ScrollRestoration->>Window: window.scrollTo({top:0,left:0,behavior})
  ScrollRestoration->>Window: For each selector: element.scrollTo({top:0,left:0,behavior})
Loading

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~25 minutes

Suggested reviewers

  • schiller-manuel

Poem

A rabbit hops through routes anew,
With labeled leaps and cleaner view.
A gentle hush for errors caught,
And tidy paths by selectors wrought.
Scrolls align from top to base—
Hop, hop! restored to perfect place. 🐇✨

✨ Finishing Touches
  • 📝 Generate Docstrings
🧪 Generate unit tests
  • Create PR with unit tests
  • Post copyable unit tests in a comment
  • Commit unit tests in branch refactor-router-core-scroll-restoration-misc-perf

🪧 Tips

Chat

There are 3 ways to chat with CodeRabbit:

  • Review comments: Directly reply to a review comment made by CodeRabbit. Example:
    • I pushed a fix in commit <commit_id>, please review it.
    • Open a follow-up GitHub issue for this discussion.
  • Files and specific lines of code (under the "Files changed" tab): Tag @coderabbitai in a new review comment at the desired location with your query.
  • PR comments: Tag @coderabbitai in a new PR comment to ask questions about the PR branch. For the best results, please provide a very specific query, as very limited context is provided in this mode. Examples:
    • @coderabbitai gather interesting stats about this repository and render them as a table. Additionally, render a pie chart showing the language distribution in the codebase.
    • @coderabbitai read the files in the src/scheduler package and generate a class diagram using mermaid and a README in the markdown format.

Support

Need help? Create a ticket on our support page for assistance with any issues or questions.

CodeRabbit Commands (Invoked using PR/Issue comments)

Type @coderabbitai help to get the list of available commands.

Other keywords and placeholders

  • Add @coderabbitai ignore anywhere in the PR description to prevent this PR from being reviewed.
  • Add @coderabbitai summary to generate the high-level summary at a specific location in the PR description.
  • Add @coderabbitai anywhere in the PR title to generate the title automatically.

CodeRabbit Configuration File (.coderabbit.yaml)

  • You can programmatically configure CodeRabbit by adding a .coderabbit.yaml file to the root of your repository.
  • Please see the configuration documentation for more information.
  • If your editor has YAML language server enabled, you can add the path at the top of this file to enable auto-completion and validation: # yaml-language-server: $schema=https://coderabbit.ai/integrations/schema.v2.json

Status, Documentation and Community

  • Visit our Status Page to check the current availability of CodeRabbit.
  • Visit our Documentation for detailed information on how to use CodeRabbit.
  • Join our Discord Community to get help, request features, and share feedback.
  • Follow us on X/Twitter for updates and announcements.

Copy link

nx-cloud bot commented Aug 18, 2025

View your CI Pipeline Execution ↗ for commit 23fa3d8

Command Status Duration Result
nx affected --targets=test:eslint,test:unit,tes... ✅ Succeeded 4m 8s View ↗
nx run-many --target=build --exclude=examples/*... ✅ Succeeded 1m 36s View ↗

☁️ Nx Cloud last updated this comment at 2025-08-18 13:21:43 UTC

Copy link

pkg-pr-new bot commented Aug 18, 2025

More templates

@tanstack/arktype-adapter

npm i https://pkg.pr.new/TanStack/router/@tanstack/arktype-adapter@4990

@tanstack/directive-functions-plugin

npm i https://pkg.pr.new/TanStack/router/@tanstack/directive-functions-plugin@4990

@tanstack/eslint-plugin-router

npm i https://pkg.pr.new/TanStack/router/@tanstack/eslint-plugin-router@4990

@tanstack/history

npm i https://pkg.pr.new/TanStack/router/@tanstack/history@4990

@tanstack/react-router

npm i https://pkg.pr.new/TanStack/router/@tanstack/react-router@4990

@tanstack/react-router-devtools

npm i https://pkg.pr.new/TanStack/router/@tanstack/react-router-devtools@4990

@tanstack/react-router-ssr-query

npm i https://pkg.pr.new/TanStack/router/@tanstack/react-router-ssr-query@4990

@tanstack/react-start

npm i https://pkg.pr.new/TanStack/router/@tanstack/react-start@4990

@tanstack/react-start-client

npm i https://pkg.pr.new/TanStack/router/@tanstack/react-start-client@4990

@tanstack/react-start-plugin

npm i https://pkg.pr.new/TanStack/router/@tanstack/react-start-plugin@4990

@tanstack/react-start-server

npm i https://pkg.pr.new/TanStack/router/@tanstack/react-start-server@4990

@tanstack/router-cli

npm i https://pkg.pr.new/TanStack/router/@tanstack/router-cli@4990

@tanstack/router-core

npm i https://pkg.pr.new/TanStack/router/@tanstack/router-core@4990

@tanstack/router-devtools

npm i https://pkg.pr.new/TanStack/router/@tanstack/router-devtools@4990

@tanstack/router-devtools-core

npm i https://pkg.pr.new/TanStack/router/@tanstack/router-devtools-core@4990

@tanstack/router-generator

npm i https://pkg.pr.new/TanStack/router/@tanstack/router-generator@4990

@tanstack/router-plugin

npm i https://pkg.pr.new/TanStack/router/@tanstack/router-plugin@4990

@tanstack/router-ssr-query-core

npm i https://pkg.pr.new/TanStack/router/@tanstack/router-ssr-query-core@4990

@tanstack/router-utils

npm i https://pkg.pr.new/TanStack/router/@tanstack/router-utils@4990

@tanstack/router-vite-plugin

npm i https://pkg.pr.new/TanStack/router/@tanstack/router-vite-plugin@4990

@tanstack/server-functions-plugin

npm i https://pkg.pr.new/TanStack/router/@tanstack/server-functions-plugin@4990

@tanstack/solid-router

npm i https://pkg.pr.new/TanStack/router/@tanstack/solid-router@4990

@tanstack/solid-router-devtools

npm i https://pkg.pr.new/TanStack/router/@tanstack/solid-router-devtools@4990

@tanstack/solid-start

npm i https://pkg.pr.new/TanStack/router/@tanstack/solid-start@4990

@tanstack/solid-start-client

npm i https://pkg.pr.new/TanStack/router/@tanstack/solid-start-client@4990

@tanstack/solid-start-plugin

npm i https://pkg.pr.new/TanStack/router/@tanstack/solid-start-plugin@4990

@tanstack/solid-start-server

npm i https://pkg.pr.new/TanStack/router/@tanstack/solid-start-server@4990

@tanstack/start-client-core

npm i https://pkg.pr.new/TanStack/router/@tanstack/start-client-core@4990

@tanstack/start-plugin-core

npm i https://pkg.pr.new/TanStack/router/@tanstack/start-plugin-core@4990

@tanstack/start-server-core

npm i https://pkg.pr.new/TanStack/router/@tanstack/start-server-core@4990

@tanstack/start-server-functions-client

npm i https://pkg.pr.new/TanStack/router/@tanstack/start-server-functions-client@4990

@tanstack/start-server-functions-fetcher

npm i https://pkg.pr.new/TanStack/router/@tanstack/start-server-functions-fetcher@4990

@tanstack/start-server-functions-server

npm i https://pkg.pr.new/TanStack/router/@tanstack/start-server-functions-server@4990

@tanstack/start-storage-context

npm i https://pkg.pr.new/TanStack/router/@tanstack/start-storage-context@4990

@tanstack/valibot-adapter

npm i https://pkg.pr.new/TanStack/router/@tanstack/valibot-adapter@4990

@tanstack/virtual-file-routes

npm i https://pkg.pr.new/TanStack/router/@tanstack/virtual-file-routes@4990

@tanstack/zod-adapter

npm i https://pkg.pr.new/TanStack/router/@tanstack/zod-adapter@4990

commit: 23fa3d8

Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 0

🧹 Nitpick comments (1)
packages/router-core/src/scroll-restoration.ts (1)

31-31: Consider preserving error context for debugging

Silently swallowing errors can make debugging harder in production environments. Consider at least logging the error to help with troubleshooting storage-related issues.

   } catch {
-    // silent
+    // Storage access denied or unavailable
📜 Review details

Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro

💡 Knowledge Base configuration:

  • MCP integration is disabled by default for public repositories
  • Jira integration is disabled by default for public repositories
  • Linear integration is disabled by default for public repositories

You can enable these sources in your CodeRabbit configuration.

📥 Commits

Reviewing files that changed from the base of the PR and between f2190d7 and 23fa3d8.

📒 Files selected for processing (1)
  • packages/router-core/src/scroll-restoration.ts (8 hunks)
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (2)
  • GitHub Check: Test
  • GitHub Check: Preview
🔇 Additional comments (7)
packages/router-core/src/scroll-restoration.ts (7)

88-88: Good performance improvement with explicit typing

The explicit typing of parent as HTMLElement improves type safety and code clarity.


90-95: Clever optimization using push + reverse instead of unshift

Good performance optimization! Using push() in the loop followed by a single reverse() is more efficient than repeated unshift() operations, as unshift() has O(n) complexity for each call while push() is O(1).


135-161: Smart refactor using labeled block instead of IIFE

Excellent optimization! Replacing the IIFE with a labeled block eliminates the function call overhead while maintaining the same control flow semantics. This is a clean and performant approach.


167-167: Robust hash extraction with split limit

Good defensive programming! Using split('#', 2) ensures that only the first # is used as a delimiter, preventing issues with URLs that might contain multiple # characters in the hash portion.


185-196: Clean scroll-to-top implementation

The refactored implementation is more readable and maintainable. The use of a single scrollOptions object and the explicit continue for 'window' selector improves code clarity.


291-294: Efficient state initialization with ||= operator

Great use of the logical OR assignment operator (||=) for lazy initialization. This is both more concise and potentially more performant than the previous approach.


340-340: Consistent use of ||= operator

Good consistency with the ||= operator usage throughout the file. This maintains a uniform coding style.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

1 participant