diff options
author | Mathieu Suen <mathieu.suen@sonarsource.com> | 2022-09-27 11:11:45 +0200 |
---|---|---|
committer | sonartech <sonartech@sonarsource.com> | 2022-09-29 20:03:14 +0000 |
commit | 27a59988437611958e553e0028f5aab949d53e9c (patch) | |
tree | d1bd54bf86a6ad3c6f8cf0082777152bbbeec143 /server/sonar-web/src/main/js/components/SourceViewer/helpers | |
parent | 516a97f0bae4ae30ccdf6db3d328cbd1939d3ffc (diff) | |
download | sonarqube-27a59988437611958e553e0028f5aab949d53e9c.tar.gz sonarqube-27a59988437611958e553e0028f5aab949d53e9c.zip |
SONAR-17416 Improve Source code viewer perfomance and allow to load more line each time
Diffstat (limited to 'server/sonar-web/src/main/js/components/SourceViewer/helpers')
5 files changed, 22 insertions, 37 deletions
diff --git a/server/sonar-web/src/main/js/components/SourceViewer/helpers/__tests__/loadIssues-test.ts b/server/sonar-web/src/main/js/components/SourceViewer/helpers/__tests__/loadIssues-test.ts index 5fd555bbf6b..ca57c36d947 100644 --- a/server/sonar-web/src/main/js/components/SourceViewer/helpers/__tests__/loadIssues-test.ts +++ b/server/sonar-web/src/main/js/components/SourceViewer/helpers/__tests__/loadIssues-test.ts @@ -82,7 +82,7 @@ jest.mock('../../../../api/issues', () => ({ describe('loadIssues', () => { it('should load issues', async () => { - const result = await loadIssues('foo.java', 1, 500, mockMainBranch()); + const result = await loadIssues('foo.java', mockMainBranch()); expect(result).toMatchSnapshot(); }); }); diff --git a/server/sonar-web/src/main/js/components/SourceViewer/helpers/highlight.ts b/server/sonar-web/src/main/js/components/SourceViewer/helpers/highlight.ts index 6c457caa288..9749f769b7c 100644 --- a/server/sonar-web/src/main/js/components/SourceViewer/helpers/highlight.ts +++ b/server/sonar-web/src/main/js/components/SourceViewer/helpers/highlight.ts @@ -28,15 +28,13 @@ export interface Token { const ISSUE_LOCATION_CLASS = 'source-line-code-issue'; -export function splitByTokens(code: string, rootClassName = ''): Token[] { - const container = document.createElement('div'); +export function splitByTokens(code: NodeListOf<ChildNode>, rootClassName = ''): Token[] { let tokens: Token[] = []; - container.innerHTML = code; - [].forEach.call(container.childNodes, (node: Element) => { + Array.prototype.forEach.call(code, (node: Element) => { if (node.nodeType === 1) { // ELEMENT NODE const fullClassName = rootClassName ? rootClassName + ' ' + node.className : node.className; - const innerTokens = splitByTokens(node.innerHTML, fullClassName); + const innerTokens = splitByTokens(node.childNodes, fullClassName); tokens = tokens.concat(innerTokens); } if (node.nodeType === 3 && node.nodeValue) { diff --git a/server/sonar-web/src/main/js/components/SourceViewer/helpers/indexing.ts b/server/sonar-web/src/main/js/components/SourceViewer/helpers/indexing.ts index 3e840c2ae6f..92e594ebc11 100644 --- a/server/sonar-web/src/main/js/components/SourceViewer/helpers/indexing.ts +++ b/server/sonar-web/src/main/js/components/SourceViewer/helpers/indexing.ts @@ -86,7 +86,9 @@ export function duplicationsByLine(duplications: Duplication[] | undefined) { export function symbolsByLine(sources: SourceLine[]) { const index: { [line: number]: string[] } = {}; sources.forEach(line => { - const tokens = splitByTokens(line.code || ''); + const container = document.createElement('div'); + container.innerHTML = line.code || ''; + const tokens = splitByTokens(container.childNodes); const symbols = flatten( tokens.map(token => { const keys = token.className.match(/sym-\d+/g); diff --git a/server/sonar-web/src/main/js/components/SourceViewer/helpers/lines.ts b/server/sonar-web/src/main/js/components/SourceViewer/helpers/lines.ts index ef4bcf0348c..63d1395b079 100644 --- a/server/sonar-web/src/main/js/components/SourceViewer/helpers/lines.ts +++ b/server/sonar-web/src/main/js/components/SourceViewer/helpers/lines.ts @@ -20,7 +20,7 @@ import { intersection } from 'lodash'; import { LinearIssueLocation } from '../../../types/types'; -export const LINES_TO_LOAD = 500; +export const LINES_TO_LOAD = 1000; export function optimizeHighlightedSymbols( symbolsForLine: string[] = [], diff --git a/server/sonar-web/src/main/js/components/SourceViewer/helpers/loadIssues.ts b/server/sonar-web/src/main/js/components/SourceViewer/helpers/loadIssues.ts index 74e47b39cba..aa4bb6ab580 100644 --- a/server/sonar-web/src/main/js/components/SourceViewer/helpers/loadIssues.ts +++ b/server/sonar-web/src/main/js/components/SourceViewer/helpers/loadIssues.ts @@ -25,6 +25,8 @@ import { Issue, RawQuery } from '../../../types/types'; // maximum possible value const PAGE_SIZE = 500; +// Maximum issues return 20*500 for the API. +const PAGE_MAX = 20; function buildQuery(component: string, branchLike: BranchLike | undefined) { return { @@ -36,7 +38,7 @@ function buildQuery(component: string, branchLike: BranchLike | undefined) { }; } -export function loadPage(query: RawQuery, page: number, pageSize = PAGE_SIZE): Promise<Issue[]> { +function loadPage(query: RawQuery, page: number, pageSize = PAGE_SIZE): Promise<Issue[]> { return searchIssues({ ...query, p: page, @@ -46,42 +48,25 @@ export function loadPage(query: RawQuery, page: number, pageSize = PAGE_SIZE): P ); } -export function loadPageAndNext( - query: RawQuery, - toLine: number, - page: number, - pageSize = PAGE_SIZE -): Promise<Issue[]> { - return loadPage(query, page).then(issues => { - if (issues.length === 0) { - return []; - } +async function loadPageAndNext(query: RawQuery, page = 1, pageSize = PAGE_SIZE): Promise<Issue[]> { + const issues = await loadPage(query, page); - const lastIssue = issues[issues.length - 1]; + if (issues.length === 0) { + return []; + } - if ( - (lastIssue.textRange != null && lastIssue.textRange.endLine > toLine) || - issues.length < pageSize - ) { - return issues; - } + if (issues.length < pageSize || page >= PAGE_MAX) { + return issues; + } - return loadPageAndNext(query, toLine, page + 1, pageSize).then(nextIssues => { - return [...issues, ...nextIssues]; - }); - }); + const nextIssues = await loadPageAndNext(query, page + 1, pageSize); + return [...issues, ...nextIssues]; } export default function loadIssues( component: string, - _fromLine: number, - toLine: number, branchLike: BranchLike | undefined ): Promise<Issue[]> { const query = buildQuery(component, branchLike); - return new Promise(resolve => { - loadPageAndNext(query, toLine, 1).then(issues => { - resolve(issues); - }); - }); + return loadPageAndNext(query); } |