Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Side effect of third argument of preact render #7868

Closed
1 task done
aleksandrjet opened this issue Jul 30, 2023 · 2 comments
Closed
1 task done

Side effect of third argument of preact render #7868

aleksandrjet opened this issue Jul 30, 2023 · 2 comments
Labels
- P4: important Violate documented behavior or significantly impacts performance (priority) pkg: preact Related to Preact (scope)

Comments

@aleksandrjet
Copy link
Contributor

What version of astro are you using?

2.9.5

Are you using an SSR adapter? If so, which one?

node

What package manager are you using?

pnpm

What operating system are you using?

mac

What browser are you using?

chrome

Describe the Bug

I saw PR of @matthewp when third argument was added to Preact render. It was solving problem with doubles of child nodes.

- render(
-   h(Component, props, children != null ? h(StaticHtml, { value: children }) : children),
-   element
- )

+ function Wrapper({ children }: { children:  JSX.Element }) {
+   let attrs = Object.fromEntries(Array.from(element.attributes).map(attr => [attr.name, attr.value]))
+   return h(element.localName, attrs, children)
+ }
+ render(
+   h(Wrapper, null, h(Component, props, children != null ? h(StaticHtml, { value: children }) : children)),
+   element.parentNode!,
+   element
+ )

But now i see new problem, when i try to use Suspense. It happens because third argument in render tells Preact, that isHydrate mode is not now.

// preact/src/render.js
export function render(vnode, parentDom, replaceNode) {
   ...
  // After adding of third argument with HTMLElement, we have false there
  let isHydrating = typeof replaceNode === 'function'
  ...
}

So, preact considered we have not hydrate and Suspense component shows Fallback component which was passed to Lazy. With third argument of render in app it displays fast turning of html mark from server -> html mark of suspense fallback -> hydrated html mark. I expect, that html mark of suspense fallback will have never seen during hydration.

Preact source code has comment about this:

We do not set suspended: true during hydration because we want the actual markup 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.

If Preact knew we are staying in isHydrate mode, it would not show Fallback component

Can we fix it?

Can we solve problem with doubles element another method? I tried to return old behavior, when we had two arguments for Preact render and all tests passed.

Also one reason, why we need to use two arguments instead three - calling of render with three arguments have marked as deprecated and this possibility will be removed in next Preact version

How to reproduce it

Supporting of Suspense and Lazy component have not still approved yet. I hope, my pr will be included at close time. For reproducing problem with three arguments of render, you need to move to branch with supporting of Suspense:

git clone https://github.com/aleksandrjet/astro.git
cd astro
git checkout preact-prepass-render
pnpm i
pnpm build
cd examples/lazy-preact
pnpm run dev

And you may see, that Fallback of Suspense have been showed one time

#5937

What's the expected result?

Fallback component of Suspense will never show while hydrating

Link to Minimal Reproducible Example

https://github.com/aleksandrjet/astro/tree/preact-prepass-render

Participation

  • I am willing to submit a pull request for this issue.
@github-actions github-actions bot added the needs triage Issue needs to be triaged label Jul 30, 2023
@natemoo-re
Copy link
Member

Thanks for opening an issue! I do think that adding preact-ssr-prepass as included in #7569 would be great, we can continue the discussion there. I'll re-review that PR soon.

@natemoo-re natemoo-re linked a pull request Aug 1, 2023 that will close this issue
@natemoo-re natemoo-re added - P4: important Violate documented behavior or significantly impacts performance (priority) pkg: preact Related to Preact (scope) labels Aug 1, 2023
@github-actions github-actions bot removed the needs triage Issue needs to be triaged label Aug 1, 2023
@bluwy
Copy link
Member

bluwy commented Sep 26, 2023

In Astro 3.0, it is now

const bootstrap = client !== 'only' ? hydrate : render;
bootstrap(
h(Component, props, children != null ? h(StaticHtml, { value: children }) : children),
element
);
so I think it should be fixed now. I couldn't quite replicate the issue locally too. Closing this for now but feel free to let me know if the issue still persists!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
- P4: important Violate documented behavior or significantly impacts performance (priority) pkg: preact Related to Preact (scope)
Projects
None yet
Development

Successfully merging a pull request may close this issue.

3 participants