From 52f4113a43ecc3d365441c2dcf55d52b524cd968 Mon Sep 17 00:00:00 2001 From: Jason Miller Date: Fri, 27 Dec 2019 18:17:58 -0500 Subject: [PATCH] Experimental support for resuming suspended hydration --- mangle.json | 2 ++ src/create-element.js | 2 ++ src/diff/index.js | 15 +++++++++++++++ 3 files changed, 19 insertions(+) diff --git a/mangle.json b/mangle.json index 221e76e3e2..2ee49e2aa6 100644 --- a/mangle.json +++ b/mangle.json @@ -27,6 +27,8 @@ "$_children": "__k", "$_suspensions": "__u", "$_dom": "__e", + "$_hydrateDom": "__s", + "$_hydrating": "__h", "$_component": "__c", "$__html": "__html", "$_parent": "__", diff --git a/src/create-element.js b/src/create-element.js index 45f62bd5cb..e7ec9b8385 100644 --- a/src/create-element.js +++ b/src/create-element.js @@ -70,6 +70,8 @@ export function createVNode(type, props, key, ref) { _dom: null, _lastDomChild: null, _component: null, + _hydrateDom: null, + _hydrating: false, constructor: undefined }; diff --git a/src/diff/index.js b/src/diff/index.js index b9084ddc31..32e2f5d119 100644 --- a/src/diff/index.js +++ b/src/diff/index.js @@ -40,6 +40,16 @@ export function diff( // constructor as undefined. This to prevent JSON-injection. if (newVNode.constructor !== undefined) return null; + // If this was the innermost VNode at a point where the tree suspended, + // pick up diffing where we left off using the saved DOM element and hydration state. + if (oldVNode._hydrateDom && excessDomChildren == null) { + oldDom = oldVNode._hydrateDom; + excessDomChildren = [oldDom]; + newVNode._dom = oldDom; + oldVNode._hydrateDom = null; + isHydrating = oldVNode._hydrating; + } + if ((tmp = options._diff)) tmp(newVNode); try { @@ -215,6 +225,11 @@ export function diff( if ((tmp = options.diffed)) tmp(newVNode); } catch (e) { + // Before bailing out, mark the current VNode with the DOM element and hydration state. + // We can use this information if we return here to render later on. + newVNode._dom = oldDom; + oldVNode._hydrateDom = oldDom; + oldVNode._hydrating = isHydrating; options._catchError(e, newVNode, oldVNode); }