3 ms·
> In IE 11 and Safari for example with Babel transpilation, arrow functions are going to eat your frame rate alive, especially if you have a text input handler
by JasonSage 9y ago
> In IE 11 and Safari for example with Babel transpilation, arrow functions are going to eat your frame rate alive, especially if you have a text input handler with some sort of validation around it. Even in latest Chrome and Firefox, you end up with inputs that feel slow.
Except, the author writes that there isn't quantitative data to back up this kind of claim. It's exactly the kind of armchair performance speculation that they're trying to refute! Can you cite a benchmark or real-world app which exhibits this kind behavior? I'm not saying you're wrong, but the author deals with tons of codebases and tons of developers and says that this comes up a lot but there's never any data to back it up.
- Silhouette 9y agoThe author dismisses a lot of things as speculation that several years of hard data on my own projects say can be real. It doesn't take much in the way of large tables or lists or SVGs to be in a situation where your costs for rendering and/or reconciliation with the real DOM are significant. The bottleneck typically isn't the time to build the new function every time you render the React component. The problem is that doing so can remove all of the benefit you would otherwise get from using a pure component (or otherwise implementing shouldComponentUpdate), because each function you pass in as a prop will have a new identity and therefore will not compare equal to the previous one, even if in reality it is calling the same underlying function with the same parameters so nothing material has changed.
- acemarke 9y agoLegitimate request: can you provide some actual benchmarks or examples that demonstrate these perf issues? Part of the reason why Ryan, Michael, and others like myself are pushing back on this is that "creating functions kills perf!" has become a kind of "received wisdom" that people are blindly and dogmatically passing around, yet there don't seem to be hard numbers to actually back up what everyone "knows" to be an issue. Ryan did also address the `shouldComponentUpdate / PureComponent` aspect in the post already.
- Silhouette 9y agoLegitimate request: can you provide some actual benchmarks or examples that demonstrate these perf issues? Not straightforwardly (due to pseudonymity and in any case client confidentiality) but I can give you a typical example. I've worked on quite a few web apps in recent years that have used SVGs to draw somewhat complicated and interactive visualisations. That needs a level of efficiency well beyond your basic "Here's a control, here's the underlying data in the model, there's roughly a 1:1 correspondence between them" web app UI. For example, some of the layout algorithms could take a significant fraction of a second just to run once, so typically you get a whole extra level of cache sitting between your underlying data and your React-based rendering functionality. Even then, a rerender of the whole visualisation can easily take a significant fraction of a second, just due to the number of elements involved and the relatively poor performance of browsers at handling large inline SVGs in various situations. So, you immediately need to start isolating which parts of the SVG actually need updating in response to user events, including relatively frequent ones like mouse moves or repeated keypresses. But if many of those child components are also going to be interactive, there are potentially hundreds or thousands of event handlers flying around. If each type of interaction needs a handler that has some common information, like say where your underlying controller logic lives, and also something specific to each element, like say the ID(s) of some underlying item(s) in your data model that are related to that part of the visualisation, then either you get a lot of binding going on or you have to pass in a common function and manually call it with the extra parameters from the event handler functions for your SVG elements. One thing you really don't want to do in this situation is have function involved that is (a) recreated on each render of (b) a high-level component with a lot of children that will ultimately be calling that function. Doing so will inevitably mean that you need to rerender all such children in your viz instead of just a very small number that might be relevant to say a particular mouse move or keyboard event. The thing that gets me is that in this sort of environment, whether it's an SVG or a table or a list or any other part of the DOM that will contain a lot of content and probably be based on a lot of different underlying data points in your model, it's entirely predictable that you will have to focus on only narrow parts of your rendered content in response to frequent user-triggered events. So you know right from the start that you can't just bind your event handling functions at the top level and pass them down through props and add more specific parameters as you pass them into more specific child components. That entire strategy is doomed before your write a line of code (though unfortunately it will probably work just fine if you're developing with a very small set of data and a very simple resulting visualisation, which can create a false sense of confidence if you're not careful). So you might as well plan the design for your event handling and callbacks around what you're inevitably going to need from the start. I can't actually give you hard data on the exact FPS we saw the first time we tried the bad way of doing this, but I can tell you that it was more like SPF than FPS. Ryan did also address the `shouldComponentUpdate / PureComponent` aspect in the post already. Honestly, the last parts of the article about ignoring handlers didn't make much sense to me anyway. I can't see why you'd ever want to pass props into a React component that weren't ultimately going to influence rendering one way or another, and therefore why you'd ever be in a position where you could safely ignore props for shouldComponentUpdate purposes yet wouldn't just remove them altogether. Certainly any assumptions about event-handling on<X> not needing to be diffed would be totally wrong in the context of a table/list/SVG/etc. where each child element is tied to some specific underlying data point(s) and has event handler functions supplied via props accordingly. That looked like another of those cases where the author is generalising their own limited experience and failing to realise that for plenty of other situations the same assumptions won't apply.