Hi all:
On each keystroke trigger an action, reduce the state to compensate for the new character, but observe that re-rendering becomes laggy. You can watch the lag here.
Provider >
App >
Dashboard >
Home {connected, but passes no state/props through children. why? to dispatch an auth middleware event on load} >
ProjectDashboard >
ProjectController {connected, passes a single object of state, ~small} >
Project {dumb}
a third component is connected, but is not rendered. its a layout component for login, and I don't believe to be associated with the issue at hand.
I've profiled while punching keys into the field. It's the name field shown. It looks like a ton of time is being spent in validate and doing deepEquals in shouldComponentUpdate.


Would love some tips! Thanks!
What is contained in props on your Project component? It looks like you've got something big in your props that's being validated.
I'd recommend grabbing the react devtools, as it makes viewing this stuff much easier.
Could you post your Project component's code?
I get similar performance issues with forms when I'm using redux-devtools.
Have you tried out reselect? It'll memoize selectors, which should help you avoid re-calculating stuff when data changes.
Aside from that, pulling in react-pure-render might help as well.
hi @timdorr @cesarandreu. thanks for your willingness to add ideas!
validation step?It's a known issue with Redux DevTools and if you'd like to see it fixed, a good first step is to contribute tests. You won't have this issue in production.
There's a PR attempted to fix it: https://github.com/gaearon/redux-devtools/pull/133
Can you please test whether it improves the situation?
This is fixed in [email protected].
Performing an action with DevTools open was O(n), now it's O(1).
thanks @gaearon! will try at my next opportunity
I'm still seeing a bit of a lag when carrying out rapid state changes on the latest version (in this scenario it's a keydown event for an autocomplete). My suspicion is that it may be due to the number of LogMonitor nodes it has to update in quick succession. I created a very simple custom monitor which just logged the action and the problem seemed to go away. If anyone else is experiencing this I think the resolution may be one of the following..
(I can hopefully help out with a resolution, I wonder if this issue could be transferred to redux-devtools)
Oh, I see now. There hasn't been much effort to optimize LogMonitor so I wouldn't be surprised if there are many low hanging fruit there.
Adding a shouldComponentUpdate that does a shallowEqual for LogMonitorEntry seems to greatly improve responsiveness for me when using redux-forms (goes from unusable to usable). I'm not entirely sure if it's safe to just do a shallowEqual though... so far seems ok.
@davecoates Then please file an issue (or, better, a PR) to add it!
@davecoates The issue I found with redux-form is that onChange', 'onBlur', 'onFocus', 'onUpdate',
'handleChange', 'handleBlur', 'handleFocus' on field prop change on every render. I put a shouldComponentUpdate on my Widget component (that render a input, select or whatever) to ignore changes of those functions. This is what I use:
const IGNORE_FUNCTIONS = [
'onChange', 'onBlur', 'onFocus', 'onUpdate',
'handleChange', 'handleBlur', 'handleFocus']
export function shallowEqual(objA, objB) {
if (objA === objB) {
return true
}
if (typeof objA !== 'object' || objA === null ||
typeof objB !== 'object' || objB === null) {
return false
}
const keysA = Object.keys(objA)
const keysB = Object.keys(objB)
if (keysA.length !== keysB.length) {
return false
}
// Test for A's keys different from B.
const bHasOwnProperty = Object.prototype.hasOwnProperty.bind(objB)
for (let i = 0; i < keysA.length; i++) {
if (!bHasOwnProperty(keysA[i])) {
return false
}
if (keysA[i] === 'field') {
if (!shallowEqual(objA[keysA[i]], objB[keysA[i]])) {
return false
}
} else if (typeof objA[keysA[i]] === 'function' &&
IGNORE_FUNCTIONS.indexOf(keysA[i]) > -1 ) {
// don't compare function is the IGNORE_FUNCTIONS array
continue
} else if (objA[keysA[i]] !== objB[keysA[i]]) {
// console.log('rerender because of prop named:')
// console.log(keysA[i])
// console.log('before:')
// console.log(objA[keysA[i]])
// console.log('after:')
// console.log(objB[keysA[i]])
return false
}
}
return true
}
export default function shouldPureComponentUpdate(nextProps, nextState) {
return !shallowEqual(this.props, nextProps) ||
!shallowEqual(this.state, nextState)
}
class Widget extends Component {
static propTypes = {
field: PropTypes.object.isRequired,
}
shouldComponentUpdate = shouldPureComponentUpdate
}
@vincentfretin Please file an issue in Redux Form. You shouldn't have to do these optimizations by hand.
Redux DevTools 3.0 Beta 2 should vastly improve performance.
Please help test it: https://github.com/gaearon/redux-devtools/releases/tag/v3.0.0-beta-2
I'm still seeing the same issue in 3.0.5 for onChange.
@stanleycyang Please share a project reproducing the problem.
Edit: this is for DevTools. Just noticed this is in the redux ticket, as it was the first thing that popped up when I googled the two terms. I can move it if you'd prefer.
git clone https://github.com/erikras/redux-form
git checkout gh-pages
npm install
npm run dev
Navigate to http://localhost:3030/#/examples/synchronous-validation
Hold down the spacebar in the username field
Remove the DevTools from the project: src/index.js by deleting the following line
{devToolsEnabled && !window.devToolsExtension && <DevTools/>}
Refresh
Notice speedup.
You can also get a preview here: http://erikras.github.io/redux-form/#/examples/synchronous-validation?_k=hl6zzk
This is not just keyup for me. DevTools is slow for everything.
90% of folks that experience this issue aren't building their react bundle/compile with the production flag on. And another interesting fact of the day, 99% of statistics like my statement are made up! Haha
Best resolution if your building your React app code with grunt or something:
export NODE_ENV=production && grunt
That usually does the trick, IME
Most helpful comment
90% of folks that experience this issue aren't building their react bundle/compile with the production flag on. And another interesting fact of the day, 99% of statistics like my statement are made up! Haha
Best resolution if your building your React app code with grunt or something:
That usually does the trick, IME