Skip to content

refactor: simplify skeleton loading and OrchestratorList rendering#598

Draft
rickstaa wants to merge 1 commit intomainfrom
feat/reduce-cls-skeleton-loaders
Draft

refactor: simplify skeleton loading and OrchestratorList rendering#598
rickstaa wants to merge 1 commit intomainfrom
feat/reduce-cls-skeleton-loaders

Conversation

@rickstaa
Copy link
Copy Markdown
Member

@rickstaa rickstaa commented Mar 25, 2026

Summary

  • Inline ConnectButton skeleton directly in the dynamic() loading callback to prevent CLS during hydration (SSR-disabled component needs a placeholder while its JS chunk loads)
  • Simplify OrchestratorList rendering in pages/index.tsx by removing showOrchList state, requestAnimationFrame deferral, Spinner wrapper, and external skeleton — data is always available from getStaticProps so these loading states were never shown in practice (same as TransactionsList which has no skeleton)

Extracted from #509 by @Roaring30s. Partially addresses #433.

Note: useWindowSize removal and useMediaQuery replacement will be handled in a follow-up PR — see #602.

Test plan

  • Verify ConnectButton area shows skeleton on initial page load (throttle network in DevTools)
  • Confirm no layout shift when ConnectButton hydrates
  • Verify OrchestratorList renders correctly without the showOrchList deferral
  • Run Lighthouse and check CLS score

@rickstaa rickstaa requested a review from ECWireless as a code owner March 25, 2026 11:00
Copilot AI review requested due to automatic review settings March 25, 2026 11:00
@vercel
Copy link
Copy Markdown
Contributor

vercel bot commented Mar 25, 2026

The latest updates on your projects. Learn more about Vercel for GitHub.

Project Deployment Actions Updated (UTC)
explorer-arbitrum-one Ready Ready Preview, Comment Mar 26, 2026 11:57am

Request Review

Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull request overview

This PR targets Lighthouse CLS improvements by adding skeleton fallbacks for client-only UI and reducing forced reflows in the main layout by removing useWindowSize usage.

Changes:

  • Add skeleton loaders for ConnectButton (dynamic import fallback) and the home-page Orchestrator list.
  • Replace the “Loading orchestrators…” placeholder with a skeleton component.
  • Remove useWindowSize and the width-based useEffect that previously adjusted document.body overflow in layouts/main.tsx.

Reviewed changes

Copilot reviewed 4 out of 4 changed files in this pull request and generated 4 comments.

File Description
pages/index.tsx Uses OrchestratorListSkeleton instead of a text placeholder before the orchestrator list mounts.
layouts/main.tsx Removes useWindowSize and adds a dynamic-import loading skeleton for ConnectButton.
components/OrchestratorList/Skeleton.tsx New skeleton UI intended to match the OrchestratorList table layout while it’s deferred.
components/ConnectButton/Skeleton.tsx New skeleton UI used as the loading fallback for the client-only ConnectButton.
Comments suppressed due to low confidence (1)

layouts/main.tsx:216

  • Removing the width-based effect means document.body.style.overflow = "hidden" (set in onDrawerOpen) may remain stuck if the viewport crosses the mobile/desktop breakpoint while the drawer is open (e.g., resize/rotate), since there’s no longer any breakpoint listener to clear it. Consider using a lightweight matchMedia listener for the @bp3 breakpoint (or closing the drawer on breakpoint change) to ensure body overflow is always restored when leaving the mobile drawer layout.
  useEffect(() => {
    ReactGA.set({
      customBrowserType: !isMobile
        ? "desktop"

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment on lines +31 to +36
{/* Table header skeleton */}
<Box
css={{ padding: "$3 $5", borderBottom: "1px solid $colors$neutral4" }}
>
<Flex css={{ gap: "$4" }}>
<Skeleton css={{ width: 150, height: 16 }} />
Copy link

Copilot AI Mar 25, 2026

Choose a reason for hiding this comment

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

This skeleton doesn’t replicate the Table layout constraints (notably the overflowX: "auto" wrapper and minWidth: 960 table width in components/Table/index.tsx). On narrow viewports this can reintroduce CLS when the real OrchestratorList mounts and suddenly forces horizontal scrolling/min-width. Consider matching the Table wrapper structure/constraints so the skeleton and real table occupy the same space.

Copilot uses AI. Check for mistakes.
css={{
marginTop: "$4",
marginLeft: "$5",
marginBottom: "$4",
Copy link

Copilot AI Mar 25, 2026

Choose a reason for hiding this comment

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

The input-section spacing here doesn’t match the real Table input wrapper: components/Table/index.tsx applies marginTop: "$4" and marginLeft: "$5" but no wrapper marginBottom. The extra marginBottom: "$4" in the skeleton makes it taller than the real OrchestratorList header area, which can cause a vertical layout shift when swapping from skeleton to the actual table.

Suggested change
marginBottom: "$4",

Copilot uses AI. Check for mistakes.
layouts/main.tsx Outdated
Comment on lines +111 to +115
import ConnectButtonSkeleton from "../components/ConnectButton/Skeleton";

const ConnectButton = dynamic(() => import("../components/ConnectButton"), {
ssr: false,
loading: () => <ConnectButtonSkeleton />,
Copy link

Copilot AI Mar 25, 2026

Choose a reason for hiding this comment

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

ConnectButtonSkeleton is imported mid-file (after non-import statements) and via a relative path. With simple-import-sort/imports enforced, this will fail lint and also deviates from the existing @components/* import convention in this file. Move the import into the main import block and use the @components/ConnectButton/Skeleton alias so imports can be sorted correctly.

Copilot uses AI. Check for mistakes.
pages/index.tsx Outdated
Comment on lines +7 to +8
import RoundStatus from "@components/RoundStatus";
import OrchestratorListSkeleton from "@components/OrchestratorList/Skeleton";
Copy link

Copilot AI Mar 25, 2026

Choose a reason for hiding this comment

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

Import order here is no longer sorted (@components/OrchestratorList/Skeleton comes after @components/RoundStatus). With simple-import-sort/imports enforced in this repo, this will fail lint; re-run import sorting so the new skeleton import is placed in the correct order within the @components/* group.

Suggested change
import RoundStatus from "@components/RoundStatus";
import OrchestratorListSkeleton from "@components/OrchestratorList/Skeleton";
import OrchestratorListSkeleton from "@components/OrchestratorList/Skeleton";
import RoundStatus from "@components/RoundStatus";

Copilot uses AI. Check for mistakes.
const activeChain = useActiveChain();
const [drawerOpen, setDrawerOpen] = useState(false);
const [bannerActive, setBannerActive] = useState<boolean>(false);
const { width } = useWindowSize();
Copy link
Copy Markdown
Contributor

@vercel vercel bot Mar 25, 2026

Choose a reason for hiding this comment

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

Drawer open on mobile leaves body.overflow hidden after window resize to desktop, preventing page scrolling

Fix on Vercel

Inline ConnectButton skeleton directly in the dynamic() loading
callback to prevent CLS during hydration. Simplify OrchestratorList
rendering in pages/index.tsx by removing the showOrchList state,
requestAnimationFrame deferral, and Spinner wrapper — data is always
available from getStaticProps so these loading states were never shown.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
@rickstaa rickstaa changed the title feat: reduce CLS with skeleton loaders and remove useWindowSize refactor: simplify skeleton loading and OrchestratorList rendering Mar 26, 2026
@rickstaa rickstaa force-pushed the feat/reduce-cls-skeleton-loaders branch from f008ea4 to af3a5b5 Compare March 26, 2026 11:55
@rickstaa rickstaa marked this pull request as draft March 26, 2026 13:49
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

Status: Triage

Development

Successfully merging this pull request may close these issues.

2 participants