Commit Graph

37 Commits

Author SHA1 Message Date
Valentin Shergin 3c69a9eb4b Fabric: display: none nodes do not create views anymore
Summary:
This introduces a new shadow node trait (`Hidden`) which disables emitting ShadowVides for such nodes and all their descendants.

Changelog: [Internal] Fabric-specific internal change.

Reviewed By: sammy-SC

Differential Revision: D22134220

fbshipit-source-id: 8ea1fc3186019005ad687eacaca0ba4a4d8343dc
2020-07-01 20:54:58 -07:00
David Vacca 84bca09f87 Fix position of TextInlineViews when nesting multiple Text components
Summary:
This diff fixes the position of TextInlineViews when nesting multiple Text.
The root is that we were not taking into consideration LayoutOffset of nested TextViews during the calculation of the nested views.

changelog: [Internal] Internal fix in Fabric

Reviewed By: JoshuaGross

Differential Revision: D21586893

fbshipit-source-id: 55e6ad0cf95222588ffe9185f5e22baea1059448
2020-05-14 21:42:37 -07:00
Samuel Susla a7bbc858c5 Use vector.empty() to check for emptyness
Summary:
Changelog: [Internal]

Using `empty()` vs `size() == 0` or `size() > 0`.
It is a more semantic way to check whether container is empty or not.

Reviewed By: JoshuaGross

Differential Revision: D21573183

fbshipit-source-id: b83283f687432a037941852114717a0f014e28db
2020-05-14 11:58:58 -07:00
Samuel Susla 16d15209e5 Remove branching for optimized differ QE
Summary: Changelog: [Internal]

Reviewed By: JoshuaGross

Differential Revision: D21556312

fbshipit-source-id: 0d6d275de2d691cb42e5e70e5bf19bcc983cae12
2020-05-14 05:30:48 -07:00
Joshua Gross bb5d04366a Differ: fix TinyMap to prevent possible crashes in find() and begin(), and prevent erased elements from being iterated over
Summary:
The core issue solved in D21389371 was that erased elements of a TinyMap were being iterated over, because TinyMap has somewhat-complicated logic around cleaning out the underlying vector. In some very marginal cases, vectors were not being cleaned and an iterator pointing at erased elements was being returned.

The diff prevents some possible crashes in `begin()` and `find()` while making it much less likely to iterate over erased elements.

We also add a unit test to catch the case fixed in D21389371, in particular.

We also are keeping the code added in D21389371 (for now) since it's a cheap check, and will be a safeguard until we have rigorous testing around TinyMap. To be clear that logic should noop currently, but will prevent crashes in case guarantees around TinyMap change in the future.

Currently there is only one line of code that actually uses the TinyMap iterator, so this should be safe.

Reviewed By: shergin

Differential Revision: D21392762

fbshipit-source-id: 36dc998958c230fad01af93338974f8889cbcf55
2020-05-04 21:28:35 -07:00
Joshua Gross d815be1c99 Fix Optimized Differ (was generating extraneous Create mutations)
Summary:
When we call `.erase` on the TinyMap, it sets the key of the element to 0. When we call `.begin()` later, TinyMap will sometimes, but not always, clean up the underlying Vector. This means that *most* of the time, underlying erased elements will be removed from the Vector; but sometimes erased elements will still be there when iterating over it.

This was causing us to generate extra "Create" mutations.

To fix this, for now we just check for zeroed-out elements when iterating over the vector.

Changelog: [Internal]

Reviewed By: mdvacca

Differential Revision: D21389371

fbshipit-source-id: 1e641050987d40a3f3e31499dcb373cfb28ae6f8
2020-05-04 16:04:51 -07:00
Joshua Gross 2b062eadc8 Fix bug in optimized differ
Summary:
The differ was still producing correct, but not minimal, instruction sets in some cases due to an optimization that was buggy.

This affected cases where 2+ nodes were inserted at the beginning of a list. It would trigger the old behavior where all nodes after the first would be removed, deleted, then reinserted.

See the test case (which was failing and now passed) and P128190998 (the 3->4 transition) for samples.

Changelog: [Internal] Fabric differ

Reviewed By: mdvacca

Differential Revision: D20785729

fbshipit-source-id: 2fea6a816753066abb358ed7bb51003140cd5fc4
2020-03-31 19:36:45 -07:00
Joshua Gross d770d78032 Reimplement D19965405: Small improvements in Differentiator/TinyMap
Summary:
Two things:
1) I reimplement Valentin's idea in D19965405, so that TinyMaps can be iterated over, with a couple of bugfixes (calling front() or back() on an empty vector will crash).
2) I now use TinyMap instead of better::map in the "optimized" diffing algorithm.
3) `erase` now actually removes elements from the vector, but only when more than half of elements have been erased.
4) If you repeatedly erase elements at the beginning of the vector, they will no longer be iterated over. This is a specific optimization for our heaviest TinyMap use-cases.

These amount to some small but hopefully somewhat meaningful perf improvements.

Changelog: [Internal] Fabric perf

Reviewed By: shergin

Differential Revision: D20718719

fbshipit-source-id: 91f4b2e2e0f6387ae484e43d5b0095103087baa6
2020-03-28 14:49:54 -07:00
Joshua Gross 50a34bcd7f Optimize diff algorithm to produce fewer remove+insert ("move") paired instructions
Summary:
An evolution of D20633188 but more performant.

There are three optimized paths before the slow path.

The first optimized path tries to pair identical nodes from old/new tree, and generate Update mutations, until we hit nodes that are different (indicating either a remove or an insert). This already existed.

The next two optimizations, introduced by Tim in his JS pseudocode, were inspired by ReactJS's diffing algorithm. They work in cases where the rest of the nodes are (1) all removals/deletes or (2) all creates+inserts.

Finally, if those final two optimized paths can't run, it's because there is a mix of delete+remove, create+insert, and "move" operations, mixed at the beginning, middle, and/or end of the list.

This has slightly better average/best-case complexity as the previous implementation.
In particularly pathological cases where all nodes are arbitrarily reordered, or reversed, for instance (ABCDE->EDCBA) the algorithm has the same complexity as the previous algorithm (quadratic).

For now iOS is pinned to the older differ

Changelog: [Internal] Experiment to optimize diffing algorithm in Fabric

Reviewed By: shergin

Differential Revision: D20684094

fbshipit-source-id: d29fba95a0328156c023e1c87804f23770ee1d91
2020-03-27 19:07:53 -07:00
Héctor Ramos 07def55396 fbshipit-source-id: da15f69185e724eaf7d4bc78dbc61fcdcb3074d5 2020-03-13 21:46:45 -07:00
Valentin Shergin 8e3e0bd6a7 Fabric: Introducting ShadowNode::getOrderIndex()
Summary:
The diff introduces a new field in `ShadowNode` which defines in which order ShadowViews created from the node and its siblings will appear ShadowView tree. The feature will be used to overcome some platform limitations (e.g. on Android) on the mounting layer (it will be able to move some nodes of some time to the end (or beginning) of the list) and build features like zIndex ordering in C++ core.

Changelog: [Internal] Fabric-specific internal change.

Reviewed By: mdvacca

Differential Revision: D20396718

fbshipit-source-id: 16aef7c2b5511c874341ab7554e5585b2cdc356f
2020-03-11 22:45:27 -07:00
Valentin Shergin 8fb0eefb78 Fabric: Using move semantic in Differentiator
Summary:
This diff changes how we pass lists of nodes to `calculateShadowViewMutations`: previously we passed that as `const &` and now we pass them as rvalue references because we will need to mute them in the future diffs.

This diff also adds a `static_assert` to ensure that the lists are movable.

Changelog: [Internal] Fabric-specific internal change.

Reviewed By: mdvacca

Differential Revision: D20353754

fbshipit-source-id: 0c3383bff6ded8a49d1ac003fce8919d3906b5bb
2020-03-11 22:45:27 -07:00
Valentin Shergin 4f3e3f8cc1 Fabric: Tweaking view flattening algorithm to rely on new traits instead of LayoutableShadowNode::isLayoutOnly()
Summary: Now, following the previous diff, we remove `LayoutableShadowNode::isLayoutOnly()` and change the view flattening algorithm to rely on two new traits. See the previous diff to learn more about how it works.

Reviewed By: sammy-SC

Differential Revision: D20212252

fbshipit-source-id: 87a07e8bb17b2e66e5703f107dc35ca7a8e49634
2020-03-04 12:33:03 -08:00
Valentin Shergin b8c17dd7c0 Revert D19965405: Fabric: Small improvements in Differentiator/TinyMap
Differential Revision:
D19965405

Original commit changeset: 92eedf38d55b

fbshipit-source-id: 92073ca877899e2a607f283275f0d7c894dd4720
2020-03-03 16:39:31 -08:00
Valentin Shergin b41307af77 Fabric: Small improvements in Differentiator/TinyMap
Summary:
What's changed:
 * `end()` now returns the pointer to the imaginary element after the very last one (which is aligned with STL);
 * `erase()` now swaps the removing and the last elements and shrinks the size of an array.

Changelog: [Internal] Fabric-specific internal change.

Reviewed By: sammy-SC

Differential Revision: D19965405

fbshipit-source-id: 92eedf38d55be35a0d9ab6120634b51c8d6e4674
2020-03-02 23:03:01 -08:00
Valentin Shergin b9e5ebd640 Fabric: Using traitCast in Differentiator
Summary:
The Diffing is one of the hottest pieces of Fabric. Removing dynamic_cast here should improve perf. See the previous diff for more details.

Changelog: [Internal] Fabric-specific internal change.

Reviewed By: sammy-SC

Differential Revision: D20052030

fbshipit-source-id: 27fd9f34f2a1f9d22b9da6b1e3c1a2982045c07a
2020-02-26 22:08:17 -08:00
Valentin Shergin b549d0ea9e Fabric: Test for ShadowNode trees Diffing algorithm
Summary:
Here is a mutation test for the Diffing algorithm that we use to diff ShadowNode trees and flatten them. As a side-effect, it also "tests" that Concurrent Yoga does not crash and produces decent cloning requests.

The test works this way:
1. We create a random ShadowNode tree;
2. We create a View tree from that that we continue to maintain;
3. We apply random mutation on this;
4. We layout the tree;
5. We generate the mutation instruction comparing a previous tree with a new one;
6. We apply mutations on the first tree;
7. We generate a new tree from scratch;
8. We compare the new tree with the tree updated with mutations and expect equivalence;
9. Repeat a million times.

Changelog: [Internal] Fabric-specific internal change.

Reviewed By: JoshuaGross, mdvacca

Differential Revision: D19357714

fbshipit-source-id: 04765ede87d91180952ae650ff0d505dfac2ed8e
2020-01-28 22:37:17 -08:00
Andres Suarez 722feeb02b Tidy up license headers [1/n]
Summary: Changelog: [General] [Fixed] - License header cleanup

Reviewed By: yungsters

Differential Revision: D17952695

fbshipit-source-id: 81aa607612ba1357ef7814ef20371335151afe7e
2019-10-16 10:06:33 -07:00
Min ho Kim 84f5ebe4f9 Fix typos (#25770)
Summary:
Fix typos mostly in comments and some string literals.

## Changelog

[General] [Fixed] - Fix typos
Pull Request resolved: https://github.com/facebook/react-native/pull/25770

Differential Revision: D16437857

Pulled By: cpojer

fbshipit-source-id: ffeb4d6b175e341381352091134f7c97d78c679f
2019-07-23 03:23:11 -07:00
Valentin Shergin b0273bbe70 Fabric: Reimplementation of stubViewTreeFromShadowNode
Summary:
`stubViewTreeFromShadowNode` was implemented without using `calculateShadowViewMutations` (aka Diffing algorithm).
The problem is that we use `stubViewTreeFromShadowNode` to test the diffing, so it was not fully correct to use the algorithm to test itself.

Reviewed By: JoshuaGross

Differential Revision: D16342526

fbshipit-source-id: 2674245ed5ec71309fe5d362779a33d8dd31dc7b
2019-07-17 14:22:02 -07:00
Valentin Shergin bca4e4c8a4 Fabric: Additional static asserts in Differentiator
Summary: I am about to change the definition of ShadowView a bit, so I think we need to ensure that we don't regress move semantic.

Reviewed By: JoshuaGross, sammy-SC

Differential Revision: D15911453

fbshipit-source-id: ce2cd4cb2375ecb76295948a1e9b5d2e7fb80f38
2019-06-23 21:33:18 -07:00
David Vacca 4f4d3857ea Back out "[Fabric][C++] Backout Force Diffing algorithm to insert views Bottom Up"
Summary: Original commit changeset: 455034ce7b70

Reviewed By: JoshuaGross

Differential Revision: D15900818

fbshipit-source-id: c197aaedde1ab32e2e1a5764eb400600ab46b840
2019-06-21 11:52:56 -07:00
David Vacca c603e55ed4 Backout Force Diffing algorithm to insert views Bottom Up
Summary: This is a temporary backout of D14817454, to verify if this is related T45503571

Reviewed By: JoshuaGross

Differential Revision: D15780018

fbshipit-source-id: 455034ce7b7096101db93a8604b77e1233db1137
2019-06-12 07:35:13 -07:00
Valentin Shergin 01523ae660 Fabric: TinyMap in Differentiator
Summary: Diffing algorithm uses a small map for every layer of shadow tree; that's a lot of maps. Luckily, it does not need a complex feature-full map (which is not free to allocate and use), it needs a tiny map with a dozen values. Why do we need to pay for what we don't use? This diff introduces a trivial map optimized for constraints that we have here. (See more details in the code.)

Reviewed By: mdvacca

Differential Revision: D15200495

fbshipit-source-id: d859b68b9543253840b403e7430f945a0b76d87b
2019-05-03 12:36:29 -07:00
Valentin Shergin c5f0969fba Fabric: Code style changes in Differentiator
Summary: Trivial. Code style-only changes.

Reviewed By: mdvacca

Differential Revision: D15200497

fbshipit-source-id: 00b5f2e6ce7491e80e03ceb7f433571f397c2392
2019-05-03 12:36:29 -07:00
Valentin Shergin f8c5fa37d9 Fabric: insertedPairs in calculateShadowViewMutations now stores pointers (not values)
Summary:
This is a small micro-optimization in Diffing algorithm.
Seems we don't need to store full ShadowView objects in `insertedPairs` map, we can store only pointers to them. That can save memory and CPU cycles because we will not need to store full objects and copy shared pointers (which is somewhat expensive).

Reviewed By: mdvacca

Differential Revision: D15200498

fbshipit-source-id: 2a268c3ee80755555bff3317e10e679be1cf9830
2019-05-03 12:36:28 -07:00
Valentin Shergin 30c3ea5c3f Fabric: Using move semanic in Differentiator
Summary: Diffing is already pretty fast, but using move semantic should make it even faster. ShadowViews have shared pointers, so moving them can save us atomic counter bumps.

Reviewed By: mdvacca

Differential Revision: D15200496

fbshipit-source-id: 6fb0eb79e07cd6ae9b3100713497c634f306bc18
2019-05-03 12:36:28 -07:00
David Vacca 5850bd0785 Force Diffing algorithm to insert views Bottom Up (from children to root)
Summary:
This diff changes the way views are inserted by the diffing algorithm.
Previously the diffing algorithm inserted views top-down, now it insert views bottom-up (same order as previous version of RN).

Let say we need to create the following tree:
```

A --> B --> C
      |
      | --> D

```

Before, the diffing algorithm created the following list of instructions:
```
insert(A, B, 0)
insert(B, C, 0)
insert(B, D, 1)
```

After this diff, the insert instructions are going to be:

```
insert(B, C, 0)
insert(B, D, 1)
insert(A, B, 0)
```

Reviewed By: shergin

Differential Revision: D14817454

fbshipit-source-id: 7aac1a1e1784c53bca2747aee80a5bc8ee788e7a
2019-04-10 16:18:20 -07:00
Valentin Shergin 5a418c5a5d Fabric: Fixed a bug in Diffing algorithm
Summary: Before the fix, the algorithm compares ShadowViews to make a decision should it recursively call itself or not; that didn't work properly because a ShadowView doesn't fully represent the state of the subtree tree (e.g. they don't have information about children nodes). After the fix, we compare pointers to ShadowNodes (by comparing pairs).

Reviewed By: mdvacca

Differential Revision: D14696996

fbshipit-source-id: 560d623b15a272f13b08a11745dec6be39a5dbdd
2019-03-30 12:21:54 -07:00
Valentin Shergin 28e89e5081 Fabric: ShadowNodeFamily, the first steps
Summary:
ShadowNodeFamily is a new concept that allows us to implement an efficient way to solve the problem of finding a path to some ancestor node (practically reimplement ShadowNode::constructAncestorPath() in some efficient way).

This diff is the first one in the series. It introduces a new class and moves some data into it.

Reviewed By: JoshuaGross

Differential Revision: D14416947

fbshipit-source-id: c93865a8929a2128498e34d3589487696aac6283
2019-03-18 23:56:13 -07:00
Valentin Shergin 56501dcc47 Fabric: Changing the shape of ShadowViewNodePair class
Summary:
I am not sure why it compiled before, it clearly should not, IMO. The `const` types (and references!) are not allowed inside `std::vector` because they are not assignable.
Some experiments that I did caused compilation errors here, so I am changing that to be actually correct.

Reviewed By: JoshuaGross

Differential Revision: D14249199

fbshipit-source-id: 07a22ef13f5de9dfc7ab307493419e6006994bc2
2019-03-04 10:00:01 -08:00
David Vacca 95c414cfbf Introduce "updateProps" field InsertMutation
Summary: This diff introduces the concept of "updateProps" as part of InsertMutation and it changes the diffing algorithm to populate this field.

Reviewed By: shergin

Differential Revision: D14289608

fbshipit-source-id: 642f00d03d294a12ea7fa7482c72e701b756f3d4
2019-03-03 09:00:47 -08:00
Valentin Shergin 77838b5504 Fabric: Systraces are back
Summary:
It's better to comment `DWITH_FBSYSTRACE` out in BUCK files instead of removing them from the code.
I'll publish the BUCK changes as separate diff for simpler backout in the future.

Reviewed By: mdvacca

Differential Revision: D14019272

fbshipit-source-id: 8b322b5c115efe33c15929e008b97a05220813df
2019-02-11 16:01:05 -08:00
Valentin Shergin fd3b8f2000 Fabric: Introducing Better: For faster, clear and ideomatic codebase
Summary:
`Better` is a trivial collection of basic tools borrowed from other low-level general purpose libraries (like Folly, Abseil or Boost). The main goals of Better:
 - Make the codebase more portable;
 - Make the dependency list explicit (by decoupling it as a dependency list of Better);
 - Make relying on modern C++ patterns and tools in code simple and easy.
 - Make executing experiments with different dependencies easier.

 As a first example usage, this diff replaces std::unordered_map with an efficient one from folly on the one of the hottest paths.

Reviewed By: JoshuaGross

Differential Revision: D13944565

fbshipit-source-id: 5fa2c4abe6c17f7361eddcc25f968b6440d5d9db
2019-02-08 13:57:33 -08:00
David Vacca 842b9c106a Temporary remove systraces from Fabric core code
Summary: This is a temporary change to measure production data

Reviewed By: fkgozali

Differential Revision: D13906807

fbshipit-source-id: 2a2f71aa379c4aca63c7bb4a9644704f713cb088
2019-02-02 13:08:06 -08:00
Valentin Shergin cb14b06309 Fabric: More systraces for Diffing and Commit phase
Summary: Trivial.

Reviewed By: mdvacca

Differential Revision: D13644482

fbshipit-source-id: 90cfa04797682e57fc4de009fe4a412167b9e8cd
2019-01-11 18:13:55 -08:00
Valentin Shergin 62173a1569 Introducing fabric/mounting module
Summary:
ShadowView, ShadowViewMutation, and Differentiator were decoupled to separate module.
That enables us to use ShadowView more widely without facing a circular dependency problem.

Reviewed By: mdvacca

Differential Revision: D13205229

fbshipit-source-id: 7373864bf153a7813c2f97edb263a41454ce0b88
2018-11-27 18:34:14 -08:00