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

A way to render synchronously #4044

Closed
dmail opened this issue Jun 14, 2023 · 6 comments
Closed

A way to render synchronously #4044

dmail opened this issue Jun 14, 2023 · 6 comments

Comments

@dmail
Copy link
Contributor

dmail commented Jun 14, 2023

Describe the feature you'd love to see

I need a way to update the UI synchronously using preact. Ideally something like flushSync.

Additional context

In my use case:

  • preact is rendering some UI
  • code outside preact is updating the surrounding of that UI
  • when it happens we want to hide a button in the UI rendered by preact

Currently we see an intermediate state where the surrounding is updated and button is still displayed.
This intermediate state lasts <1ms, the time for preact to update the UI.
Intermediate states are undesirable as they cause blinks on the button.

With react I could do something like that:

import { flushSync } from "react-dom";
import { useState } from "react";

window.setButtonVisibility = () => {}; // called by external code

export const App = () => {
  const [visible, setVisible] = useState();
  window.setButtonVisibility = (value) => {
    flushSync(() => {
      setVisible(value);
    });
  };
  return <button style={{ display: visible ? "block": "none" }}>Hello</button>;
}

But in preact I don't know what I could do

Related

@JoviDeCroock
Copy link
Member

You can leverage something like

import { options } from "preact";

function myCrucialUpdater() {
  let oldDebounce = options.debounceRendering;
  options.debounceRendering = fn => fn();
  update();
  options.debounceRendering = oldDebounce;
}

@dmail
Copy link
Contributor Author

dmail commented Jun 14, 2023

Ohhh, nice 💯 .
We are going to try this (it will take a bit of time) and I'll come back to let you know how it goes.

@JoviDeCroock
Copy link
Member

Hey @dmail did this work out for you?

@dmail
Copy link
Contributor Author

dmail commented Jun 26, 2023

Hi @JoviDeCroock,

Short answer
In the end we found a second source of desynchronization. So rendering synchronously was not enough to fix our issue.

Detailed answer
In our scenario we have a root page without preact embedding an iframe with UI rendered by preact.
The communication between the parent page and the iframe is done via postMessage.
When parent page tells to the iframe to update via postmessage, the browser waits a bit before executing js inside the iframe. So preact is notified too late, rendering synchronously would not be enough to catch up.

In our case instead of doing things in sequence and synchronously:

1. send message to iframe using postMessage
2. update UI in the parent page

We are waiting between step 1 and 2 (using setTimeout for now)

1. send message to iframe using postMessage
+2. wait for the iframe UI to be updated
3. update UI in the parent page

This way there is no intermediate state displayed to the user.

@dmail
Copy link
Contributor Author

dmail commented Jun 26, 2023

Thank you very much for the help and reactivity ❤️

@JoviDeCroock
Copy link
Member

Awesome, glad to hear you got this resolved. I'll close this issue out then :)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

2 participants