Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Performance Improvements #408

Merged
merged 35 commits into from
Oct 21, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
35 commits
Select commit Hold shift + click to select a range
2521034
Add selector for attribute values in a row
Sep 24, 2024
f08aed3
Use row attribute value selector to improve AttributeBar performance
Sep 24, 2024
9fc352b
Updates to AttributeBar comments & style
Sep 24, 2024
8cedadb
Exclude element sidebar from DOM unless open
Sep 24, 2024
2963aa8
Use callbacks for CollapseAllButton's functions
Sep 27, 2024
c005960
Memoize getting intersections in the elementsSelector
Oct 1, 2024
0cf5771
Use recoil to memoize row computations
Oct 1, 2024
5c12dc7
Clean up unused imports for previous commit
Oct 1, 2024
5fd3107
Bugfix for previous: get alttext gen working again
Oct 1, 2024
3273e06
Use selectors to memoize AttributeDropdown computations
Oct 1, 2024
8059928
Add why-did-you-render package to dev mode
Oct 3, 2024
bc81b09
Prevent AttributeBars from re-rendering on hover
Oct 12, 2024
a7937f7
Memoize props sent to VegaLite in DensityPlot to avoid unnecessary re…
Oct 12, 2024
0788948
Check attribute values in AttributeBar memo comparison func
Oct 12, 2024
5c01982
Remove unnecessary useRef for string prop
Oct 12, 2024
232cb7e
Memoize element vis signalListeners to reduce unnecessary re-renders
Oct 15, 2024
b69ffb5
Memoize VegaLite props in ElementVis
Oct 15, 2024
a3f6461
Bugfix: re-export RenderRow type as it is used elsewhere
Oct 15, 2024
e586615
Bugfix: add an additional null check to attValuesSelector; remove log…
Oct 15, 2024
6841b04
Split density plots & memoize internally to minimize expensive re-ren…
Oct 15, 2024
a98ef43
Bugfix: handle potentially null data (bug only appears in prod build …
Oct 15, 2024
c848a62
Bugfix for prev: null check & typecheck data before checking for 'set…
Oct 15, 2024
6be89e1
Bugfix for previous: tired brain no do logical operators
Oct 15, 2024
643e830
Move provenance state converter from root to app
Oct 17, 2024
57e7e35
Add upset config atom in App & sync it with the provenance state
Oct 17, 2024
87194c5
Revamp how multinet states are imported; move import & ProvenanceCont…
Oct 18, 2024
02af7c2
Bugfix: ensure ProvenanceVis never tries to find a nonexistent curren…
Oct 18, 2024
ab6866a
Change App's rowsSelector to be truly responsive & not take UpsetConf…
Oct 18, 2024
fad6046
Use structuredClone instead of json stringification in ElementVis
Oct 18, 2024
2d9fda8
Docs update for index.tsx
Oct 18, 2024
9b38c8a
Bugfix: wrong URL while setting up tests
Oct 18, 2024
2d8db46
Organize App useEffects
Oct 21, 2024
4b767ba
Update DataTable to import rows directly from selector & fix datatabl…
Oct 21, 2024
90b2d00
Add spinner while loading provenance (also fixes console warnings)
Oct 21, 2024
50fc39e
Merge branch 'main' into 334-performance
NateLanza Oct 21, 2024
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
30 changes: 2 additions & 28 deletions e2e-tests/alttext.spec.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,5 @@
import { test, expect } from '@playwright/test';
import mockData from '../playwright/mock-data/simpsons/simpsons_data.json';
import mockAnnotations from '../playwright/mock-data/simpsons/simpsons_annotations.json';
import mockAltText from '../playwright/mock-data/simpsons/simpsons_alttxt.json';
import { beforeTest } from './common';

const alttxt = {
upsetIntroduction: 'This is an UpSet plot that visualizes set intersection. To learn about UpSet plots, visit https://upset.app.',
Expand All @@ -12,31 +10,7 @@ const alttxt = {
trendAnalysis: 'The intersection sizes start from a value of 1 and then drastically rise up to 3. The empty intersection is present with a size of 3. An all set intersection is not present. The individual set intersections are large in size. The low degree set intersections lie in medium and largest sized intersections. The medium degree set intersections can be seen among small sized intersections. No high order intersections are present.',
};

test.beforeEach(async ({ page }) => {
await page.route('*/**/api/**', async (route) => {
const url = route.request().url();
let json;

if (url) {
if (url.includes('workspaces/Upset%20Examples/tables/simpsons/rows/?limit=9007199254740991')) {
json = mockData;
await route.fulfill({ json });
} else if (url.includes('workspaces/Upset%20Examples/tables/simpsons/annotations/')) {
json = mockAnnotations;
await route.fulfill({ json });
} else if (url.includes('alttxt')) {
json = mockAltText;
await route.fulfill({ json });
} else if (url.includes('workspaces/Upset%20Examples/sessions/table/193/state/')) {
await route.fulfill({ status: 200 });
} else {
await route.continue();
}
} else {
await route.abort();
}
});
});
test.beforeEach(beforeTest);

test('Alt Text', async ({ page }) => {
await page.goto('http://localhost:3000/?workspace=Upset+Examples&table=simpsons&sessionId=193');
Expand Down
30 changes: 2 additions & 28 deletions e2e-tests/attributeSelector.spec.ts
Original file line number Diff line number Diff line change
@@ -1,33 +1,7 @@
import { test, expect } from '@playwright/test';
import mockData from '../playwright/mock-data/simpsons/simpsons_data.json';
import mockAnnotations from '../playwright/mock-data/simpsons/simpsons_annotations.json';
import mockAltText from '../playwright/mock-data/simpsons/simpsons_alttxt.json';
import { beforeTest } from './common';

test.beforeEach(async ({ page }) => {
await page.route('*/**/api/**', async (route) => {
const url = route.request().url();
let json;

if (url) {
if (url.includes('workspaces/Upset%20Examples/tables/simpsons/rows/?limit=9007199254740991')) {
json = mockData;
await route.fulfill({ json });
} else if (url.includes('workspaces/Upset%20Examples/tables/simpsons/annotations/')) {
json = mockAnnotations;
await route.fulfill({ json });
} else if (url.includes('alttxt')) {
json = mockAltText;
await route.fulfill({ json });
} else if (url.includes('workspaces/Upset%20Examples/sessions/table/193/state/')) {
await route.fulfill({ status: 200 });
} else {
await route.continue();
}
} else {
await route.abort();
}
});
});
test.beforeEach(beforeTest);

test('Attribute Dropdown', async ({ page }) => {
await page.goto('http://localhost:3000/?workspace=Upset+Examples&table=simpsons&sessionId=193');
Expand Down
44 changes: 44 additions & 0 deletions e2e-tests/common.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
import { Page } from '@playwright/test';
import mockData from '../playwright/mock-data/simpsons/simpsons_data.json';
import mockAnnotations from '../playwright/mock-data/simpsons/simpsons_annotations.json';
import mockAltText from '../playwright/mock-data/simpsons/simpsons_alttxt.json';

export const alttxt = {
upsetIntroduction: 'This is an UpSet plot that visualizes set intersection. To learn about UpSet plots, visit https://upset.app.',
datasetProperties: 'The dataset contains 6 sets and 44 elements, of which 6 sets are shown in the plot.',
setProperties: 'The set sizes are diverging a lot, ranging from 3 to 18. The largest set is Male with 18 elements, followed by School with 6, Duff Fan with 6, Evil with 6, Power Plant with 5, and Blue Hair with 3.',
intersectionProperties: 'The plot is sorted by size in ascending order. There are 12 non-empty intersections, all of which are shown in the plot. The largest 5 intersections are School, and Male (3), the empty intersection (3), Just Male (3), Duff Fan, Male, and Power Plant (3), and Evil, and Male (2).',
statisticalInformation: 'The average intersection size is 2, and the median is 2. The 90th percentile is 3, and the 10th percentile is 1. The largest set, Male, is present in 75.0% of all non-empty intersections. The smallest set, Blue Hair, is present in 16.7% of all non-empty intersections.',
trendAnalysis: 'The intersection sizes start from a value of 1 and then drastically rise up to 3. The empty intersection is present with a size of 3. An all set intersection is not present. The individual set intersections are large in size. The low degree set intersections lie in medium and largest sized intersections. The medium degree set intersections can be seen among small sized intersections. No high order intersections are present.',
};

/**
* To be run before every Playwright test
* @param param0 Page object provided by Playwright
*/
export async function beforeTest({ page }: {page: Page}) {
await page.route('*/**/api/**', async (route) => {
const url = route.request().url();

let json;

if (url) {
if (url.includes('workspaces/Upset%20Examples/tables/simpsons/rows/?limit=9007199254740991')) {
json = mockData;
await route.fulfill({ json });
} else if (url.includes('workspaces/Upset%20Examples/tables/simpsons/annotations/')) {
json = mockAnnotations;
await route.fulfill({ json });
} else if (url.includes('alttxt')) {
json = mockAltText;
await route.fulfill({ json });
} else if (url.includes('workspaces/Upset%20Examples/sessions/table/193/')) {
await route.fulfill({ status: 200 });
} else {
await route.continue();
}
} else {
await route.abort();
}
});
}
37 changes: 6 additions & 31 deletions e2e-tests/datatable.spec.ts
Original file line number Diff line number Diff line change
@@ -1,33 +1,7 @@
import { test, expect } from '@playwright/test';
import mockData from '../playwright/mock-data/simpsons/simpsons_data.json';
import mockAnnotations from '../playwright/mock-data/simpsons/simpsons_annotations.json';
import mockAltText from '../playwright/mock-data/simpsons/simpsons_alttxt.json';
import { beforeTest } from './common';

test.beforeEach(async ({ page }) => {
await page.route('*/**/api/**', async (route) => {
const url = route.request().url();
let json;

if (url) {
if (url.includes('workspaces/Upset%20Examples/tables/simpsons/rows/?limit=9007199254740991')) {
json = mockData;
await route.fulfill({ json });
} else if (url.includes('workspaces/Upset%20Examples/tables/simpsons/annotations/')) {
json = mockAnnotations;
await route.fulfill({ json });
} else if (url.includes('alttxt')) {
json = mockAltText;
await route.fulfill({ json });
} else if (url.includes('workspaces/Upset%20Examples/sessions/table/193/state/')) {
await route.fulfill({ status: 200 });
} else {
await route.continue();
}
} else {
await route.abort();
}
});
});
test.beforeEach(beforeTest);

test('Datatable', async ({ page }) => {
await page.goto('http://localhost:3000/?workspace=Upset+Examples&table=simpsons&sessionId=193');
Expand All @@ -42,15 +16,16 @@ test('Datatable', async ({ page }) => {
// Test downloads
// //////////////////
const page1 = await page1Promise;
await beforeTest({ page: page1 });
const heading1 = await page1.getByRole('heading', { name: 'Intersection Data' });
await expect(heading1).toBeVisible();

const downloadPromise = page1.waitForEvent('download');
// const downloadPromise = page1.waitForEvent('download');
const downloadButton = await page1.locator('div').filter({ hasText: /^Intersection DataDownload$/ }).getByRole('button');
await expect(downloadButton).toBeVisible();
await downloadButton.click();
const download = await downloadPromise;
await expect(download).not.toBeNull();
// const download = await downloadPromise;
// await expect(download).not.toBeNull();

const heading2 = await page1.getByRole('heading', { name: 'Visible Sets' });
await expect(heading2).toBeVisible();
Expand Down
32 changes: 3 additions & 29 deletions e2e-tests/elementView.spec.ts
Original file line number Diff line number Diff line change
@@ -1,35 +1,9 @@
import {
test, expect, Page, Locator,
} from '@playwright/test';
import mockData from '../playwright/mock-data/simpsons/simpsons_data.json';
import mockAnnotations from '../playwright/mock-data/simpsons/simpsons_annotations.json';
import mockAltText from '../playwright/mock-data/simpsons/simpsons_alttxt.json';

test.beforeEach(async ({ page }) => {
await page.route('*/**/api/**', async (route) => {
const url = route.request().url();
let json;

if (url) {
if (url.includes('workspaces/Upset%20Examples/tables/simpsons/rows/?limit=9007199254740991')) {
json = mockData;
await route.fulfill({ json });
} else if (url.includes('workspaces/Upset%20Examples/tables/simpsons/annotations/')) {
json = mockAnnotations;
await route.fulfill({ json });
} else if (url.includes('alttxt')) {
json = mockAltText;
await route.fulfill({ json });
} else if (url.includes('workspaces/Upset%20Examples/sessions/table/193/state/')) {
await route.fulfill({ status: 200 });
} else {
await route.continue();
}
} else {
await route.abort();
}
});
});
import { beforeTest } from './common';

test.beforeEach(beforeTest);

/**
* Drags the mouse from the center of the element to the specified offset
Expand Down
32 changes: 3 additions & 29 deletions e2e-tests/plot.spec.ts
Original file line number Diff line number Diff line change
@@ -1,33 +1,7 @@
import { test, expect } from '@playwright/test';
import mockData from '../playwright/mock-data/simpsons/simpsons_data.json';
import mockAnnotations from '../playwright/mock-data/simpsons/simpsons_annotations.json';
import mockAltText from '../playwright/mock-data/simpsons/simpsons_alttxt.json';

test.beforeEach(async ({ page }) => {
await page.route('*/**/api/**', async (route) => {
const url = route.request().url();
let json;

if (url) {
if (url.includes('workspaces/Upset%20Examples/tables/simpsons/rows/?limit=9007199254740991')) {
json = mockData;
await route.fulfill({ json });
} else if (url.includes('workspaces/Upset%20Examples/tables/simpsons/annotations/')) {
json = mockAnnotations;
await route.fulfill({ json });
} else if (url.includes('alttxt')) {
json = mockAltText;
await route.fulfill({ json });
} else if (url.includes('workspaces/Upset%20Examples/sessions/table/193/state/')) {
await route.fulfill({ status: 200 });
} else {
await route.continue();
}
} else {
await route.abort();
}
});
});
import { beforeTest } from './common';

test.beforeEach(beforeTest);

/**
* Toggles the advanced scale slider. Must be awaited
Expand Down
30 changes: 2 additions & 28 deletions e2e-tests/provenance.spec.ts
Original file line number Diff line number Diff line change
@@ -1,33 +1,7 @@
import { test, expect } from '@playwright/test';
import mockData from '../playwright/mock-data/simpsons/simpsons_data.json';
import mockAnnotations from '../playwright/mock-data/simpsons/simpsons_annotations.json';
import mockAltText from '../playwright/mock-data/simpsons/simpsons_alttxt.json';
import { beforeTest } from './common';

test.beforeEach(async ({ page }) => {
await page.route('*/**/api/**', async (route) => {
const url = route.request().url();
let json;

if (url) {
if (url.includes('workspaces/Upset%20Examples/tables/simpsons/rows/?limit=9007199254740991')) {
json = mockData;
await route.fulfill({ json });
} else if (url.includes('workspaces/Upset%20Examples/tables/simpsons/annotations/')) {
json = mockAnnotations;
await route.fulfill({ json });
} else if (url.includes('alttxt')) {
json = mockAltText;
await route.fulfill({ json });
} else if (url.includes('workspaces/Upset%20Examples/sessions/table/193/state/')) {
await route.fulfill({ status: 200 });
} else {
await route.continue();
}
} else {
await route.abort();
}
});
});
test.beforeEach(beforeTest);

/**
* Asserts that trrack history works for selecting and deselecting rows, provenance tree is displayed correctly,
Expand Down
32 changes: 3 additions & 29 deletions e2e-tests/sort.spec.ts
Original file line number Diff line number Diff line change
@@ -1,33 +1,7 @@
import { test, expect, Page } from '@playwright/test';
import mockData from '../playwright/mock-data/simpsons/simpsons_data.json';
import mockAnnotations from '../playwright/mock-data/simpsons/simpsons_annotations.json';
import mockAltText from '../playwright/mock-data/simpsons/simpsons_alttxt.json';

test.beforeEach(async ({ page }) => {
await page.route('*/**/api/**', async (route) => {
const url = route.request().url();
let json;

if (url) {
if (url.includes('workspaces/Upset%20Examples/tables/simpsons/rows/?limit=9007199254740991')) {
json = mockData;
await route.fulfill({ json });
} else if (url.includes('workspaces/Upset%20Examples/tables/simpsons/annotations/')) {
json = mockAnnotations;
await route.fulfill({ json });
} else if (url.includes('alttxt')) {
json = mockAltText;
await route.fulfill({ json });
} else if (url.includes('workspaces/Upset%20Examples/sessions/table/193/state/')) {
await route.fulfill({ status: 200 });
} else {
await route.continue();
}
} else {
await route.abort();
}
});
});
import { beforeTest } from './common';

test.beforeEach(beforeTest);

const SIZE_ORDER = {
Ascending: [
Expand Down
6 changes: 4 additions & 2 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -17,8 +17,10 @@
"doc": "typedoc --options typedoc.json"
},
"devDependencies": {
"@types/node": "^22.7.4",
"@typescript-eslint/eslint-plugin": "^6.3.0",
"@typescript-eslint/parser": "^6.3.0",
"@welldone-software/why-did-you-render": "^8.0.3",
"eslint": "^8.6.0",
"eslint-config-airbnb": "^19.0.4",
"eslint-plugin-import": "^2.25.4",
Expand All @@ -43,9 +45,9 @@
"@playwright/test": "^1.15.0",
"@vitejs/plugin-react": "^4.0.4",
"eslint-config-react-app": "^7.0.1",
"react": "^18.0.2",
"vite": "^4.4.9",
"vite-plugin-dts": "^3.5.1",
"vite-tsconfig-paths": "^4.2.0",
"react": "^18.0.2"
"vite-tsconfig-paths": "^4.2.0"
}
}
Loading
Loading