Skip to content

Add skeleton loader per chunk and button loading

Add skeleton loaders for per-chunk blame loading

What does this MR do and why?

This MR improves the user experience of the inline blame viewer by adding skeleton loaders for individual chunks as they load, and a loading state for the blame button during initial activation.

Problem: Users reported confusion about whether blame data was still loading when scrolling through files. The current implementation only shows a skeleton loader when blame is first activated, but provides no visual feedback when additional chunks load as users scroll. This led to users waiting unnecessarily (5-10 seconds) to ensure all data had loaded.

Solution:

  1. Per-chunk skeleton loaders: Display skeleton loaders for each chunk that is currently loading blame data
  2. Blame button loading state: Show loading spinner on the blame button during initial activation

Screenshots or screen recordings

Before

Current behavior showing no loading feedback for chunks

After

New behavior with per-chunk skeletons and button loading state

How to set up and validate locally

  1. Navigate to any repository file (e.g., /gitlab-org/gitlab/-/blob/master/README.md)
  2. Click the "Blame" button
  3. Verify: Button shows loading spinner during initial load
  4. Verify: Skeleton loaders appear in blame column for initial chunks
  5. Scroll down to trigger loading of additional chunks
  6. Verify: Skeleton loaders appear for new chunks as they load
  7. Verify: Skeletons disappear when actual blame data loads

MR acceptance checklist

  • Code review guidelines
  • Merge request performance guidelines
  • Style guides
  • Database guidelines
  • Separation of EE specific content

Implementation details

Architecture Changes

Loading State Management:

  • Added loadingChunks array to track which chunks are currently loading blame data
  • Modified handleChunkAppear() to update loading state when chunks start/finish loading
  • Used Vue's reactivity system with arrays instead of Sets for better compatibility

Component Communication:

  • source_viewer.vue emits blame-loading-changed events when initial loading state changes
  • Parent component passes loading state to blob_header_viewer_switcher.vue
  • Blame button receives isBlameLoading prop to show loading spinner

Visual Feedback:

  • Enhanced blame_info.vue to render skeleton loaders for loading chunks
  • Skeletons positioned to align with their corresponding code chunks
  • Maintained existing initial skeleton loader for backward compatibility

Files Modified

  • app/assets/javascripts/vue_shared/components/source_viewer/source_viewer.vue
  • app/assets/javascripts/vue_shared/components/source_viewer/components/blame_info.vue
  • app/assets/javascripts/blob/components/blob_header_viewer_switcher.vue
  • Parent component containing both header and source viewer

Related issues

Closes #500037

Testing

  • Added/updated unit tests for loading state management
  • Added/updated integration tests for skeleton loader rendering
  • Verified accessibility of loading states
  • Tested with large files to ensure performance
  • Tested rapid scrolling scenarios

Merge request reports

Loading