Commit 025a27b1 authored by Simon Knox's avatar Simon Knox

Merge branch '238973-user-timing-webide' into 'master'

Introduce User Timing API metrics for WebIDE

See merge request gitlab-org/gitlab!43407
parents fe976e4e 8f78da10
......@@ -2,7 +2,18 @@
import { mapActions, mapGetters, mapState } from 'vuex';
import { GlButton, GlLoadingIcon } from '@gitlab/ui';
import { __ } from '~/locale';
import {
WEBIDE_MARK_APP_START,
WEBIDE_MARK_FILE_FINISH,
WEBIDE_MARK_FILE_CLICKED,
WEBIDE_MARK_TREE_FINISH,
WEBIDE_MEASURE_TREE_FROM_REQUEST,
WEBIDE_MEASURE_FILE_FROM_REQUEST,
WEBIDE_MEASURE_FILE_AFTER_INTERACTION,
} from '~/performance_constants';
import { performanceMarkAndMeasure } from '~/performance_utils';
import { modalTypes } from '../constants';
import eventHub from '../eventhub';
import FindFile from '~/vue_shared/components/file_finder/index.vue';
import NewModal from './new_dropdown/modal.vue';
import IdeSidebar from './ide_side_bar.vue';
......@@ -14,6 +25,50 @@ import ErrorMessage from './error_message.vue';
import CommitEditorHeader from './commit_sidebar/editor_header.vue';
import glFeatureFlagsMixin from '~/vue_shared/mixins/gl_feature_flags_mixin';
const markPerformance = params => {
performanceMarkAndMeasure(params);
};
const markTreePerformance = () => {
markPerformance({
mark: WEBIDE_MARK_TREE_FINISH,
measures: [
{
name: WEBIDE_MEASURE_TREE_FROM_REQUEST,
start: undefined,
end: WEBIDE_MARK_TREE_FINISH,
},
],
});
};
const markEditorLoadPerformance = () => {
markPerformance({
mark: WEBIDE_MARK_FILE_FINISH,
measures: [
{
name: WEBIDE_MEASURE_FILE_FROM_REQUEST,
start: undefined,
end: WEBIDE_MARK_FILE_FINISH,
},
],
});
};
const markEditorInteractionPerformance = () => {
markPerformance({
mark: WEBIDE_MARK_FILE_FINISH,
measures: [
{
name: WEBIDE_MEASURE_FILE_AFTER_INTERACTION,
start: WEBIDE_MARK_FILE_CLICKED,
end: WEBIDE_MARK_FILE_FINISH,
},
],
});
};
eventHub.$on(WEBIDE_MEASURE_TREE_FROM_REQUEST, markTreePerformance);
eventHub.$on(WEBIDE_MEASURE_FILE_FROM_REQUEST, markEditorLoadPerformance);
eventHub.$on(WEBIDE_MEASURE_FILE_AFTER_INTERACTION, markEditorInteractionPerformance);
export default {
components: {
NewModal,
......@@ -59,6 +114,9 @@ export default {
if (this.themeName)
document.querySelector('.navbar-gitlab').classList.add(`theme-${this.themeName}`);
},
beforeCreate() {
performance.mark(WEBIDE_MARK_APP_START);
},
methods: {
...mapActions(['toggleFileFinder']),
onBeforeUnload(e = {}) {
......
......@@ -2,6 +2,13 @@
import { mapActions, mapGetters, mapState } from 'vuex';
import { GlDeprecatedSkeletonLoading as GlSkeletonLoading } from '@gitlab/ui';
import FileTree from '~/vue_shared/components/file_tree.vue';
import {
WEBIDE_MARK_TREE_START,
WEBIDE_MEASURE_TREE_FROM_REQUEST,
WEBIDE_MARK_FILE_CLICKED,
} from '~/performance_constants';
import { performanceMarkAndMeasure } from '~/performance_utils';
import eventHub from '../eventhub';
import IdeFileRow from './ide_file_row.vue';
import NavDropdown from './nav_dropdown.vue';
......@@ -25,8 +32,21 @@ export default {
return !this.currentTree || this.currentTree.loading;
},
},
beforeCreate() {
performanceMarkAndMeasure({ mark: WEBIDE_MARK_TREE_START });
},
updated() {
if (this.currentTree?.tree?.length) {
this.$nextTick(() => {
eventHub.$emit(WEBIDE_MEASURE_TREE_FROM_REQUEST);
});
}
},
methods: {
...mapActions(['toggleTreeOpen']),
clickedFile() {
performanceMarkAndMeasure({ mark: WEBIDE_MARK_FILE_CLICKED });
},
},
IdeFileRow,
};
......@@ -53,6 +73,7 @@ export default {
:level="0"
:file-row-component="$options.IdeFileRow"
@toggleTreeOpen="toggleTreeOpen"
@clickFile="clickedFile"
/>
</template>
<div v-else class="file-row">{{ __('No files') }}</div>
......
......@@ -4,6 +4,14 @@ import { viewerInformationForPath } from '~/vue_shared/components/content_viewer
import { deprecatedCreateFlash as flash } from '~/flash';
import ContentViewer from '~/vue_shared/components/content_viewer/content_viewer.vue';
import DiffViewer from '~/vue_shared/components/diff_viewer/diff_viewer.vue';
import {
WEBIDE_MARK_FILE_CLICKED,
WEBIDE_MARK_FILE_START,
WEBIDE_MEASURE_FILE_AFTER_INTERACTION,
WEBIDE_MEASURE_FILE_FROM_REQUEST,
} from '~/performance_constants';
import { performanceMarkAndMeasure } from '~/performance_utils';
import eventHub from '../eventhub';
import {
leftSidebarViews,
viewerTypes,
......@@ -164,6 +172,9 @@ export default {
}
},
},
beforeCreate() {
performanceMarkAndMeasure({ mark: WEBIDE_MARK_FILE_START });
},
beforeDestroy() {
this.editor.dispose();
},
......@@ -289,6 +300,13 @@ export default {
});
this.$emit('editorSetup');
this.$nextTick(() => {
if (performance.getEntriesByName(WEBIDE_MARK_FILE_CLICKED).length) {
eventHub.$emit(WEBIDE_MEASURE_FILE_AFTER_INTERACTION);
} else {
eventHub.$emit(WEBIDE_MEASURE_FILE_FROM_REQUEST);
}
});
},
refreshEditorDimensions() {
if (this.showEditor) {
......
......@@ -5,7 +5,7 @@ export const PERFORMANCE_TYPE_MEASURE = 'measure';
// SNIPPET namespace
//
// marks
// Marks
export const SNIPPET_MARK_VIEW_APP_START = 'snippet-view-app-start';
export const SNIPPET_MARK_EDIT_APP_START = 'snippet-edit-app-start';
export const SNIPPET_MARK_BLOBS_CONTENT = 'snippet-blobs-content-finished';
......@@ -13,3 +13,20 @@ export const SNIPPET_MARK_BLOBS_CONTENT = 'snippet-blobs-content-finished';
// Measures
export const SNIPPET_MEASURE_BLOBS_CONTENT = 'snippet-blobs-content';
export const SNIPPET_MEASURE_BLOBS_CONTENT_WITHIN_APP = 'snippet-blobs-content-within-app';
//
// WebIDE namespace
//
// Marks
export const WEBIDE_MARK_APP_START = 'webide-app-start';
export const WEBIDE_MARK_TREE_START = 'webide-tree-start';
export const WEBIDE_MARK_TREE_FINISH = 'webide-tree-finished';
export const WEBIDE_MARK_FILE_START = 'webide-file-start';
export const WEBIDE_MARK_FILE_CLICKED = 'webide-file-clicked';
export const WEBIDE_MARK_FILE_FINISH = 'webide-file-finished';
// Measures
export const WEBIDE_MEASURE_TREE_FROM_REQUEST = 'webide-tree-loading-from-request';
export const WEBIDE_MEASURE_FILE_FROM_REQUEST = 'webide-file-loading-from-request';
export const WEBIDE_MEASURE_FILE_AFTER_INTERACTION = 'webide-file-loading-after-interaction';
export const performanceMarkAndMeasure = ({ mark, measures = [] } = {}) => {
window.requestAnimationFrame(() => {
if (mark && !performance.getEntriesByName(mark).length) {
performance.mark(mark);
}
measures.forEach(measure => {
window.requestAnimationFrame(() =>
performance.measure(measure.name, measure.start, measure.end),
);
});
});
};
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