diff --git a/src/components/waveform/waveform.jsx b/src/components/waveform/waveform.jsx
index 1b2abe96e..48a0a4935 100644
--- a/src/components/waveform/waveform.jsx
+++ b/src/components/waveform/waveform.jsx
@@ -2,52 +2,65 @@ import React from 'react';
import PropTypes from 'prop-types';
import styles from './waveform.css';
-const Waveform = props => {
- const {
- width,
- height,
- data
- } = props;
+// Waveform is expensive to compute, make sure it only updates when data does
+// by using PureComponent. In future can be changed back to function with React.memo
+// eslint-disable-next-line react/prefer-stateless-function
+class Waveform extends React.PureComponent {
+ render () {
+ const {
+ width,
+ height,
+ data
+ } = this.props;
- const cappedData = [0, ...data, 0];
+ // Never want a density of points higher than the number of pixels
+ // This is very conservative, could be far fewer points because of curve smoothing.
+ // Drawing too many points seems to cause an explosion in browser
+ // composite time when animating the playhead
+ const takeEveryN = Math.ceil(data.length / width);
- const points = [
- ...cappedData.map((v, i) =>
- [width * i / cappedData.length, height * v / 2]
- ),
- ...cappedData.reverse().map((v, i) =>
- [width * (cappedData.length - i - 1) / cappedData.length, -height * v / 2]
- )
- ];
+ const filteredData = takeEveryN === 1 ? data :
+ data.filter((_, i) => i % takeEveryN === 0);
- const pathComponents = points.map(([x, y], i) => {
- const [nx, ny] = points[i < points.length - 1 ? i + 1 : 0];
- return `Q${x} ${y} ${(x + nx) / 2} ${(y + ny) / 2}`;
- });
+ const cappedData = [0, ...filteredData, 0];
- return (
-
- );
-};
+
+
+
+
+ );
+ }
+}
Waveform.propTypes = {
data: PropTypes.arrayOf(PropTypes.number),