diff options
author | Filipa Lacerda <filipa@gitlab.com> | 2018-07-05 12:05:57 +0000 |
---|---|---|
committer | Phil Hughes <me@iamphill.com> | 2018-07-05 12:05:57 +0000 |
commit | 49828db524ad1d1a5dfd954e9635e0bdaedea5df (patch) | |
tree | bf8304e1078b1bb1a8018f8179cbeb89aa518db4 | |
parent | 8b0e2628099c34a9ac352b6a9a05605613c45a53 (diff) | |
download | gitlab-ce-49828db524ad1d1a5dfd954e9635e0bdaedea5df.tar.gz |
Improves performance on MR refactor and adds specs
-rw-r--r-- | app/assets/javascripts/diffs/components/parallel_diff_view.vue | 12 | ||||
-rw-r--r-- | app/assets/javascripts/diffs/store/utils.js | 27 | ||||
-rw-r--r-- | app/assets/javascripts/notes/components/diff_with_note.vue | 159 | ||||
-rw-r--r-- | changelogs/unreleased/48825-performance.yml | 8 | ||||
-rw-r--r-- | spec/javascripts/diffs/store/utils_spec.js | 31 |
5 files changed, 143 insertions, 94 deletions
diff --git a/app/assets/javascripts/diffs/components/parallel_diff_view.vue b/app/assets/javascripts/diffs/components/parallel_diff_view.vue index d7280338b68..52561e197e6 100644 --- a/app/assets/javascripts/diffs/components/parallel_diff_view.vue +++ b/app/assets/javascripts/diffs/components/parallel_diff_view.vue @@ -24,19 +24,21 @@ export default { ...mapGetters(['commit']), parallelDiffLines() { return this.diffLines.map(line => { + const parallelLine = Object.assign({}, line); + if (line.left) { - Object.assign(line, { left: trimFirstCharOfLineContent(line.left) }); + parallelLine.left = trimFirstCharOfLineContent(line.left); } else { - Object.assign(line, { left: { type: EMPTY_CELL_TYPE } }); + parallelLine.left = { type: EMPTY_CELL_TYPE }; } if (line.right) { - Object.assign(line, { right: trimFirstCharOfLineContent(line.right) }); + parallelLine.right = trimFirstCharOfLineContent(line.right); } else { - Object.assign(line, { right: { type: EMPTY_CELL_TYPE } }); + parallelLine.right = { type: EMPTY_CELL_TYPE }; } - return line; + return parallelLine; }); }, diffLinesLength() { diff --git a/app/assets/javascripts/diffs/store/utils.js b/app/assets/javascripts/diffs/store/utils.js index da7ae16aaf1..d9589baa76e 100644 --- a/app/assets/javascripts/diffs/store/utils.js +++ b/app/assets/javascripts/diffs/store/utils.js @@ -155,18 +155,21 @@ export function addContextLines(options) { } } -export function trimFirstCharOfLineContent(line) { - if (!line.richText) { - return line; - } - - const firstChar = line.richText.charAt(0); - - if (firstChar === ' ' || firstChar === '+' || firstChar === '-') { - Object.assign(line, { - richText: line.richText.substring(1), - }); +/** + * Trims the first char of the `richText` property when it's either a space or a diff symbol. + * @param {Object} line + * @returns {Object} + */ +export function trimFirstCharOfLineContent(line = {}) { + const parsedLine = Object.assign({}, line); + + if (line.richText) { + const firstChar = parsedLine.richText.charAt(0); + + if (firstChar === ' ' || firstChar === '+' || firstChar === '-') { + parsedLine.richText = line.richText.substring(1); + } } - return line; + return parsedLine; } diff --git a/app/assets/javascripts/notes/components/diff_with_note.vue b/app/assets/javascripts/notes/components/diff_with_note.vue index d321f2ce15e..9c2908c477e 100644 --- a/app/assets/javascripts/notes/components/diff_with_note.vue +++ b/app/assets/javascripts/notes/components/diff_with_note.vue @@ -1,89 +1,94 @@ <script> -import { mapState, mapActions } from 'vuex'; -import imageDiffHelper from '~/image_diff/helpers/index'; -import { convertObjectPropsToCamelCase } from '~/lib/utils/common_utils'; -import DiffFileHeader from '~/diffs/components/diff_file_header.vue'; -import SkeletonLoadingContainer from '~/vue_shared/components/skeleton_loading_container.vue'; -import { trimFirstCharOfLineContent } from '~/diffs/store/utils'; + import { mapState, mapActions } from 'vuex'; + import imageDiffHelper from '~/image_diff/helpers/index'; + import { convertObjectPropsToCamelCase } from '~/lib/utils/common_utils'; + import DiffFileHeader from '~/diffs/components/diff_file_header.vue'; + import SkeletonLoadingContainer from '~/vue_shared/components/skeleton_loading_container.vue'; + import { trimFirstCharOfLineContent } from '~/diffs/store/utils'; -export default { - components: { - DiffFileHeader, - SkeletonLoadingContainer, - }, - props: { - discussion: { - type: Object, - required: true, + export default { + components: { + DiffFileHeader, + SkeletonLoadingContainer, }, - }, - data() { - return { - error: false, - }; - }, - computed: { - ...mapState({ - noteableData: state => state.notes.noteableData, - }), - hasTruncatedDiffLines() { - return this.discussion.truncatedDiffLines && this.discussion.truncatedDiffLines.length !== 0; + props: { + discussion: { + type: Object, + required: true, + }, }, - isDiscussionsExpanded() { - return true; // TODO: @fatihacet - Fix this. + data() { + return { + error: false, + }; }, - isCollapsed() { - return this.diffFile.collapsed || false; - }, - isImageDiff() { - return !this.diffFile.text; - }, - diffFileClass() { - const { text } = this.diffFile; - return text ? 'text-file' : 'js-image-file'; - }, - diffFile() { - return convertObjectPropsToCamelCase(this.discussion.diffFile, { deep: true }); - }, - imageDiffHtml() { - return this.discussion.imageDiffHtml; - }, - currentUser() { - return this.noteableData.current_user; - }, - userColorScheme() { - return window.gon.user_color_scheme; - }, - normalizedDiffLines() { - const lines = this.discussion.truncatedDiffLines || []; + computed: { + ...mapState({ + noteableData: state => state.notes.noteableData, + }), + hasTruncatedDiffLines() { + return this.discussion.truncatedDiffLines && + this.discussion.truncatedDiffLines.length !== 0; + }, + isDiscussionsExpanded() { + return true; // TODO: @fatihacet - Fix this. + }, + isCollapsed() { + return this.diffFile.collapsed || false; + }, + isImageDiff() { + return !this.diffFile.text; + }, + diffFileClass() { + const { text } = this.diffFile; + return text ? 'text-file' : 'js-image-file'; + }, + diffFile() { + return convertObjectPropsToCamelCase(this.discussion.diffFile, { deep: true }); + }, + imageDiffHtml() { + return this.discussion.imageDiffHtml; + }, + currentUser() { + return this.noteableData.current_user; + }, + userColorScheme() { + return window.gon.user_color_scheme; + }, + normalizedDiffLines() { + if (this.discussion.truncatedDiffLines) { + return this.discussion.truncatedDiffLines.map(line => + trimFirstCharOfLineContent(convertObjectPropsToCamelCase(line)), + ); + } - return lines.map(line => trimFirstCharOfLineContent(convertObjectPropsToCamelCase(line))); + return []; + }, }, - }, - mounted() { - if (this.isImageDiff) { - const canCreateNote = false; - const renderCommentBadge = true; - imageDiffHelper.initImageDiff(this.$refs.fileHolder, canCreateNote, renderCommentBadge); - } else if (!this.hasTruncatedDiffLines) { - this.fetchDiff(); - } - }, - methods: { - ...mapActions(['fetchDiscussionDiffLines']), - rowTag(html) { - return html.outerHTML ? 'tr' : 'template'; + mounted() { + if (this.isImageDiff) { + const canCreateNote = false; + const renderCommentBadge = true; + imageDiffHelper.initImageDiff(this.$refs.fileHolder, canCreateNote, renderCommentBadge); + } else if (!this.hasTruncatedDiffLines) { + this.fetchDiff(); + } }, - fetchDiff() { - this.error = false; - this.fetchDiscussionDiffLines(this.discussion) - .then(this.highlight) - .catch(() => { - this.error = true; - }); + methods: { + ...mapActions(['fetchDiscussionDiffLines']), + rowTag(html) { + return html.outerHTML ? 'tr' : 'template'; + }, + fetchDiff() { + this.error = false; + this.fetchDiscussionDiffLines(this.discussion) + .then(this.highlight) + .catch(() => { + this.error = true; + }); + }, }, - }, -}; + }; </script> <template> diff --git a/changelogs/unreleased/48825-performance.yml b/changelogs/unreleased/48825-performance.yml new file mode 100644 index 00000000000..428852f6f8b --- /dev/null +++ b/changelogs/unreleased/48825-performance.yml @@ -0,0 +1,8 @@ +--- +title: Improves performance of mr code, by fixing the state being mutated outside + of the store in the util function trimFirstCharOfLineContent and in map operations. + Avoids map operation in an empty array. Adds specs to the trimFirstCharOfLineContent + function +merge_request: 20380 +author: filipa +type: performance diff --git a/spec/javascripts/diffs/store/utils_spec.js b/spec/javascripts/diffs/store/utils_spec.js index 5a024a0f2ad..32136d9ebff 100644 --- a/spec/javascripts/diffs/store/utils_spec.js +++ b/spec/javascripts/diffs/store/utils_spec.js @@ -176,4 +176,35 @@ describe('DiffsStoreUtils', () => { expect(linesWithReferences[1].metaData.newPos).toEqual(3); }); }); + + describe('trimFirstCharOfLineContent', () => { + it('trims the line when it starts with a space', () => { + expect(utils.trimFirstCharOfLineContent({ richText: ' diff' })).toEqual({ richText: 'diff' }); + }); + + it('trims the line when it starts with a +', () => { + expect(utils.trimFirstCharOfLineContent({ richText: '+diff' })).toEqual({ richText: 'diff' }); + }); + + it('trims the line when it starts with a -', () => { + expect(utils.trimFirstCharOfLineContent({ richText: '-diff' })).toEqual({ richText: 'diff' }); + }); + + it('does not trims the line when it starts with a letter', () => { + expect(utils.trimFirstCharOfLineContent({ richText: 'diff' })).toEqual({ richText: 'diff' }); + }); + + it('does not modify the provided object', () => { + const lineObj = { + richText: ' diff', + }; + + utils.trimFirstCharOfLineContent(lineObj); + expect(lineObj).toEqual({ richText: ' diff' }); + }); + + it('handles a undefined or null parameter', () => { + expect(utils.trimFirstCharOfLineContent()).toEqual({}); + }); + }); }); |