QwikDev / qwik

Instant-loading web apps, without effort
https://qwik.dev
MIT License
20.77k stars 1.29k forks source link

[✨] useOnVisible #5291

Open GrandSchtroumpf opened 1 year ago

GrandSchtroumpf commented 1 year ago

Is your feature request related to a problem?

Currently useVisibleTask$ runs:

This means that we cannot rely on it to lazy query data for example, as it'll be trigger eagerly with soft navigation.

Describe the solution you'd like

As qwik loader already has an IntersectionObserver, I think it could trigger a callback when the element is visible.

export const Item = component$(() => {
  useVisibleTask$(() => {
    // Triggered lazily on MPA
    // Triggered eagerly on SPA
  });
  useOnVisible$(() => {
    // Triggered lazily on MPA & SPA
  });
})

Describe alternatives you've considered

Create a local hook for that, but it might be difficult to optimize.

function useOnVisibleQrl(cb: QRL<() => void>, options) {
  const ref = useSignal<HTMLElement>();
  useVisibleTask$(() => {
    const observer = new IntersectionObserver((entries) => {
      for (const entry of entries) {
        if (!entry.isIntersecting) continue;
        cb();
        obserser.disconnect();
      }
    }, options);
    return () => observer.disconnect();
  })
}
const useOnVisible$ = plicit$FirstArg(useOnVisibleQrl);

Additional context

No response

wmertens commented 1 year ago

Hmm I wonder if that's a bug. useVisibleTask should fire only when visible, IMHO.

Here's a repro showing visible running on mount in client: https://qwik.builder.io/playground/#v=1.2.13&f=5VjBchJBEL3nK8ZEwxLZZYEEqC3AysEqPWhZxruBBJKpEKBgExKBs0d%2FxA%2Fwe%2FwBf8HX3TOzLFkQqiwvVlKwO9Pd0z3T8%2Fo1y0lTrVeysqbgaq48MVqZQa5g%2FLyMepvyzCxgoM%2FuGeN4ACx5pQeonN1tE1J2917WxgY7%2F7xeuz%2Fp5p2IgJ6U6NPxuP3oVcN80NP9vkfImQ9Qsz3vc0HgkO3nuILm1EszBpfEmuUUuQ%2BnH1%2B%2F%2F5TDzOqBEleyOz9KGMLMeJ6yEg%2BvrvpdWLFxBIAWFI2mepYaWCySw2V7CggfD%2FFP%2BlIKA3fcoxa5Kw4kej%2B%2Ff%2F3145tqCLtqnV0QUALUp4NG0YwpFFgN%2BgE4luoKbAbiEyRnWr%2FrJ%2BZnvM2yl5pDlf0won3dmulFo4hvN5zPL5xVMmVeZum9ODxUDSnExZbICx81eUxnk7pvItvMTpol7iVpmBwtJSbVTMkkevRIQzF9ilRY4BehWe5VCJl5ZV94jRQPSFZfySEQYnhtMziGsOST9cdQs2XsSCbB%2BkxOEwn0jCI8Is8BwkwUITCcBqjsZ%2Fw%2BgaEj5RF7KSpcgrSOYZBO5x2%2Fb9Zhauk03uAtJV8qG3nADX1JRNZZCUQIUpMY5luirDh1T%2BQKqhSGdkV7yXgrmGE4abbAYuYEUrssmC9psea%2BSiPT3Oek33e3d2kmnnZBxPZbLvWeCKCB2TQ%2F0Q8bZgfAvQ3TtMv7tj2ZJVw9UudCv73ns%2BQ8FuDW%2BXMFzFhrUI56O5Miu4VRybntjIpsptHV2z0vhfOkSMxL5XppXjwy11wPJiM9RlfTeYxcjzFC0UBDEFwMg7ubopAlv%2B2zDV8PfOKtR8W9vUBAju5V0kZE6qDX61GagFAicSIk4ehBIZ%2F0pTqotekvmfXH7Ut9B2ZxEr6Q0Qd%2For%2BAQkRWAkM0c93VV9dxpCohzNHALboTPQB0qDZaCxoZDSeamElEhB%2B8875Lo1N9GV87vQXclmQs4IGSDt9ILnxSEj0NplKppG23O4gFJ7piCzZY2fpJUS8tf%2BwWN2u61awCSzh5UU9WYNF%2BtwdBs1XxcBQpv5SyK%2FxI7MmUkWMdErNupkx1hvhZAlmWWHPeiVy2LQav5RCqGTFvv51Z8dWNxfZA33InEaEVRM4dV8phSMW1pwconPSTARCNJP1pt3OjY39bDQrEIHf6%2BP4cS61W2yWW4zWxAOp3C2WNAh%2Bv1K1UJOV0JJWMSHoX4Ul4sksw1uiqb9XdQskUt7mFWyInQ9crCczBoo8mlyGgDIDBgbF3dqVNUmhG%2Frd%2Bq177J%2F0WV5W%2F32r9Bg

GrandSchtroumpf commented 1 year ago

@wmertens According to mhevery this is how it's working "for now" :

Once the app is running in the client useVisibleTask executes eagerly.

From his comment

I think it can be confusing as developer might think it always execute code when the element enters the viewport.

iamriajul commented 10 months ago

Is there any update?

mhevery commented 10 months ago

We are thinking of making it lazy, but it is dependant on other features landing first.

gioboa commented 1 week ago

is this still valid?