Commit 757c9e23 authored by Phil Hughes's avatar Phil Hughes

Impove the diffs app render queue

Improves the logic around the diffs app render queue to help decrease
the total blocking time.
With this change we set `renderIt` as `false` if the index of the
diff file is more than 3, this allows us to very quickly
render the first 3 files.

Closes https://gitlab.com/gitlab-org/gitlab/-/issues/321691
parent fe2022ba
...@@ -349,14 +349,6 @@ export default { ...@@ -349,14 +349,6 @@ export default {
refetchDiffData() { refetchDiffData() {
this.fetchData(false); this.fetchData(false);
}, },
startDiffRendering() {
requestIdleCallback(
() => {
this.startRenderDiffsQueue();
},
{ timeout: 1000 },
);
},
needsReload() { needsReload() {
return this.diffFiles.length && isSingleViewStyle(this.diffFiles[0]); return this.diffFiles.length && isSingleViewStyle(this.diffFiles[0]);
}, },
...@@ -368,8 +360,6 @@ export default { ...@@ -368,8 +360,6 @@ export default {
.then(({ real_size }) => { .then(({ real_size }) => {
this.diffFilesLength = parseInt(real_size, 10); this.diffFilesLength = parseInt(real_size, 10);
if (toggleTree) this.setTreeDisplay(); if (toggleTree) this.setTreeDisplay();
this.startDiffRendering();
}) })
.catch(() => { .catch(() => {
createFlash(__('Something went wrong on our end. Please try again!')); createFlash(__('Something went wrong on our end. Please try again!'));
...@@ -384,7 +374,6 @@ export default { ...@@ -384,7 +374,6 @@ export default {
// change when loading the other half of the diff files. // change when loading the other half of the diff files.
this.setDiscussions(); this.setDiscussions();
}) })
.then(() => this.startDiffRendering())
.catch(() => { .catch(() => {
createFlash(__('Something went wrong on our end. Please try again!')); createFlash(__('Something went wrong on our end. Please try again!'));
}); });
......
...@@ -49,7 +49,6 @@ import { ...@@ -49,7 +49,6 @@ import {
convertExpandLines, convertExpandLines,
idleCallback, idleCallback,
allDiscussionWrappersExpanded, allDiscussionWrappersExpanded,
prepareDiffData,
prepareLineForRenamedFile, prepareLineForRenamedFile,
} from './utils'; } from './utils';
...@@ -163,7 +162,15 @@ export const fetchDiffFilesBatch = ({ commit, state, dispatch }) => { ...@@ -163,7 +162,15 @@ export const fetchDiffFilesBatch = ({ commit, state, dispatch }) => {
return pagination.next_page; return pagination.next_page;
}) })
.then((nextPage) => nextPage && getBatch(nextPage)) .then((nextPage) => {
dispatch('startRenderDiffsQueue');
if (nextPage) {
return getBatch(nextPage);
}
return null;
})
.catch(() => commit(types.SET_RETRIEVING_BATCHES, false)); .catch(() => commit(types.SET_RETRIEVING_BATCHES, false));
return getBatch() return getBatch()
...@@ -197,13 +204,7 @@ export const fetchDiffFilesMeta = ({ commit, state }) => { ...@@ -197,13 +204,7 @@ export const fetchDiffFilesMeta = ({ commit, state }) => {
commit(types.SET_MERGE_REQUEST_DIFFS, data.merge_request_diffs || []); commit(types.SET_MERGE_REQUEST_DIFFS, data.merge_request_diffs || []);
commit(types.SET_DIFF_METADATA, strippedData); commit(types.SET_DIFF_METADATA, strippedData);
worker.postMessage( worker.postMessage(data.diff_files);
prepareDiffData({
diff: data,
priorFiles: state.diffFiles,
meta: true,
}),
);
return data; return data;
}) })
...@@ -304,33 +305,38 @@ export const renderFileForDiscussionId = ({ commit, rootState, state }, discussi ...@@ -304,33 +305,38 @@ export const renderFileForDiscussionId = ({ commit, rootState, state }, discussi
}; };
export const startRenderDiffsQueue = ({ state, commit }) => { export const startRenderDiffsQueue = ({ state, commit }) => {
const checkItem = () => const diffFilesToRender = state.diffFiles.filter(
new Promise((resolve) => { (file) =>
const nextFile = state.diffFiles.find( !file.renderIt &&
(file) => file.viewer &&
!file.renderIt && (!isCollapsed(file) || file.viewer.name !== diffViewerModes.text),
file.viewer && );
(!isCollapsed(file) || file.viewer.name !== diffViewerModes.text), let currentDiffFileIndex = 0;
);
const checkItem = () => {
if (nextFile) { const nextFile = diffFilesToRender[currentDiffFileIndex];
requestAnimationFrame(() => {
commit(types.RENDER_FILE, nextFile); if (nextFile) {
currentDiffFileIndex += 1;
commit(types.RENDER_FILE, nextFile);
const requestIdle = () =>
requestIdleCallback((idleDeadline) => {
// Wait for at least 5ms before trying to render
if (idleDeadline.timeRemaining() >= 6) {
checkItem();
} else {
requestIdle();
}
}); });
requestIdleCallback(
() => {
checkItem()
.then(resolve)
.catch(() => {});
},
{ timeout: 1000 },
);
} else {
resolve();
}
});
return checkItem(); requestIdle();
}
};
if (diffFilesToRender.length) {
checkItem();
}
}; };
export const setRenderIt = ({ commit }, file) => commit(types.RENDER_FILE, file); export const setRenderIt = ({ commit }, file) => commit(types.RENDER_FILE, file);
......
...@@ -381,22 +381,13 @@ function prepareDiffFileLines(file) { ...@@ -381,22 +381,13 @@ function prepareDiffFileLines(file) {
inlineLines.forEach((line) => prepareLine(line, file)); // WARNING: In-Place Mutations! inlineLines.forEach((line) => prepareLine(line, file)); // WARNING: In-Place Mutations!
Object.assign(file, {
inlineLinesCount: inlineLines.length,
});
return file; return file;
} }
function getVisibleDiffLines(file) { function finalizeDiffFile(file, index) {
return file.inlineLinesCount;
}
function finalizeDiffFile(file) {
const lines = getVisibleDiffLines(file);
Object.assign(file, { Object.assign(file, {
renderIt: lines < LINES_TO_BE_RENDERED_DIRECTLY, renderIt:
index < 3 ? file[INLINE_DIFF_LINES_KEY].length < LINES_TO_BE_RENDERED_DIRECTLY : false,
isShowingFullFile: false, isShowingFullFile: false,
isLoadingFullFile: false, isLoadingFullFile: false,
discussions: [], discussions: [],
...@@ -424,7 +415,7 @@ export function prepareDiffData({ diff, priorFiles = [], meta = false }) { ...@@ -424,7 +415,7 @@ export function prepareDiffData({ diff, priorFiles = [], meta = false }) {
.map((file, index, allFiles) => prepareRawDiffFile({ file, allFiles, meta })) .map((file, index, allFiles) => prepareRawDiffFile({ file, allFiles, meta }))
.map(ensureBasicDiffFileLines) .map(ensureBasicDiffFileLines)
.map(prepareDiffFileLines) .map(prepareDiffFileLines)
.map(finalizeDiffFile); .map((file, index) => finalizeDiffFile(file, priorFiles.length + index));
return deduplicateFilesList([...priorFiles, ...cleanedFiles]); return deduplicateFilesList([...priorFiles, ...cleanedFiles]);
} }
......
...@@ -105,7 +105,6 @@ describe('diffs/components/app', () => { ...@@ -105,7 +105,6 @@ describe('diffs/components/app', () => {
jest.spyOn(wrapper.vm, 'fetchDiffFilesBatch').mockImplementation(fetchResolver); jest.spyOn(wrapper.vm, 'fetchDiffFilesBatch').mockImplementation(fetchResolver);
jest.spyOn(wrapper.vm, 'fetchCoverageFiles').mockImplementation(fetchResolver); jest.spyOn(wrapper.vm, 'fetchCoverageFiles').mockImplementation(fetchResolver);
jest.spyOn(wrapper.vm, 'setDiscussions').mockImplementation(() => {}); jest.spyOn(wrapper.vm, 'setDiscussions').mockImplementation(() => {});
jest.spyOn(wrapper.vm, 'startRenderDiffsQueue').mockImplementation(() => {});
jest.spyOn(wrapper.vm, 'unwatchDiscussions').mockImplementation(() => {}); jest.spyOn(wrapper.vm, 'unwatchDiscussions').mockImplementation(() => {});
jest.spyOn(wrapper.vm, 'unwatchRetrievingBatches').mockImplementation(() => {}); jest.spyOn(wrapper.vm, 'unwatchRetrievingBatches').mockImplementation(() => {});
store.state.diffs.retrievingBatches = true; store.state.diffs.retrievingBatches = true;
...@@ -119,7 +118,6 @@ describe('diffs/components/app', () => { ...@@ -119,7 +118,6 @@ describe('diffs/components/app', () => {
await nextTick(); await nextTick();
expect(wrapper.vm.startRenderDiffsQueue).toHaveBeenCalled();
expect(wrapper.vm.fetchDiffFilesMeta).toHaveBeenCalled(); expect(wrapper.vm.fetchDiffFilesMeta).toHaveBeenCalled();
expect(wrapper.vm.fetchDiffFilesBatch).toHaveBeenCalled(); expect(wrapper.vm.fetchDiffFilesBatch).toHaveBeenCalled();
expect(wrapper.vm.fetchCoverageFiles).toHaveBeenCalled(); expect(wrapper.vm.fetchCoverageFiles).toHaveBeenCalled();
...@@ -134,7 +132,6 @@ describe('diffs/components/app', () => { ...@@ -134,7 +132,6 @@ describe('diffs/components/app', () => {
await nextTick(); await nextTick();
expect(wrapper.vm.startRenderDiffsQueue).toHaveBeenCalled();
expect(wrapper.vm.fetchDiffFilesMeta).toHaveBeenCalled(); expect(wrapper.vm.fetchDiffFilesMeta).toHaveBeenCalled();
expect(wrapper.vm.fetchDiffFilesBatch).toHaveBeenCalled(); expect(wrapper.vm.fetchDiffFilesBatch).toHaveBeenCalled();
expect(wrapper.vm.fetchCoverageFiles).toHaveBeenCalled(); expect(wrapper.vm.fetchCoverageFiles).toHaveBeenCalled();
......
...@@ -80,7 +80,7 @@ describe('DiffsStoreActions', () => { ...@@ -80,7 +80,7 @@ describe('DiffsStoreActions', () => {
jest.spyOn(utils, 'idleCallback').mockImplementation(() => null); jest.spyOn(utils, 'idleCallback').mockImplementation(() => null);
['requestAnimationFrame', 'requestIdleCallback'].forEach((method) => { ['requestAnimationFrame', 'requestIdleCallback'].forEach((method) => {
global[method] = (cb) => { global[method] = (cb) => {
cb(); cb({ timeRemaining: () => 10 });
}; };
}); });
}); });
...@@ -198,7 +198,7 @@ describe('DiffsStoreActions', () => { ...@@ -198,7 +198,7 @@ describe('DiffsStoreActions', () => {
{ type: types.VIEW_DIFF_FILE, payload: 'test2' }, { type: types.VIEW_DIFF_FILE, payload: 'test2' },
{ type: types.SET_RETRIEVING_BATCHES, payload: false }, { type: types.SET_RETRIEVING_BATCHES, payload: false },
], ],
[], [{ type: 'startRenderDiffsQueue' }, { type: 'startRenderDiffsQueue' }],
done, done,
); );
}); });
......
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