rendering performance improvements (#968)

* freeze objects

* component rendering perf work

* use PureComponent where safe

* remove obsolete WorldUtil code

* make brushable histogram a pure component
This commit is contained in:
Bruce Martin
2019-10-04 07:59:22 -07:00
committed by GitHub
parent 700c871e6d
commit 3f2811d9da
12 changed files with 47 additions and 190 deletions
@@ -13,15 +13,21 @@ import * as globals from "../../globals";
import actions from "../../actions";
import { makeContinuousDimensionName } from "../../util/nameCreators";
@connect(state => ({
world: state.world,
scatterplotXXaccessor: state.controls.scatterplotXXaccessor,
scatterplotYYaccessor: state.controls.scatterplotYYaccessor,
continuousSelection: state.continuousSelection,
differential: state.differential,
colorAccessor: state.colors.colorAccessor
}))
class HistogramBrush extends React.Component {
@connect((state, ownProps) => {
const { isObs, isUserDefined, isDiffExp, field } = ownProps;
const myName = makeContinuousDimensionName(
{ isObs, isUserDefined, isDiffExp },
field
);
return {
world: state.world,
scatterplotXXaccessor: state.controls.scatterplotXXaccessor,
scatterplotYYaccessor: state.controls.scatterplotYYaccessor,
continuousSelectionRange: state.continuousSelection[myName],
colorAccessor: state.colors.colorAccessor
};
})
class HistogramBrush extends React.PureComponent {
static getColumn(world, field, clipped = true) {
/*
Return the underlying Dataframe column for our field. By default,
@@ -84,7 +90,7 @@ class HistogramBrush extends React.Component {
}
componentDidUpdate(prevProps) {
const { field, world, continuousSelection } = this.props;
const { field, world } = this.props;
const { x, y, bins, svgRef } = this._histogram;
let { brushXselection, brushX } = this.state;
let forceBrushUpdate = false;
@@ -112,16 +118,8 @@ class HistogramBrush extends React.Component {
if the selection has changed, ensure that the brush correctly reflects
the underlying selection.
*/
if (
forceBrushUpdate ||
continuousSelection !== prevProps.continuousSelection
) {
const { isObs, isUserDefined, isDiffExp } = this.props;
const myName = makeContinuousDimensionName(
{ isObs, isUserDefined, isDiffExp },
field
);
const range = continuousSelection[myName];
const { continuousSelectionRange: range } = this.props;
if (forceBrushUpdate || range !== prevProps.continuousSelectionRange) {
if (brushXselection) {
const selection = d3.brushSelection(brushXselection.node());
if (!range && selection) {
@@ -417,8 +415,8 @@ class HistogramBrush extends React.Component {
isDiffExp
? "histogram-diffexp"
: isUserDefined
? "histogram-user-gene"
: "histogram-continuous-metadata"
? "histogram-user-gene"
: "histogram-continuous-metadata"
}
style={{
padding: globals.leftSidebarSectionPadding,
@@ -76,30 +76,26 @@ class Categories extends React.Component {
>
{/* READ ONLY CATEGORICAL FIELDS */}
{/* this is duplicative but flat, could be abstracted */}
{_.map(
allCategoryNames,
catName =>
!schema.annotations.obsByName[catName].writable ? (
<Category
key={catName}
metadataField={catName}
createAnnoModeActive={createAnnoModeActive}
isUserAnno={false}
/>
) : null
{_.map(allCategoryNames, catName =>
!schema.annotations.obsByName[catName].writable ? (
<Category
key={catName}
metadataField={catName}
createAnnoModeActive={createAnnoModeActive}
isUserAnno={false}
/>
) : null
)}
{/* WRITEABLE FIELDS */}
{_.map(
allCategoryNames,
catName =>
schema.annotations.obsByName[catName].writable ? (
<Category
key={catName}
metadataField={catName}
createAnnoModeActive={createAnnoModeActive}
isUserAnno
/>
) : null
{_.map(allCategoryNames, catName =>
schema.annotations.obsByName[catName].writable ? (
<Category
key={catName}
metadataField={catName}
createAnnoModeActive={createAnnoModeActive}
isUserAnno
/>
) : null
)}
{writableCategoriesEnabled ? (
<div>
+1 -1
View File
@@ -83,7 +83,7 @@ function renderThrottle(callback) {
graphInteractionMode: state.controls.graphInteractionMode,
colorAccessor: state.colors.colorAccessor
}))
class Graph extends React.Component {
class Graph extends React.PureComponent {
computePointPositions = memoize((X, Y, modelTF) => {
/*
compute the model coordinate for each point
@@ -6,7 +6,7 @@ import { World } from "../../util/stateManager";
import { tooltipHoverOpenDelay } from "../../globals";
@connect()
class CellSetButton extends React.Component {
class CellSetButton extends React.PureComponent {
set() {
const {
differential,
@@ -57,7 +57,7 @@ function createProjectionTF(viewportWidth, viewportHeight) {
responsive: state.responsive
};
})
class Scatterplot extends React.Component {
class Scatterplot extends React.PureComponent {
computePointPositions = memoize((X, Y, xScale, yScale) => {
const positions = new Float32Array(2 * X.length);
for (let i = 0, len = X.length; i < len; i += 1) {