Whenever we do this, Rollup needs to materialize this as an object.
This causes it to also add the Babel compatibility property which is
unnecessary bloat. However, since when we use these, we leak the object
this often also deopts any compiler optimizations.
If we really need an object we should export default an object.
Currently there is an exception for DOMTopLevelEventTypes since
listing out the imports is a PITA and it doesn't escape so it should
get properly inlined. We should probably move to a different pattern
to avoid this for consistency though.
In the process of switching to MessageChannel, it seems the postMessage call was modified to pass `"*"` (originally the target origin value from `window.postMessage`). This actually ends up triggering serialization, whereas passing `undefined` bypasses.
To save some investigation, passing a Number like `0` still incurs serialization overhead - `undefined` has special behavior.
Disables the recently introduced (#14181) warning for shorthand
CSS property collisions by wrapping in a feature flag. Let's hold off
shipping this until at least the next minor.
* Add a checkbox to fixtures UI to choose React production build
* Assign header__label class name to label directly, instead of using a separate span
* center the production checkbox vertically
Scheduler needs to schedule a task that fires after paint. To do this,
it currently posts a message event to `window`. This happens on every
frame until the queue is empty. An unfortunate consequence is that every
other message event handler also gets called on every frame; even if
they exit immediately, this adds up to significant per-frame overhead.
Instead, we'll create a MessageChannel and post to that, with a
fallback to the old behavior if MessageChannel does not exist.
I figured out a simpler way to do #14181. It does allocate some but I think that's OK. Time complexity might even be better since we avoid the nested loops the old one had.
* BUG: ReactPartialRenderer / New Context polutes mutable global state
The new context API stores the provided values on the shared context instance. When used in a synchronous context, this is not an issue. However when used in an concurrent context this can cause a "push provider" from one react render to have an effect on an unrelated concurrent react render.
I've encountered this bug in production when using renderToNodeStream, which asks ReactPartialRenderer for bytes up to a high water mark before yielding. If two Node Streams are created and read from in parallel, the state of one can polute the other.
I wrote a failing test to illustrate the conditions under which this happens.
I'm also concerned that the experimental concurrent/async React rendering on the client could suffer from the same issue.
* Use unique thread ID for each partial render to access Context
This first adds an allocator that keeps track of a unique ThreadID index
for each currently executing partial renderer. IDs are not just growing
but are reused as streams are destroyed.
This ensures that IDs are kept nice and compact.
This lets us use an "array" for each Context object to store the current
values. The look up for these are fast because they're just looking up
an offset in a tightly packed "array".
I don't use an actual Array object to store the values. Instead, I rely
on that VMs (notably V8) treat storage of numeric index property access
as a separate "elements" allocation.
This lets us avoid an extra indirection.
However, we must ensure that these arrays are not holey to preserve this
feature.
To do that I store the _threadCount on each context (effectively it takes
the place of the .length property on an array).
This lets us first validate that the context has enough slots before we
access the slot. If not, we fill in the slots with the default value.
This is one of the most insidious quirks of React DOM that people run into. Now we warn when we think an update is dangerous.
We still allow rendering `{background, backgroundSize}` with unchanging values, for example. But once you remove either one or change `background` (without changing `backgroundSize` at the same time), that's bad news. So we warn.
Fixes#6348.
Oopsie!
This could have been avoided if our types were modeled correctly with
Flow (using a disjoint union).
Fuzz tester didn't catch it because it does not generate cases where
a Suspense component mounts with no children. I'll update it.
* Don't warn if an unmounted component is pinged
* Suspense fuzz tester
The fuzzer works by generating a random tree of React elements. The tree
two types of custom components:
- A Text component suspends rendering on initial mount for a fuzzy
duration of time. It may update a fuzzy number of times; each update
supsends for a fuzzy duration of time.
- A Container component wraps some children. It may remount its children
a fuzzy number of times, by updating its key.
The tree may also include nested Suspense components.
After this tree is generated, the tester sets a flag to temporarily
disable Text components from suspending. The tree is rendered
synchronously. The output of this render is the expected output.
Then the tester flips the flag back to enable suspending. It renders the
tree again. This time the Text components will suspend for the amount of
time configured by the props. The tester waits until everything has
resolved. The resolved output is then compared to the expected output
generated in the previous step.
Finally, we render once more, but this time in concurrent mode. Once
again, the resolved output is compared to the expected output.
I tested by commenting out various parts of the Suspense implementation
to see if broke in the expected way. I also confirmed that it would have
caught #14133, a recent bug related to deletions.
* When a generated test case fails, log its input
* Moar fuzziness
Adds more fuzziness to the generated tests. Specifcally, introduces
nested Suspense cases, where the fallback of a Suspense component
also suspends.
This flushed out a bug (yay!) whose test case I've hard coded.
* Use seeded random number generator
So if there's a failure, we can bisect.
* Add failing test for ping on unmounted component
We had a test for this, but not outside of concurrent mode :)
* Don't warn if an unmounted component is pinged
* Parse build script type and package names
This ensures that `yarn build core dom` includes DOM.
It also ensures that spaces like `yarn build "core, dom"` doesn't build EVERYTHING.
* Get rid of label in bundles config
Instead we just use the name from entry using fuzzy search.
There is one special case. If you put in `/index` or `/index.js`.
That allows to build things like `react/index` to only build isomorphic
where as `react` would build everything. Or `react-dom/index` to exclude
the server renderers.
* Instead of matching `/index.js` just append it to the search string
That way things like `yarn build react/` works too.
* Fixed `treeBaseDuration` by propagating its value from the suspended tree to the Fragment React temporarily wraps around it when showing the fallback UI.
* Fixed `actualDuration` by recording elapsed profiler time in the event of an error.
* Fixed `actualDuration` in concurrent mode by propagating the time spent rendering the suspending component to its parent.
Also updated ReactSuspensePlaceholder-test.internal to cover these new cases.
Fixes a bug where deletion effects in the primary tree were dropped
before entering the second render pass.
Because we no longer reset the effect list after the first render pass,
I've also moved the deletion of the fallback children to the complete
phase, after the tree successfully renders without suspending.
Will need to revisit this heuristic when we implement resuming.