[Discover] Improve doc viewer source tab performance by limiting height (#127439) (#128125)

(cherry picked from commit f5533008dd)
This commit is contained in:
Matthias Wilhelm 2022-03-21 09:24:07 +01:00 committed by GitHub
parent 1a0c459e4a
commit 85e11e45f0
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
3 changed files with 97 additions and 5 deletions

View file

@ -0,0 +1,50 @@
/*
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
* or more contributor license agreements. Licensed under the Elastic License
* 2.0 and the Server Side Public License, v 1; you may not use this file except
* in compliance with, at your election, the Elastic License 2.0 or the Server
* Side Public License, v 1.
*/
import { monaco } from '@kbn/monaco';
import { getHeight } from './get_height';
describe('getHeight', () => {
window.innerHeight = 500;
const getMonacoMock = (lineCount: number) => {
return {
getDomNode: jest.fn(() => {
return {
getBoundingClientRect: jest.fn(() => {
return {
top: 200,
};
}),
};
}),
getOption: jest.fn(() => 10),
getModel: jest.fn(() => ({ getLineCount: jest.fn(() => lineCount) })),
getTopForLineNumber: jest.fn((line) => line * 10),
} as unknown as monaco.editor.IStandaloneCodeEditor;
};
test('when using document explorer, returning the available height in the flyout', () => {
const monacoMock = getMonacoMock(500);
const height = getHeight(monacoMock, true);
expect(height).toBe(275);
});
test('when using classic table, its displayed inline without scrolling', () => {
const monacoMock = getMonacoMock(100);
const height = getHeight(monacoMock, false);
expect(height).toBe(1020);
});
test('when using classic table, limited height > 500 lines to allow scrolling', () => {
const monacoMock = getMonacoMock(1000);
const height = getHeight(monacoMock, false);
expect(height).toBe(5020);
});
});

View file

@ -0,0 +1,32 @@
/*
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
* or more contributor license agreements. Licensed under the Elastic License
* 2.0 and the Server Side Public License, v 1; you may not use this file except
* in compliance with, at your election, the Elastic License 2.0 or the Server
* Side Public License, v 1.
*/
import { monaco } from '@kbn/monaco';
import { MARGIN_BOTTOM, MAX_LINES_CLASSIC_TABLE } from './source';
export function getHeight(editor: monaco.editor.IStandaloneCodeEditor, useDocExplorer: boolean) {
const editorElement = editor?.getDomNode();
if (!editorElement) {
return 0;
}
let result;
if (useDocExplorer) {
// assign a good height filling the available space of the document flyout
const position = editorElement.getBoundingClientRect();
result = window.innerHeight - position.top - MARGIN_BOTTOM;
} else {
// takes care of the classic table, display a maximum of 500 lines
// why not display it all? Due to performance issues when the browser needs to render it all
const lineHeight = editor.getOption(monaco.editor.EditorOption.lineHeight);
const lineCount = editor.getModel()?.getLineCount() || 1;
const displayedLineCount =
lineCount > MAX_LINES_CLASSIC_TABLE ? MAX_LINES_CLASSIC_TABLE : lineCount;
result = editor.getTopForLineNumber(displayedLineCount + 1) + lineHeight;
}
return result > 0 ? result : 0;
}

View file

@ -14,10 +14,11 @@ import { EuiButton, EuiEmptyPrompt, EuiLoadingSpinner, EuiSpacer, EuiText } from
import { i18n } from '@kbn/i18n';
import { useDiscoverServices } from '../../../../utils/use_discover_services';
import { JSONCodeEditorCommonMemoized } from '../../../../components/json_code_editor/json_code_editor_common';
import { SEARCH_FIELDS_FROM_SOURCE } from '../../../../../common';
import { DOC_TABLE_LEGACY, SEARCH_FIELDS_FROM_SOURCE } from '../../../../../common';
import { useEsDocSearch } from '../../../../utils/use_es_doc_search';
import { DataView } from '../../../../../../data_views/common';
import { ElasticRequestState } from '../../../../application/doc/types';
import { getHeight } from './get_height';
interface SourceViewerProps {
id: string;
@ -27,6 +28,12 @@ interface SourceViewerProps {
width?: number;
}
// Ihe number of lines displayed without scrolling used for classic table, which renders the component
// inline limitation was necessary to enable virtualized scrolling, which improves performance
export const MAX_LINES_CLASSIC_TABLE = 500;
// Displayed margin of the code editor to the window bottom when rendered in the document explorer flyout
export const MARGIN_BOTTOM = 25;
export const DocViewerSource = ({
id,
index,
@ -38,6 +45,7 @@ export const DocViewerSource = ({
const [jsonValue, setJsonValue] = useState<string>('');
const { uiSettings } = useDiscoverServices();
const useNewFieldsApi = !uiSettings.get(SEARCH_FIELDS_FROM_SOURCE);
const useDocExplorer = !uiSettings.get(DOC_TABLE_LEGACY);
const [reqState, hit, requestData] = useEsDocSearch({
id,
index,
@ -62,16 +70,18 @@ export const DocViewerSource = ({
return;
}
const lineHeight = editor.getOption(monaco.editor.EditorOption.lineHeight);
const lineCount = editor.getModel()?.getLineCount() || 1;
const height = editor.getTopForLineNumber(lineCount + 1) + lineHeight;
const height = getHeight(editor, useDocExplorer);
if (height === 0) {
return;
}
if (!jsonValue || jsonValue === '') {
editorElement.style.height = '0px';
} else {
editorElement.style.height = `${height}px`;
}
editor.layout();
}, [editor, jsonValue]);
}, [editor, jsonValue, useDocExplorer]);
const loadingState = (
<div className="sourceViewer__loading">