diff --git a/app/assets/javascripts/rapid_diffs/stores/diffs_list.js b/app/assets/javascripts/rapid_diffs/stores/diffs_list.js
index d8f4adb01bffae498ee04b04b8012a51bd06be18..84edbcf5ec9cdceb779fbc5da96d65cd767ca9b3 100644
--- a/app/assets/javascripts/rapid_diffs/stores/diffs_list.js
+++ b/app/assets/javascripts/rapid_diffs/stores/diffs_list.js
@@ -4,6 +4,7 @@ import { renderHtmlStreams } from '~/streaming/render_html_streams';
 import { toPolyfillReadable } from '~/streaming/polyfills';
 import { DiffFile } from '~/rapid_diffs/diff_file';
 import { DIFF_FILE_MOUNTED } from '~/rapid_diffs/dom_events';
+import { performanceMarkAndMeasure } from '~/performance/utils';
 
 export const statuses = {
   idle: 'idle',
@@ -66,6 +67,16 @@ export const useDiffsList = defineStore('diffsList', {
           document.querySelector('#js-stream-container'),
           signal,
         );
+        performanceMarkAndMeasure({
+          mark: 'rapid-diffs-list-loaded',
+          measures: [
+            {
+              name: 'rapid-diffs-list-loading',
+              start: 'rapid-diffs-first-diff-file-shown',
+              end: 'rapid-diffs-list-loaded',
+            },
+          ],
+        });
       });
     },
     reloadDiffs(url) {
diff --git a/app/components/rapid_diffs/app_component.html.haml b/app/components/rapid_diffs/app_component.html.haml
index 62c78497877f85a207801e582918b20191bdba8d..9be3beefaf39979882fd4a2a3315b7ba6bc74fb0 100644
--- a/app/components/rapid_diffs/app_component.html.haml
+++ b/app/components/rapid_diffs/app_component.html.haml
@@ -9,9 +9,19 @@
     .rd-app-content{ data: { sidebar_visible: true } }
       .code{ class: helpers.user_color_scheme }
         %div{ data: { diffs_list: true } }
+          = javascript_tag nonce: content_security_policy_nonce do
+            :plain
+              requestAnimationFrame(() => { window.performance.mark('rapid-diffs-first-diff-file-shown') })
           - if diffs_list?
             = diffs_list
           - else
             = render RapidDiffs::DiffFileComponent.with_collection(@diffs_slice, parallel_view: @diff_view == :parallel)
           - if @stream_url
             #js-stream-container{ data: { diffs_stream_url: @stream_url } }
+          - else
+            = javascript_tag nonce: content_security_policy_nonce do
+              :plain
+                requestAnimationFrame(() => {
+                  window.performance.mark('rapid-diffs-list-loaded');
+                  window.performance.measure('rapid-diffs-list-loading', 'rapid-diffs-first-diff-file-shown', 'rapid-diffs-list-loaded');
+                })
diff --git a/spec/frontend/rapid_diffs/stores/diffs_list_spec.js b/spec/frontend/rapid_diffs/stores/diffs_list_spec.js
index 476b3e901c24ce7506814e2fde7f1ddcc22a2b04..69982a6b410992645e366cd3a8121705c188dc85 100644
--- a/spec/frontend/rapid_diffs/stores/diffs_list_spec.js
+++ b/spec/frontend/rapid_diffs/stores/diffs_list_spec.js
@@ -7,9 +7,11 @@ import waitForPromises from 'helpers/wait_for_promises';
 import { toPolyfillReadable } from '~/streaming/polyfills';
 import { DiffFile } from '~/rapid_diffs/diff_file';
 import { DIFF_FILE_MOUNTED } from '~/rapid_diffs/dom_events';
+import { performanceMarkAndMeasure } from '~/performance/utils';
 
 jest.mock('~/streaming/polyfills');
 jest.mock('~/streaming/render_html_streams');
+jest.mock('~/performance/utils');
 
 describe('Diffs list store', () => {
   let store;
@@ -103,6 +105,21 @@ describe('Diffs list store', () => {
       });
     });
 
+    it('measures performance', async () => {
+      await store.streamRemainingDiffs('/stream');
+      await waitForPromises();
+      expect(performanceMarkAndMeasure).toHaveBeenCalledWith({
+        mark: 'rapid-diffs-list-loaded',
+        measures: [
+          {
+            name: 'rapid-diffs-list-loading',
+            start: 'rapid-diffs-first-diff-file-shown',
+            end: 'rapid-diffs-list-loaded',
+          },
+        ],
+      });
+    });
+
     itCancelsRunningRequest(() => store.streamRemainingDiffs('/stream'));
     itSetsStatuses(() => store.streamRemainingDiffs('/stream'));
     itAddsLoadingFilesWhileStreaming(() => store.streamRemainingDiffs('/stream'));