QwikDev / qwik

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

[🐞] conditional rendering around Slot causes browser rerender of slot contents #5425

Open VarPDev opened 10 months ago

VarPDev commented 10 months ago

Which component is affected?

Qwik Runtime

Describe the bug

By placing a component inside the layout.tsx file after the slot, visible via a signal value a rerender of the entire slot takes place

You can play it back by clicking on the switch at the top right of the header. Once the kitten appears click again to make it disappear and you will notice that the get resume button, in the hero section, will do the entry animation, this means that the component has been reloaded.

layout.tsx code below:

export default component$(() => {
  const show = useSignal(false);

  return (
    <>
      <Header show={show} />
      <main>
        {show.value && <Cat />}
        {/* If I move this after the Slot, on value change slot reload */}
        {/* {show.value && <CatWalk />} */}
        <Slot />
        {show.value && <CatWalk />}
      </main>
      <Footer />
    </>
  );
});

if you move {show.value && <CatWalk />} before the slot, it don't reload

The full repo: https://github.com/VarPDev/pako

Reproduction

https://pako-git-ssr-varpdev.vercel.app/?_vercel_share=DU0WyukXXApiQswlWQPBtLb2pXz3168A

Steps to reproduce

No response

System Info

System:
    OS: macOS 13.1
    CPU: (8) arm64 Apple M1
    Memory: 62.70 MB / 8.00 GB
    Shell: 5.8.1 - /bin/zsh
  Binaries:
    Node: 21.1.0 - ~/.nvm/versions/node/v21.1.0/bin/node
    Yarn: 1.22.19 - ~/.nvm/versions/node/v21.1.0/bin/yarn
    npm: 10.2.0 - ~/.nvm/versions/node/v21.1.0/bin/npm
  Browsers:
    Chrome: 119.0.6045.123
    Safari: 16.2
  npmPackages:
    @builder.io/qwik: ^1.2.15 => 1.2.15 
    @builder.io/qwik-city: ^1.2.15 => 1.2.15 
    undici: ^5.26.0 => 5.27.0 
    vite: ^4.4.11 => 4.5.0

Additional Information

No response

wmertens commented 10 months ago

@VarPDev can you make a minimal repro in https://qwik.builder.io/playground?

VarPDev commented 10 months ago

@wmertens I can't use the playground well. You can clone the repository I linked though, run npm i and npm run dev. You can find the code on the "layout.tsx" page.

It's a simple site, nothing complex

wmertens commented 10 months ago

@VarPDev Here's a playground (very cute cat btw), I can't reproduce your issue?

https://qwik.builder.io/playground/#v=1.2.17&f=7Vtbb%2BO2En7vr9Dxom1SRI6v8eUkwVn0qTjFOS8Fto%2BVYysW1omN2IvdpN3%2F3m9mSJGUSEpKt0ALdLNOLJGcO2eGQ9I2mtF84DWbi4Qs%2BcJEYfkq4UvLv1fVVw8yUAFe3NxN8stXfUyl1HLXJIrD%2FliQLpZJXnzarP%2BNV9tNcb89LZPhbHD4RC8%2BFuvTFs%2BLUX8ob077wzKZDr6m77tNjs7q4QEOv3hMuT2dT9E7ufwu%2Bd8Gs7aAG91muzzZ5wpFP%2Fnu0owROOniKjSIyVBjXlL2nOg%2FJLT7Q3ZXnJ6XyaA%2FIkupctqHO6ywm63g2eEXSnbSsbCg2b%2BSR8X8aMpPBuYyeZPneQjZcrnaIJZvLgKtWY7UgCki9w09L5MedBYicLVH1vcAKiYOiUOHREXh%2Fgl2kD5l6%2BID5pvSi0P38Ip%2BwqQb4sqcJEU0gJIYHtASUP%2FolPXIg5VCZz6yZgADeSfy%2F5JByi%2F%2Bz0rRuJcqwzlLh1MkLewKwqjjktd9DIvgqxRlHK5HLIa0SQNpjMZG6JcLyYRk00kuTWIRjA1yUZ0Mk6K%2BqFxqY%2Bq0ReTCmXF4Uhojd6xcP3ot2m%2F%2BPvKfY6jZH4xlPmkylHdQVIyHAXfgo8D5XJJj4c9EPiH6OjsJpnpgXDJ%2F1eTzQ1WELqUD%2FAiVb5%2BesudL%2BYOXJaFBqWePxQOnactkxWuvCXLcx7x4RLqbbLLjBu6a%2BPzP%2B81z%2FoTkGItA7kfMATr9qdD6GZ9FpGnUn1YbNV%2FcXms1Q2fxoTzdvGNDipKZ1VFTKr74ffkwFG66WHjNF4ONWE%2BHEe2miJDQoJpTiyBwnJAdHyIIDh8Oxa5pnqrIrOWoAp4O252dhWPMu%2F3%2BfZoJRZZJV0zZ7uUYtOUO%2BeuOPOIA3lAMrbRCbz9Qc5Gk4K7sDxPpOCCOISVLrwyBwDoPiWMZXCSGZWtuNXWO2nTFPJT5sY%2BOG2tloNhgbBz3fZ0vViHDnknGTpVl6njSOnkLJZ0PH15eUCJomCzK6Tg5e5nwumE26IB8ivv5LAU01lxj%2FKMcR%2Bc5%2BBA3XyHf%2F%2F7tT8m7tz%2F%2BlxJ8Ye9jtnufmvJGYLlSLgUW%2BFeh73iX7WBU%2FSlTVs9mxSYku3anPpsoqKL5nhIxL8V9%2BpLdJzMUJiWgpVRcGaCaM7yQRUlS9k7G8AogGquO4QW3MC%2FKR4wGZeu4P7Ldiu1ITdbPXtV2OCUax9vo7vOxL5RZwGR2%2BQCWXMYAu0S6jsnOpqsORbWNyiYyAneYzAJqo5zDaZN0md1mbZgBSXmV01bSSNbmtMzLQfPaIJNGRDgLCbeK2xW1bQiOlO1BNXVZwUL1k5Wg6Uhr7ZA6hFUPUBMgXFF6wdY0ORSP4YFrQoJWuojNC7dmBmqV64ELN1npWmXNglszoXGVuRLupAp3XGXNgluzP5Ub%2B5TWBW7NdsP0XnWRQ83yw%2FKdddFbbdqE7WHexc5qcy5ovibJbzMp2s00zFZf8HmDv7FU1CliTVThzK6G6XemvOQU1%2BbqUaInucLDpwTgi3XyZj1ezRczb2yVQdhZOmA7YAk%2FTnElXdGuiRMbJYQEGUsfsF%2FSzJ3DiMMxpOuyN3bZmylNmHwCJOz2YFRnFTapCNUoq6co5t%2BDkDtkW5snzrWy9Rq1YaFjJBD1O6FjJi817AH%2Fa%2BAddeeWrF%2BNfaxrVk3d1C2bqsem3K4UiFF3KRMUOUMsUGW5Qj42q7hy6hBVUchwqA2uTsBmcbfKfPY2UjIP2tseewQ59uSWyRb7JC1Z8BRnbQ6ckvKoIuuJsitdAm3DVPNs4RqyX9xU9ypX1dhsO6SHjDAf9rvne2xToYiCJYzU7C7E6cCvcwEsDNCsox3Lokq4H4tUBBkRoCs89CuMiCt2xWM9kfZZS8VYImL1GOs4zizTYGRoq3fumV5KwSFRM%2BeIGJBFgwAs5DV5B7GnkwYd2MInGkBKhASPm7XFHzVbdx4s3HmgNVSb3V6nU6pqEiYVzGLnueW01OhLwNOwHeY4CkFgtW0FTetukC3mq8iMjWBY5sXT8ZTu85Q3OWtTS6VspXdUVMB3ZXikPnHwj6etBn42km1MF35FPX8A%2FLgZvNZ2G%2FhvUNQ4ttSrKmC00aouqJckqdmkDVI9tg6C0%2BlkPYF5dlU%2BsVdzLiK0ES0hY8MCblhtgfj5Pm7x1%2BHcjf5dg7%2FKhmwtqKDr0kTvQrx8xImO90YIHWcPj1ZRoowHDk%2Bj8Jw14UCRq7NrjmVxgrHfHdhEMhtcsfEnnGALQbC2Dv0gHvc4xtMyvVdlilC%2Bp009ZtRWPMH5guJwxE4Zosho9HWCso6qlXHRqjlb4Z3cmGCMXQeBuSG3hbJyOtH2SlkLhGPx6ZXqPj4UtUqnx4WpWb%2BoH0yAmFv6NcHFoGQ5Ehejz3iaIbuO043kOuH17NVRz7J7izSePYleU2pTjGUq%2FiQtncp6vEzB%2FfSG6YkLhI21jaxdLevVYGcFmMnxV9SAP1NtUIF6fIUKcLT4Hicm22UHyu05eshwRtN6qSot%2Bm3IY%2Bp4UlltRmoGd4tBhlnbLpU9fXh4kDWyTf5QqtmvIL%2ByOtKVHE9xRn7BVEJ8TDazdWRxj2OGa5yoDcelHH3TPIMlY4Yc4UhTHNQrOIXgpiOOQ1K1zS2LrBb0U9On4kPNKH76%2FEvlLN332ekdiMR5stgZxerJOpxel6PqN706mz3r2Bx1LNY3PSrM9G7l2Lu%2FlUtWvdt3%2F38X7YXiTgmn3oWKJxZ6l1KsF3vcS6%2F5nZ61vrK2NCPMOrfGiD7Q3wYx2%2BBrMKuBIdRV3DRYRBrpwIvCCDFYu3gwfqk%2BEcJoURMT0vNGiUetDip93d6c00t%2F%2FhpSokeNEbQ%2BRTbgDanQZz9h2ZjlQERCKusX7GU%2B3qgoPaxtPws8p%2BvdtExJetQ%2BrXy3G6%2BUzv6ZzCLZ7cYqJyc%2BHspGKyn1W5Xb00t1Ze43GnqMHCtxa6InbNdVgr7MDJC0xqeAsgelCPWAYz9aD%2BYMNz61%2BPjHYqPJEqpx0Th8nEBQp1L9MbLa0y9Fx%2BHiLGY4EKK2Ux69iXtZOS7TOeBpBI3B7rUY5HTMl1Dwj9kznfsI6Ni%2B9fatupGF1QtGfHuOZuvimZzLPyd7VQf1t7jLdGPO%2BZ%2Fl2e64IfxB05HLgOYO3K9n5ze3BKeP%2BzHI42%2BSf5mnz7c%2F7e%2Fvd5vyDqGGQneKjEh%2BtcZ%2F801yTQZ9eUs7qKodh2J%2ByJMfcL0JZ%2FNPdHlIzkbRrTW5qgCSZPzdNnuk24R4S6sI3PnBQRkD6pq6m1sSXtycbBr815eG2oiS5NJGBx3xAFZR5ZYNXbABgvgNHQAm1fgA87WY8%2BS339B%2BLbajqBcamYfrS91yfv7PRZ6%2F4UWe3wE

VarPDev commented 10 months ago

Yes is a cute cat ahah

The console.log, was not triggered again, but the html was rerender. If you can add tailwind in playgroud, add this button

<Link href="/" target="_blank">
  <button class="btn btn-primary text-black">Text button</button>
</Link>

in Hello component and when the cat disappears, you can see the button have a entry animation again

wmertens commented 10 months ago

@VarPDev on my phone but you can add TW by including the CDN css link in the root.tsx tab

wmertens commented 10 months ago

Ok here's a simpler playground with the problem. The animation on Hello should only happen on initial render, but instead it happens every time you click Toggle to make the before and after disappear.

https://qwik.builder.io/playground/#v=1.2.17&f=7VZbTsMwEPzvKUwkaCLlCX2gpqk4ABI%2FHKBp65SINK0SKlSq3J1Z28VxlSIhvpD4c%2BSM157dnR2jaEZhV9W4jArZ1UNYLuX0OtFvnafLAgVqvkuVS9i856dlviGhJQrkGknwVvtKLCYs9MfDOr6wGdUxC4JqX5bCSUB4SU4xEF8gwTzLoJ8mkgSKzjw%2FkrRxor65l0EHzH0INSJ4p8KBx9kv8qW34B85Os%2B%2FHbn%2B8M71xwM38gf3ILINzvKi8DbbFSLQXHpPq9Vvw%2FO0xi9N7%2BGVH7IK6NpACzbDayRtu0uX%2BRu9OdbDfMLqZVpwGzy4RIYTN%2Fg%2FCk1E1IGIXBY5MWsQem7W82N6IF1PumWibbz6yhQgFUD0nZ7aR11Q2hJdVjaNSpB5uTuk89SG62g7yYyO8SHGGLMJu9Jfzex5u14X%2FMuwnk6hAabb5NjC39yQtC04OABsNyOeFIhaQHdTFyzNYLXaqGmgI%2BmWowcaVD7BEFSkDceywXOE3cZS%2Bm3zVykEPyBdAMC5Vm4cKh17YqkSsqS%2BqHgNEvTdJFDBWvZVtjfF6LqB0OTWBeypLB1Fi3yRIGcaqB2HLvE%2FS%2F7eLPkE

When you "inspect element" on Hello and toggle the button, you'll see the before and after components appear and disappear, but you'll also see that the Hello div flashes as being re-rendered. The component itself doesn't re-render but the browser does re-render the contents. (In your example site you can see that then entire page re-renders like this).

This doesn't happen the element before or after is a string (try it by selecting the entire <p>...</p> and quoting it), only if they both are elements.

Furthermore, when I do "store as global variable" on the Hello div and toggle and then store again, these two global variables are in fact the same.

Finally, the Render Stats say that 3 operations are being made and none of them touches the Hello component, so I don't understand why the browser thinks it's changing. When I manually call insertBefore() or remove(), it doesn't show the Hello element as changing.

Paging @mhevery, it looks like there is a bug with applying operations in this particular case?

genki commented 2 months ago

@wmertens The mutation of the child list can trigger the rerendering. Changed the forward <p> element to be kept, then the rerendering is not happened.

https://qwik.dev/playground/#v=1.2.17&f=7VbtTsIwFP3PU9QlwpZsgyqIMkZ8AH%2F6ABTocHF8ZJMYJHt3z12LXZdhYvxl4r8t7b23Pb33nGM1DX9o6xqfUSP7RoTVp1KvM%2FxO87kcQKD1XbFczOadUGzTDREtQaC%2B8QjB6pBXHxM2CMejIrqwyIuI9fv5YbutnASIl%2BgUgvgCCpZJAv60I4mgKGczJXHjRP%2FLIAEP2OsgalQIzo0Dj3NYpMtgIT9STF54c%2BeHo1s%2FHA99Hg7vAWQ9OEmzLNjsVqhAuvQu8tVvy0tRYEvZeXyVxyRHdGFFV2gOrvFou71Ypm9058iI%2BYQVS5FJFzj4BIYXldjPB3YEb4ngPuNexEqUntv9%2FCSOxOtxO03UjVdPmwI8BSJ6Xkevoy%2Fo2WLTVi5JJcC8PB3KeRrDdXK9eEZpQpAxZDZmV%2BavnD3v1utMfhnWcxYSsNqY7GenWopulzkLCRCkUxKzmX00BGaeGGtEIY9IYLYoiPBVg2ZqmaGjK1pgqvn%2BAZZVAKA0hAxvrox47OjOcBRtKNuOot8TvC5Wc6VqaqlG2wkqqq0dwJ2qjtB3VTeqbjzt6xWPDvEvEX9PIj4B