Skip to content
This repository has been archived by the owner on Jun 25, 2020. It is now read-only.

perf: faster legacy table chart #385

Merged
merged 12 commits into from Mar 5, 2020

Conversation

ktmud
Copy link
Contributor

@ktmud ktmud commented Feb 29, 2020

This commit tries to optimize the performance of the legacy data table.

  1. Still use the jquery.databables plugin.
  2. Instead of d3 and reactify, we create the DOM with React itself and initialize jquery.DataTables with a useEffect hook.
  3. Removed dependency on dompurify. Now that HTML tags will be rendered as plain text (by React) instead of innerHTML.
  4. Removed a couple of not-so-popular features. See notes below.
  5. Added a script to build only specific plugin for faster development.
  6. Restyled the pagination so it looks nicer in dashboards.

Plus some minor changes to fix linting and building.

Related: apache/superset#9234

Screenshots

Tested with a ~10,000 rows, 7 columns table in Superset, pagination enabled:

Before

legacy-table--old

Takes about 6 secs to load.

Snip20200303_3

After

legacy-table--new

Takes only 3 secs to load!

Snip20200303_4

馃弳 Enhancements

@ktmud ktmud requested a review from a team as a code owner February 29, 2020 06:34
@netlify
Copy link

netlify bot commented Feb 29, 2020

Deploy preview for superset-ui-plugins ready!

Built with commit 2c903f3

https://deploy-preview-385--superset-ui-plugins.netlify.com

@ktmud ktmud force-pushed the react-legacy-table branch 2 times, most recently from e0ad5ef to 1c1f41d Compare February 29, 2020 06:58
Copy link
Contributor Author

@ktmud ktmud left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Some notes.

This commit tries to optimize the performance of the legacy data table.

1. Converting everything to Typescript.
2. Create a native React component instead of `reactify` (although all
   DOM operaions still happen in the jQuery.DataTables plugin.
3. Remove dependency on d3, optimize how bars are rendered.

Plus some minor changes to fix linting and building.

Also added a script to build only specific plugin for faster
development.
Unfortunately jquery.datatables uses innerHTML to create cell content,
and all rows are created even with pagination.

https://github.com/DataTables/DataTables/blob/83657a29e33ce93ee940ce25684940eb3acb2913/media/js/jquery.dataTables.js#L3113-L3117

This is slow and insecure. We are reverting to DOM data source as in
previous implementation, but instead of using D3 to create the table rows,
we use React. This also renders `dompurify.sanitize` unnecessary since
React will take care of it.
Copy link
Collaborator

@kristw kristw left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Removed dependency on dompurify. Now that HTML tags will be rendered as plain text (by React) instead of innerHTML.

There are columns values that are html strings, such as html links. You would need dangerouslySetInnerHTML and dompurify or use interweave.

@kristw
Copy link
Collaborator

kristw commented Mar 2, 2020

image

Could we add bottom padding for the pagination?
Also, could you share a screenshot of how does it look in Superset? I think Superset override some css and the table may look slightly different.

Also

1. improve height adjustment
2. add page size control to storybook
3. hide rows from later pages at initial rendering
@kristw
Copy link
Collaborator

kristw commented Mar 3, 2020

The build seems to be broken on xss

@ktmud
Copy link
Contributor Author

ktmud commented Mar 3, 2020

Addition information on js-xss vs dompurify, on the same 10k row sample data in Storybook, it takes ~12 secs for dompurify to finish rendering React DOM nodes and 3.5 secs for js-xss.

DOMPurify:
image

xss:
image

Plus minor variable name and comment update
@kristw
Copy link
Collaborator

kristw commented Mar 3, 2020

  • Code looks good. Some eslint errors breaking ci.
  • Have to do something with the title.

legacy_-__plugin-chart-table___TableChartPlugin-_Big_Table_鈰卂Storybook

@codecov
Copy link

codecov bot commented Mar 4, 2020

Codecov Report

Merging #385 into master will increase coverage by <.01%.
The diff coverage is 0%.

Impacted file tree graph

@@            Coverage Diff            @@
##           master    #385      +/-   ##
=========================================
+ Coverage    1.47%   1.48%   +<.01%     
=========================================
  Files         186     185       -1     
  Lines        5824    5805      -19     
  Branches      342     370      +28     
=========================================
  Hits           86      86              
+ Misses       5726    5707      -19     
  Partials       12      12
Impacted Files Coverage 螖
...ui-legacy-plugin-chart-table/src/transformProps.ts 0% <0%> (酶)
...set-ui-preset-chart-xy/src/encodeable/AxisAgent.ts 0% <0%> (酶) 猬嗭笍
...i-legacy-plugin-chart-table/src/ReactDataTable.tsx 0% <0%> (酶)
...superset-ui-legacy-plugin-chart-table/src/index.ts 0% <0%> (酶)

Continue to review full report at Codecov.

Legend - Click here to learn more
螖 = absolute <relative> (impact), 酶 = not affected, ? = missing data
Powered by Codecov. Last update bb7ef62...2c903f3. Read the comment docs.

Copy link
Collaborator

@kristw kristw left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

just a few nits

@ktmud ktmud changed the title feat: faster legacy table chart perf: faster legacy table chart Mar 4, 2020
@kristw kristw merged commit 8b1a7ac into apache-superset:master Mar 5, 2020
ktmud added a commit to ktmud/superset that referenced this pull request Mar 6, 2020
Upgrade table chart `@superset-ui/legacy-plugins-chart-table`
to apache-superset/superset-ui-plugins#385
kristw pushed a commit to apache/superset that referenced this pull request Mar 6, 2020
* perf(table-chart): upgrade to 0.11.6

Upgrade table chart `@superset-ui/legacy-plugins-chart-table`
to apache-superset/superset-ui-plugins#385

* refactor: use ternary instead of if

* fix: rename variables
nytai pushed a commit to preset-io/superset-ui-plugins that referenced this pull request Apr 27, 2020
* feat: faster legacy table chart

This commit tries to optimize the performance of the legacy data table.

1. Converting everything to Typescript.
2. Create a native React component instead of `reactify` (although all
   DOM operaions still happen in the jQuery.DataTables plugin.
3. Remove dependency on d3, optimize how bars are rendered.

Plus some minor changes to fix linting and building.

Also added a script to build only specific plugin for faster
development.

* feat(legacy-table-chart): use React to render DOM

Unfortunately jquery.datatables uses innerHTML to create cell content,
and all rows are created even with pagination.

https://github.com/DataTables/DataTables/blob/83657a29e33ce93ee940ce25684940eb3acb2913/media/js/jquery.dataTables.js#L3113-L3117

This is slow and insecure. We are reverting to DOM data source as in
previous implementation, but instead of using D3 to create the table rows,
we use React. This also renders `dompurify.sanitize` unnecessary since
React will take care of it.

* feat(legacy-table-chart): support html in data cells

Also

1. improve height adjustment
2. add page size control to storybook
3. hide rows from later pages at initial rendering

* fix(legacy-data-table): minor formatting fixes

* chore(legacy-table): add xss dependency

Plus minor variable name and comment update

* fix(legacy-table): linting errors

* refactor(legacy-table): more predictable metric labels

* feat(legacy-table): also display title for percent metric

* fix(legacy-table): typos, var names, etc

* docs: update notes for metric.label

* refactor(legacy-table): upgrade number-format

* fix(legacy-table): upgrade dependency for storybook and yarn
lexisstv pushed a commit to utrace-ltd/superset-ui-plugins that referenced this pull request Jun 1, 2020
* feat: faster legacy table chart

This commit tries to optimize the performance of the legacy data table.

1. Converting everything to Typescript.
2. Create a native React component instead of `reactify` (although all
   DOM operaions still happen in the jQuery.DataTables plugin.
3. Remove dependency on d3, optimize how bars are rendered.

Plus some minor changes to fix linting and building.

Also added a script to build only specific plugin for faster
development.

* feat(legacy-table-chart): use React to render DOM

Unfortunately jquery.datatables uses innerHTML to create cell content,
and all rows are created even with pagination.

https://github.com/DataTables/DataTables/blob/83657a29e33ce93ee940ce25684940eb3acb2913/media/js/jquery.dataTables.js#L3113-L3117

This is slow and insecure. We are reverting to DOM data source as in
previous implementation, but instead of using D3 to create the table rows,
we use React. This also renders `dompurify.sanitize` unnecessary since
React will take care of it.

* feat(legacy-table-chart): support html in data cells

Also

1. improve height adjustment
2. add page size control to storybook
3. hide rows from later pages at initial rendering

* fix(legacy-data-table): minor formatting fixes

* chore(legacy-table): add xss dependency

Plus minor variable name and comment update

* fix(legacy-table): linting errors

* refactor(legacy-table): more predictable metric labels

* feat(legacy-table): also display title for percent metric

* fix(legacy-table): typos, var names, etc

* docs: update notes for metric.label

* refactor(legacy-table): upgrade number-format

* fix(legacy-table): upgrade dependency for storybook and yarn
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

3 participants