Commit 13e54b58 authored by Tim Zallmann's avatar Tim Zallmann Committed by Kushal Pandya

Added Total rendering metrics to Performance Bar

Added the Frontend resources string to .pot
Added specs, documentation and changelog
parent 3431e27c
...@@ -52,6 +52,11 @@ export default { ...@@ -52,6 +52,11 @@ export default {
header: s__('PerformanceBar|Redis calls'), header: s__('PerformanceBar|Redis calls'),
keys: ['cmd'], keys: ['cmd'],
}, },
{
metric: 'total',
header: s__('PerformanceBar|Frontend resources'),
keys: ['name', 'size'],
},
], ],
data() { data() {
return { currentRequestId: '' }; return { currentRequestId: '' };
......
/* eslint-disable @gitlab/i18n/no-non-i18n-strings */
import Vue from 'vue'; import Vue from 'vue';
import axios from '~/lib/utils/axios_utils'; import axios from '~/lib/utils/axios_utils';
...@@ -53,12 +54,61 @@ export default ({ container }) => ...@@ -53,12 +54,61 @@ export default ({ container }) =>
PerformanceBarService.fetchRequestDetails(this.peekUrl, requestId) PerformanceBarService.fetchRequestDetails(this.peekUrl, requestId)
.then(res => { .then(res => {
this.store.addRequestDetails(requestId, res.data); this.store.addRequestDetails(requestId, res.data);
if (this.requestId === requestId) this.collectFrontendPerformanceMetrics();
}) })
.catch(() => .catch(() =>
// eslint-disable-next-line no-console // eslint-disable-next-line no-console
console.warn(`Error getting performance bar results for ${requestId}`), console.warn(`Error getting performance bar results for ${requestId}`),
); );
}, },
collectFrontendPerformanceMetrics() {
if (performance) {
const navigationEntries = performance.getEntriesByType('navigation');
const paintEntries = performance.getEntriesByType('paint');
const resourceEntries = performance.getEntriesByType('resource');
let durationString = '';
if (navigationEntries.length > 0) {
durationString = `BE ${this.formatMs(navigationEntries[0].responseEnd)} / `;
durationString += `FCP ${this.formatMs(paintEntries[1].startTime)} / `;
durationString += `DOM ${this.formatMs(navigationEntries[0].domContentLoadedEventEnd)}`;
}
let newEntries = resourceEntries.map(this.transformResourceEntry);
this.updateFrontendPerformanceMetrics(durationString, newEntries);
if ('PerformanceObserver' in window) {
// We start observing for more incoming timings
const observer = new PerformanceObserver(list => {
newEntries = newEntries.concat(list.getEntries().map(this.transformResourceEntry));
this.updateFrontendPerformanceMetrics(durationString, newEntries);
});
observer.observe({ entryTypes: ['resource'] });
}
}
},
updateFrontendPerformanceMetrics(durationString, requestEntries) {
this.store.setRequestDetailsData(this.requestId, 'total', {
duration: durationString,
calls: requestEntries.length,
details: requestEntries,
});
},
transformResourceEntry(entry) {
const nf = new Intl.NumberFormat();
return {
name: entry.name.replace(document.location.origin, ''),
duration: Math.round(entry.duration),
size: entry.transferSize ? `${nf.format(entry.transferSize)} bytes` : 'cached',
};
},
formatMs(msValue) {
const nf = new Intl.NumberFormat();
return `${nf.format(Math.round(msValue))}ms`;
},
}, },
render(createElement) { render(createElement) {
return createElement('performance-bar-app', { return createElement('performance-bar-app', {
......
...@@ -32,6 +32,16 @@ export default class PerformanceBarStore { ...@@ -32,6 +32,16 @@ export default class PerformanceBarStore {
return request; return request;
} }
setRequestDetailsData(requestId, metricKey, requestDetailsData) {
const selectedRequest = this.findRequest(requestId);
if (selectedRequest) {
selectedRequest.details = {
...selectedRequest.details,
[metricKey]: requestDetailsData,
};
}
}
requestsWithDetails() { requestsWithDetails() {
return this.requests.filter(request => request.details); return this.requests.filter(request => request.details);
} }
......
---
title: Added Total/Frontend metrics to the performance bar
merge_request: 20725
author:
type: added
...@@ -16,6 +16,12 @@ It allows you to see (from left to right): ...@@ -16,6 +16,12 @@ It allows you to see (from left to right):
![Rugged profiling using the Performance Bar](img/performance_bar_rugged_calls.png) ![Rugged profiling using the Performance Bar](img/performance_bar_rugged_calls.png)
- time taken and number of Redis calls; click through for details of these calls - time taken and number of Redis calls; click through for details of these calls
![Redis profiling using the Performance Bar](img/performance_bar_redis_calls.png) ![Redis profiling using the Performance Bar](img/performance_bar_redis_calls.png)
- total load timings of the page; click through for details of these calls
- BE = Backend - Time that the actual base page took to load
- FCP = [First Contentful Paint](https://developers.google.com/web/tools/lighthouse/audits/first-contentful-paint) - Time until something was visible to the user
- DOM = [DomContentLoaded](https://developers.google.com/web/fundamentals/performance/critical-rendering-path/measure-crp) Event
- Number of Requests that the page loaded
![Frontend requests using the Performance Bar](img/performance_bar_frontend.png)
- a link to add a request's details to the performance bar; the request can be - a link to add a request's details to the performance bar; the request can be
added by its full URL (authenticated as the current user), or by the value of added by its full URL (authenticated as the current user), or by the value of
its `X-Request-Id` header its `X-Request-Id` header
......
...@@ -12278,6 +12278,9 @@ msgstr "" ...@@ -12278,6 +12278,9 @@ msgstr ""
msgid "PerformanceBar|Download" msgid "PerformanceBar|Download"
msgstr "" msgstr ""
msgid "PerformanceBar|Frontend resources"
msgstr ""
msgid "PerformanceBar|Gitaly calls" msgid "PerformanceBar|Gitaly calls"
msgstr "" msgstr ""
......
...@@ -42,4 +42,21 @@ describe('PerformanceBarStore', () => { ...@@ -42,4 +42,21 @@ describe('PerformanceBarStore', () => {
expect(findUrl('id')).toEqual('html5-boilerplate'); expect(findUrl('id')).toEqual('html5-boilerplate');
}); });
}); });
describe('setRequestDetailsData', () => {
let store;
beforeEach(() => {
store = new PerformanceBarStore();
});
it('updates correctly specific details', () => {
store.addRequest('id', 'https://gitlab.com/');
store.setRequestDetailsData('id', 'test', {
calls: 123,
});
expect(store.findRequest('id').details.test.calls).toEqual(123);
});
});
}); });
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment