From 2fa6a88a1d7bf8313776bf13c2dda5a0c9b699f6 Mon Sep 17 00:00:00 2001 From: Thomas Sibley Date: Thu, 25 Feb 2021 12:55:23 -0800 Subject: [PATCH] controls/filter: Avoid spread syntax with potentially large arrays MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Push each value individually instead of all at once, which results in more method calls but a much smaller call stack size. Alternatively, Array.concat could be used, but this follows the pattern of surrounding code and avoids reassignment of "options", which would also necessitate removal of the "const" declaration. The /tb/global build has ~277k genotype states, which resulted in a call to Array.push with as many arguments when the spread syntax was used. This blew through the call stack size limit on Chrome with an error like: RangeError: Maximum call stack size exceeded at FilterData.eval [as makeOptions] (filter.js?6bcb:65) at FilterData.render (filter.js?6bcb:100) … Firefox was unaffected, so presumably has a larger limit. Debugging was waylaid for a bit by the assumption that exceeding the call stack size necessarily meant deep recursion, but the lack of a deep stack trace led to the realization that it can also occur when a function's arguments are too many. Resolves #1292. --- src/components/controls/filter.js | 13 ++++++++----- 1 file changed, 8 insertions(+), 5 deletions(-) diff --git a/src/components/controls/filter.js b/src/components/controls/filter.js index 763c2898c..ca2fd197d 100644 --- a/src/components/controls/filter.js +++ b/src/components/controls/filter.js @@ -61,11 +61,14 @@ class FilterData extends React.Component { }); }); if (genotypeSymbol in this.props.activeFilters) { - const sortedGenotypes = [...collectGenotypeStates(this.props.nodes)].sort(); - options.push(...sortedGenotypes.map((o) => ({ - label: `genotype ${o}`, - value: [genotypeSymbol, o] - }))); + Array.from(collectGenotypeStates(this.props.nodes)) + .sort() + .forEach((o) => { + options.push({ + label: `genotype ${o}`, + value: [genotypeSymbol, o] + }) + }); } if (strainSymbol in this.props.activeFilters) { this.props.nodes