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:
- Per-chunk skeleton loaders: Display skeleton loaders for each chunk that is currently loading blame data
- Blame button loading state: Show loading spinner on the blame button during initial activation
Screenshots or screen recordings
Before
After
How to set up and validate locally
- Navigate to any repository file (e.g.,
/gitlab-org/gitlab/-/blob/master/README.md) - Click the "Blame" button
- Verify: Button shows loading spinner during initial load
- Verify: Skeleton loaders appear in blame column for initial chunks
- Scroll down to trigger loading of additional chunks
- Verify: Skeleton loaders appear for new chunks as they load
- 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
loadingChunksarray 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.vueemitsblame-loading-changedevents when initial loading state changes - Parent component passes loading state to
blob_header_viewer_switcher.vue - Blame button receives
isBlameLoadingprop to show loading spinner
Visual Feedback:
- Enhanced
blame_info.vueto 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.vueapp/assets/javascripts/vue_shared/components/source_viewer/components/blame_info.vueapp/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

