Commit 2eb549c1 authored by Heinrich Lee Yu's avatar Heinrich Lee Yu

Lazily load performance bar request details

Only request the Peek results when switching to the specific request.
This avoids many requests when loading a page that triggers a lot of
AJAX requests.
parent 7a966852
......@@ -134,6 +134,7 @@ export default {
methods: {
changeCurrentRequest(newRequestId) {
this.currentRequest = newRequestId;
this.$emit('change-request', newRequestId);
},
flamegraphPath(mode) {
return mergeUrlParams(
......
import '../webpack';
import { isEmpty } from 'lodash';
import Vue from 'vue';
import axios from '~/lib/utils/axios_utils';
import { numberToHumanSize } from '~/lib/utils/number_utils';
......@@ -37,9 +38,10 @@ const initPerformanceBar = (el) => {
};
},
mounted() {
PerformanceBarService.registerInterceptor(this.peekUrl, this.loadRequestDetails);
PerformanceBarService.registerInterceptor(this.peekUrl, this.addRequest);
this.loadRequestDetails(this.requestId, window.location.href);
this.addRequest(this.requestId, window.location.href);
this.loadRequestDetails(this.requestId);
},
beforeDestroy() {
PerformanceBarService.removeInterceptor();
......@@ -51,26 +53,32 @@ const initPerformanceBar = (el) => {
// want to trace the request.
axios.get(urlOrRequestId);
} else {
this.loadRequestDetails(urlOrRequestId, urlOrRequestId);
this.addRequest(urlOrRequestId, urlOrRequestId);
}
},
loadRequestDetails(requestId, requestUrl) {
addRequest(requestId, requestUrl) {
if (!this.store.canTrackRequest(requestUrl)) {
return;
}
this.store.addRequest(requestId, requestUrl);
},
loadRequestDetails(requestId) {
const request = this.store.findRequest(requestId);
if (request && isEmpty(request.details)) {
return PerformanceBarService.fetchRequestDetails(this.peekUrl, requestId)
.then((res) => {
this.store.addRequestDetails(requestId, res.data);
if (this.requestId === requestId) this.collectFrontendPerformanceMetrics();
})
.catch(() =>
// eslint-disable-next-line no-console
console.warn(`Error getting performance bar results for ${requestId}`),
);
}
PerformanceBarService.fetchRequestDetails(this.peekUrl, requestId)
.then((res) => {
this.store.addRequestDetails(requestId, res.data);
if (this.requestId === requestId) this.collectFrontendPerformanceMetrics();
})
.catch(() =>
// eslint-disable-next-line no-console
console.warn(`Error getting performance bar results for ${requestId}`),
);
return Promise.resolve();
},
collectFrontendPerformanceMetrics() {
if (performance) {
......@@ -143,6 +151,7 @@ const initPerformanceBar = (el) => {
},
on: {
'add-request': this.addRequestManually,
'change-request': this.loadRequestDetails,
},
});
},
......
......@@ -18,4 +18,15 @@ describe('performance bar app', () => {
it('sets the class to match the environment', () => {
expect(wrapper.element.getAttribute('class')).toContain('development');
});
describe('changeCurrentRequest', () => {
it('emits a change-request event', () => {
expect(wrapper.emitted('change-request')).toBeUndefined();
wrapper.vm.changeCurrentRequest('123');
expect(wrapper.emitted('change-request')).toBeDefined();
expect(wrapper.emitted('change-request')[0]).toEqual(['123']);
});
});
});
......@@ -51,7 +51,7 @@ describe('performance bar wrapper', () => {
mock.restore();
});
describe('loadRequestDetails', () => {
describe('addRequest', () => {
beforeEach(() => {
jest.spyOn(vm.store, 'addRequest');
});
......@@ -59,26 +59,46 @@ describe('performance bar wrapper', () => {
it('does nothing if the request cannot be tracked', () => {
jest.spyOn(vm.store, 'canTrackRequest').mockImplementation(() => false);
vm.loadRequestDetails('123', 'https://gitlab.com/');
vm.addRequest('123', 'https://gitlab.com/');
expect(vm.store.addRequest).not.toHaveBeenCalled();
});
it('adds the request immediately', () => {
vm.loadRequestDetails('123', 'https://gitlab.com/');
vm.addRequest('123', 'https://gitlab.com/');
expect(vm.store.addRequest).toHaveBeenCalledWith('123', 'https://gitlab.com/');
});
});
it('makes an HTTP request for the request details', () => {
describe('loadRequestDetails', () => {
beforeEach(() => {
jest.spyOn(PerformanceBarService, 'fetchRequestDetails');
});
vm.loadRequestDetails('456', 'https://gitlab.com/');
it('makes an HTTP request for the request details', () => {
vm.addRequest('456', 'https://gitlab.com/');
vm.loadRequestDetails('456');
expect(PerformanceBarService.fetchRequestDetails).toHaveBeenCalledWith(
'/-/peek/results',
'456',
);
});
it('does not make a request if request was not added', () => {
vm.loadRequestDetails('456');
expect(PerformanceBarService.fetchRequestDetails).not.toHaveBeenCalled();
});
it('makes an HTTP request only once for the same request', async () => {
vm.addRequest('456', 'https://gitlab.com/');
await vm.loadRequestDetails('456');
vm.loadRequestDetails('456');
expect(PerformanceBarService.fetchRequestDetails).toHaveBeenCalledTimes(1);
});
});
});
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