Skip to content

Commit

Permalink
Fold _hydrating field into _flags field (+12 B)
Browse files Browse the repository at this point in the history
  • Loading branch information
andrewiggins committed Nov 4, 2023
1 parent 5e5e387 commit 08a277a
Show file tree
Hide file tree
Showing 9 changed files with 27 additions and 19 deletions.
7 changes: 4 additions & 3 deletions compat/src/suspense.js
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import { Component, createElement, options, Fragment } from 'preact';
import { MODE_HYDRATE } from 'preact/src/constants';
import { assign } from './util';

const oldCatchError = options._catchError;
Expand Down Expand Up @@ -34,7 +35,7 @@ options.unmount = function (vnode) {
// most likely it is because the component is suspended
// we set the vnode.type as `null` so that it is not a typeof function
// so the unmount will remove the vnode._dom
if (component && vnode._hydrating === true) {
if (component && vnode._flags & MODE_HYDRATE) {
vnode.type = null;
}

Expand Down Expand Up @@ -166,7 +167,7 @@ Suspense.prototype._childDidSuspend = function (promise, suspendingVNode) {
* to remain on screen and hydrate it when the suspense actually gets resolved.
* While in non-hydration cases the usual fallback -> component flow would occour.
*/
const wasHydrating = suspendingVNode._hydrating === true;
const wasHydrating = (suspendingVNode._flags & MODE_HYDRATE) === MODE_HYDRATE;
if (!c._pendingSuspensionCount++ && !wasHydrating) {
c.setState({ _suspended: (c._detachOnNextRender = c._vnode._children[0]) });
}
Expand Down Expand Up @@ -204,7 +205,7 @@ Suspense.prototype.render = function (props, state) {
/** @type {import('./internal').VNode} */
const fallback =
state._suspended && createElement(Fragment, null, props.fallback);
if (fallback) fallback._hydrating = null;
if (fallback) fallback._flags &= ~MODE_HYDRATE;

return [
createElement(Fragment, null, state._suspended ? null : props.children),
Expand Down
4 changes: 1 addition & 3 deletions jsx-runtime/src/index.js
Original file line number Diff line number Diff line change
@@ -1,7 +1,5 @@
import { options, Fragment } from 'preact';

/** @typedef {import('preact').VNode} VNode */

let vnodeId = 0;

/**
Expand Down Expand Up @@ -39,6 +37,7 @@ function createVNode(type, props, key, isStaticChildren, __source, __self) {
}
}

/** @type {VNode & { __source: any; __self: any }} */
const vnode = {
type,
props: normalizedProps,
Expand All @@ -50,7 +49,6 @@ function createVNode(type, props, key, isStaticChildren, __source, __self) {
_dom: null,
_nextDom: undefined,
_component: null,
_hydrating: null,
constructor: undefined,
_original: --vnodeId,
_index: -1,
Expand Down
1 change: 0 additions & 1 deletion mangle.json
Original file line number Diff line number Diff line change
Expand Up @@ -52,7 +52,6 @@
"$_onResolve": "__R",
"$_suspended": "__a",
"$_dom": "__e",
"$_hydrating": "__h",
"$_component": "__c",
"$_index": "__i",
"$_flags": "__u",
Expand Down
5 changes: 3 additions & 2 deletions src/component.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ import { assign } from './util';
import { diff, commitRoot } from './diff/index';
import options from './options';
import { Fragment } from './create-element';
import { MODE_HYDRATE } from './constants';

/**
* Base Component class. Provides `setState()` and `forceUpdate()`, which
Expand Down Expand Up @@ -136,10 +137,10 @@ function renderComponent(component) {
oldVNode,
component._globalContext,
parentDom.ownerSVGElement !== undefined,
oldVNode._hydrating != null ? [oldDom] : null,
oldVNode._flags & MODE_HYDRATE ? [oldDom] : null,
commitQueue,
oldDom == null ? getDomSibling(oldVNode) : oldDom,
oldVNode._hydrating,
(oldVNode._flags & MODE_HYDRATE) === MODE_HYDRATE,
refQueue
);

Expand Down
6 changes: 5 additions & 1 deletion src/constants.js
Original file line number Diff line number Diff line change
@@ -1,10 +1,14 @@
/** Normal hydration that attaches to a DOM tree but does not diff it. */
export const MODE_HYDRATE = 1 << 5;
/** Signifies this VNode suspended on the previous render */
export const MODE_SUSPENDED = 1 << 7;
/** Indicates that this node needs to be inserted while patching children */
export const INSERT_VNODE = 1 << 16;
/** Indicates a VNode has been matched with another VNode in the diff */
export const MATCHED = 1 << 17;

/** Reset all mode flags */
export const RESET_MODE = ~(INSERT_VNODE | MATCHED);
export const RESET_MODE = ~(MODE_HYDRATE | MODE_SUSPENDED);

export const EMPTY_OBJ = /** @type {any} */ ({});
export const EMPTY_ARR = [];
Expand Down
1 change: 0 additions & 1 deletion src/create-element.js
Original file line number Diff line number Diff line change
Expand Up @@ -72,7 +72,6 @@ export function createVNode(type, props, key, ref, original) {
// a _nextDom that has been set to `null`
_nextDom: undefined,
_component: null,
_hydrating: null,
constructor: undefined,
_original: original == null ? ++vnodeId : original,
_index: -1,
Expand Down
2 changes: 1 addition & 1 deletion src/diff/children.js
Original file line number Diff line number Diff line change
Expand Up @@ -144,7 +144,7 @@ export function diffChildren(
childVNode._nextDom = undefined;

// Unset diffing flags
childVNode._flags &= RESET_MODE;
childVNode._flags &= ~(INSERT_VNODE | MATCHED);
}

// TODO: With new child diffing algo, consider alt ways to diff Fragments.
Expand Down
19 changes: 13 additions & 6 deletions src/diff/index.js
Original file line number Diff line number Diff line change
@@ -1,4 +1,9 @@
import { EMPTY_OBJ } from '../constants';
import {
EMPTY_OBJ,
MODE_HYDRATE,
MODE_SUSPENDED,
RESET_MODE
} from '../constants';
import { BaseComponent, getDomSibling } from '../component';
import { Fragment } from '../create-element';
import { diffChildren } from './children';
Expand Down Expand Up @@ -45,11 +50,11 @@ export function diff(
if (newVNode.constructor !== undefined) return null;

// If the previous diff bailed out, resume creating/hydrating.
if (oldVNode._hydrating != null) {
isHydrating = oldVNode._hydrating;
if (oldVNode._flags & MODE_SUSPENDED) {
isHydrating = (oldVNode._flags & MODE_HYDRATE) === MODE_HYDRATE;
oldDom = newVNode._dom = oldVNode._dom;
// if we resume, we want the tree to be "unlocked"
newVNode._hydrating = null;
// newVNode._hydrating = null;
excessDomChildren = [oldDom];
}

Expand Down Expand Up @@ -253,7 +258,7 @@ export function diff(
c.base = newVNode._dom;

// We successfully rendered this VNode, unset any stored hydration/bailout state:
newVNode._hydrating = null;
newVNode._flags &= RESET_MODE;

if (c._renderCallbacks.length) {
commitQueue.push(c);
Expand All @@ -267,7 +272,9 @@ export function diff(
// if hydrating or creating initial tree, bailout preserves DOM:
if (isHydrating || excessDomChildren != null) {
newVNode._dom = oldDom;
newVNode._hydrating = !!isHydrating;
newVNode._flags |= isHydrating
? MODE_HYDRATE | MODE_SUSPENDED
: MODE_HYDRATE;
excessDomChildren[excessDomChildren.indexOf(oldDom)] = null;
// ^ could possibly be simplified to:
// excessDomChildren.length = 0;
Expand Down
1 change: 0 additions & 1 deletion src/internal.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -147,7 +147,6 @@ declare global {
*/
_nextDom: PreactElement | null | undefined;
_component: Component | null;
_hydrating: boolean | null;
constructor: undefined;
_original: number;
_index: number;
Expand Down

0 comments on commit 08a277a

Please sign in to comment.