mirror of
https://github.com/facebook/react-native.git
synced 2025-11-01 09:14:26 +00:00
Summary: Without getting into the weeds too much, RawPropParser "requires" that props be accessed in the same order every time a Props struct is parsed in order to most optimally fetch the values in a linear-ish fashion, basically ensuring that each rawProps.at() call is an O(1) operation, and overall getting all props for a particular component is O(n) in the number of props for a given struct. If props are called out of order, this breaks and worst-case we can end up with an O(n^2) operation. Unfortunately, calling .at(x) twice with the same prop name triggers the deoptimized behavior. So as much as possible, always fetch exactly once and in the same order every time. In this case, we move initialization of two fields into the constructor body so that we can call .at() a single time instead of twice. In the debug props of ViewProps I'm also reordering the fields to fetch them in the same order the constructor fetches them in, which will make this (debug-only) method slightly faster. What's the impact of this? If you dig into the Tracery samples, the average/median RawPropsParser::at takes 1us or less. However, in /every single/ call to createNode for View components, there is at least one RawPropsParser::at call that takes 250+us. This was a huge red flag when analyzing traces, after which it was trivial (for View) to find the offending out-of-order calls. Since this is happening for every View and every type of component that derives from View, that's 1ms lost per every 4 View-type ShadowNodes created by ReactJS. After just 100 views created, that's 25ms. Etc. There are other out-of-order calls lurking in the codebase that can be addressed separately. Impact scales with the size of the screen, the number of Views they render, etc. Changelog: [Internal] Reviewed By: mdvacca Differential Revision: D36889794 fbshipit-source-id: 91e0a7ca39ed10778e60a0f0339a4b4dc8b14436