From 3ee7f6f5e964d407d940ad431e62e5ed3a63e485 Mon Sep 17 00:00:00 2001 From: "JUST.in DO IT" Date: Mon, 17 Apr 2023 09:49:15 -0700 Subject: [PATCH] fix(sqllab): rendering performance regression (#23695) (cherry picked from commit c197bf9e6db85a76d8118a4ec11a83ca2f6aad6d) --- .../components/SqlEditor/SqlEditor.test.jsx | 49 +++++++++++++++---- .../src/SqlLab/components/SqlEditor/index.jsx | 3 +- 2 files changed, 41 insertions(+), 11 deletions(-) diff --git a/superset-frontend/src/SqlLab/components/SqlEditor/SqlEditor.test.jsx b/superset-frontend/src/SqlLab/components/SqlEditor/SqlEditor.test.jsx index 9dcc37fdd188a..99551b9d41e81 100644 --- a/superset-frontend/src/SqlLab/components/SqlEditor/SqlEditor.test.jsx +++ b/superset-frontend/src/SqlLab/components/SqlEditor/SqlEditor.test.jsx @@ -32,6 +32,8 @@ import { import AceEditorWrapper from 'src/SqlLab/components/AceEditorWrapper'; import SouthPane from 'src/SqlLab/components/SouthPane'; import SqlEditor from 'src/SqlLab/components/SqlEditor'; +import { setupStore } from 'src/views/store'; +import { reducers } from 'src/SqlLab/reducers'; import QueryProvider from 'src/views/QueryProvider'; import waitForComponentToPaint from 'spec/helpers/waitForComponentToPaint'; import { @@ -40,16 +42,21 @@ import { table, defaultQueryEditor, } from 'src/SqlLab/fixtures'; +import SqlEditorLeftBar from 'src/SqlLab/components/SqlEditorLeftBar'; jest.mock('src/components/AsyncAceEditor', () => ({ ...jest.requireActual('src/components/AsyncAceEditor'), - FullSQLEditor: props => ( -
{JSON.stringify(props)}
+ FullSQLEditor: ({ onChange, onBlur, value }) => ( + ), })); -jest.mock('src/SqlLab/components/SqlEditorLeftBar', () => () => ( -
-)); +jest.mock('src/SqlLab/components/SqlEditorLeftBar', () => jest.fn()); const MOCKED_SQL_EDITOR_HEIGHT = 500; @@ -59,7 +66,7 @@ fetchMock.post('glob:*/sqllab/execute/*', { result: [] }); const middlewares = [thunk]; const mockStore = configureStore(middlewares); -const store = mockStore({ +const mockInitialState = { ...initialState, sqlLab: { ...initialState.sqlLab, @@ -82,7 +89,8 @@ const store = mockStore({ dbId: 'dbid1', }, }, -}); +}; +const store = mockStore(mockInitialState); const setup = (props = {}, store) => render(, { @@ -103,6 +111,13 @@ describe('SqlEditor', () => { displayLimit: 100, }; + beforeEach(() => { + SqlEditorLeftBar.mockClear(); + SqlEditorLeftBar.mockImplementation(() => ( +
+ )); + }); + const buildWrapper = (props = {}) => mount( @@ -136,6 +151,21 @@ describe('SqlEditor', () => { expect(await findByTestId('react-ace')).toBeInTheDocument(); }); + it('avoids rerendering EditorLeftBar while typing', async () => { + const sqlLabStore = setupStore({ + initialState: mockInitialState, + rootReducers: reducers, + }); + const { findByTestId } = setup(mockedProps, sqlLabStore); + const editor = await findByTestId('react-ace'); + const sql = 'select *'; + const renderCount = SqlEditorLeftBar.mock.calls.length; + expect(SqlEditorLeftBar).toHaveBeenCalledTimes(renderCount); + fireEvent.change(editor, { target: { value: sql } }); + // Verify the rendering regression + expect(SqlEditorLeftBar).toHaveBeenCalledTimes(renderCount); + }); + it('renders sql from unsaved change', async () => { const expectedSql = 'SELECT updated_column\nFROM updated_table\nWHERE'; const { findByTestId } = setup( @@ -167,9 +197,8 @@ describe('SqlEditor', () => { }), ); - expect(await findByTestId('react-ace')).toHaveTextContent( - JSON.stringify({ value: expectedSql }).slice(1, -1), - ); + const editor = await findByTestId('react-ace'); + expect(editor).toHaveValue(expectedSql); }); it('render a SouthPane', async () => { diff --git a/superset-frontend/src/SqlLab/components/SqlEditor/index.jsx b/superset-frontend/src/SqlLab/components/SqlEditor/index.jsx index 83286e588136f..d23c3099208eb 100644 --- a/superset-frontend/src/SqlLab/components/SqlEditor/index.jsx +++ b/superset-frontend/src/SqlLab/components/SqlEditor/index.jsx @@ -26,7 +26,7 @@ import React, { useCallback, } from 'react'; import { CSSTransition } from 'react-transition-group'; -import { useDispatch, useSelector } from 'react-redux'; +import { shallowEqual, useDispatch, useSelector } from 'react-redux'; import PropTypes from 'prop-types'; import Split from 'react-split'; import { css, FeatureFlag, styled, t, useTheme } from '@superset-ui/core'; @@ -230,6 +230,7 @@ const SqlEditor = ({ hideLeftBar, }; }, + shallowEqual, ); const [height, setHeight] = useState(0);