Skip to content

#442 Memoize and code-split the ActivityTimeline so its sample data a…#456

Merged
Baskarayelu merged 1 commit into
CredenceOrg:mainfrom
felladaniel36-hash:#442-Memoize-and-code-split-the-ActivityTimeline-so-its-sample-data-and-CSS-leave-the-Trust-chunk-FIX
Jun 29, 2026
Merged

#442 Memoize and code-split the ActivityTimeline so its sample data a…#456
Baskarayelu merged 1 commit into
CredenceOrg:mainfrom
felladaniel36-hash:#442-Memoize-and-code-split-the-ActivityTimeline-so-its-sample-data-and-CSS-leave-the-Trust-chunk-FIX

Conversation

@felladaniel36-hash

@felladaniel36-hash felladaniel36-hash commented Jun 28, 2026

Copy link
Copy Markdown
Contributor

FINDINGS

  1. Root Cause
    The ACTIVITY_ITEMS constant (and SAMPLE_ACTIVITY) along with the full ActivityTimeline.tsx + ActivityTimeline.css were statically imported directly into TrustScore.tsx (and also used in Dashboard.tsx + Attestations.tsx).
    This caused the entire timeline component + its styling to be bundled into the initial route chunk, even though the timeline is a secondary, scroll-into-view surface (recent-activity panel).

  2. Impact

    • Bloated initial paint for the Trust Score route.
    • No code-splitting.
    • No row-level memoization → all rows re-rendered on any parent state change.
    • No loading skeleton for the lazy surface.
  3. Context Alignment
    The timeline is slated for both the Trust Score recent-activity panel and a dedicated Attestations route, making lazy loading + memoization critical for performance.


FIX FEATURES IMPLEMENTED

# Feature Implementation Benefit
1 Data Extraction Created src/data/activity.ts and moved SAMPLE_ACTIVITY, ACTIVITY_ITEMS, ActivityItem, and ActivityTone there Single source of truth. Prevents duplication and reduces bundle bloat in component files.
2 Memoized Row Rendering Extracted ActivityRow as a separate component inside ActivityTimeline.tsx and wrapped it with React.memo Rows no longer re-render when the parent (TrustScore) re-renders due to unrelated state.
3 Lazy Loading + Code Splitting In TrustScore.tsx (the primary consuming surface):
const LazyActivityTimeline = lazy(() => import('../components/ActivityTimeline'))
Wrapped with <Suspense>
ActivityTimeline.tsx + its CSS are now split into a separate chunk and only loaded when the panel renders.
4 Loading Skeleton Fallback Custom skeleton inside the Suspense boundary that matches the timeline layout (header + 3 rows) Provides immediate visual feedback while the chunk loads.
5 Reduced-Motion Safe Skeleton Skeleton uses the existing useReducedMotion hook (same pattern as LoadingSkeleton.tsx) No shimmer animation when user has prefers-reduced-motion: reduce.
6 Edge Case Handling - Empty items → immediately shows EmptyState
- Chunk failure → covered by existing ErrorBoundary
- Skeleton only shown during actual chunk load
Prevents stuck skeleton states and maintains existing behavior.
7 Contract Preservation items prop, default ACTIVITY_ITEMS, compact prop, empty state, tone classes, expand/collapse behavior all unchanged No breaking changes for other consumers (Dashboard, Attestations).
8 Error Handling Leverages the repo’s existing ErrorBoundary pattern (already wrapping routes) Chunk load failures are gracefully handled with retry.

BEFORE vs AFTER IMPACT

Aspect Before After
Chunk containing timeline Bundled in main TrustScore chunk Dedicated ActivityTimeline-*.js + .css
Row re-renders All rows re-render on parent updates Memoized via React.memo(ActivityRow)
Loading state None (blank until loaded) Layout-matched skeleton (reduced-motion safe)
Empty state Worked Still works immediately (no skeleton)
Bundle size (Trust Score initial) Larger Leaner (timeline deferred)

Build evidence (from npm run build):

  • dist/assets/ActivityTimeline-DJOtewtF.js (2.78 kB)
  • dist/assets/ActivityTimeline-BUviJIQi.css (3.75 kB)
  • dist/assets/activity-BIwCDQbB.js

SUMMARY

This fix completely addresses the issue description:

  • ✅ Timeline + CSS split into a separate chunk via React.lazy + Suspense
  • LoadingSkeleton fallback matching the timeline layout
  • ActivityRow extracted and wrapped with React.memo
  • ✅ Empty-state contract and all existing props preserved
  • ✅ Reduced-motion support
  • ✅ Uses existing lazy-loading + ErrorBoundary patterns in the repo
  • ✅ TypeScript strict

Result: The Trust Score initial paint is now leaner, and the timeline only loads when the user scrolls to the recent-activity panel.

CLOSES #442

…mple data and CSS leave the Trust chunk FIXED
@felladaniel36-hash

felladaniel36-hash commented Jun 28, 2026

Copy link
Copy Markdown
Contributor Author

@Baskarayelu PLEASE REVIEW.... AND PING ME BACK

@drips-wave

drips-wave Bot commented Jun 28, 2026

Copy link
Copy Markdown

@felladaniel36-hash Great news! 🎉 Based on an automated assessment of this PR, the linked Wave issue(s) no longer count against your application limits.

You can now already apply to more issues while waiting for a review of this PR. Keep up the great work! 🚀

Learn more about application limits

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

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Memoize and code-split the ActivityTimeline so its sample data and CSS leave the Trust chunk

2 participants