ElMassimo / iles

🏝 The joyful site generator
https://iles.pages.dev
MIT License
1.08k stars 32 forks source link

Hydration issue with client:visible #246

Closed TechAkayy closed 1 year ago

TechAkayy commented 1 year ago

Description πŸ“–

My HeroSection is using client:load. The other four components (vue, svelte, tsx, jsx) uses client:visible. When the first client:visible component comes into viewport, all the other component below it are loading immediately without waiting for their turn to come into viewport.

Reproduction 🐞

https://github.com/techakayy/nature-delights-with-iles

Video on youtube - https://www.youtube.com/watch?v=dl1_opZnZm0

Due to current peer dependencies issue, to install use the force flag. Use command npm install --force

Dependencies Info _Run `npx iles info` and `pnpm list` (or `npm list`) and provide the output:_ ``` iles v0.8.7 vite v3.2.5 nature-delights-with-iles@0.0.0 /Users/techakayy/Projects/iles/nature-delights-with-iles β”œβ”€β”€ @headlessui/vue@1.7.12 β”œβ”€β”€ @heroicons/vue@2.0.17 β”œβ”€β”€ @iconify/json@2.2.46 β”œβ”€β”€ @nutui/nutui@4.0.4 β”œβ”€β”€ @nuxt/eslint-config@0.1.1 β”œβ”€β”€ @pinegrow/iles-module@3.0.0-beta.102 β”œβ”€β”€ @pinegrow/tailwindcss-plugin@3.0.0-beta.48 β”œβ”€β”€ @preact/preset-vite@2.5.0 β”œβ”€β”€ @sveltejs/vite-plugin-svelte@1.0.9 β”œβ”€β”€ @unocss/preset-icons@0.50.6 β”œβ”€β”€ @vue/devtools@6.5.0 β”œβ”€β”€ @vueuse/core@9.13.0 β”œβ”€β”€ autoprefixer@10.4.14 β”œβ”€β”€ eslint-config-prettier@8.8.0 β”œβ”€β”€ eslint@8.37.0 β”œβ”€β”€ iles@0.8.7 β”œβ”€β”€ node-html-parser@6.1.5 β”œβ”€β”€ postcss@8.4.21 β”œβ”€β”€ preact-render-to-string@6.0.2 β”œβ”€β”€ prettier@2.8.7 β”œβ”€β”€ tailwindcss@3.3.1 β”œβ”€β”€ typescript@4.9.5 β”œβ”€β”€ unocss@0.50.6 β”œβ”€β”€ unplugin-vue-components@0.24.1 └── vue-tsc@0.38.9 ```

Logs πŸ“œ

If not providing a reproduction:

Output _Run `DEBUG=iles:* npm run dev` or `DEBUG=iles:* npm run build` and provide the output:_ ``` iles:config loaded config at /Users/techakayy/Projects/iles/nature-delights-with-iles/iles.config.ts +0ms iles:config { iles:config root: '/Users/techakayy/Projects/iles/nature-delights-with-iles', iles:config modules: [ iles:config { iles:config name: 'iles:base-config', iles:config debug: true, iles:config drafts: true, iles:config turbo: false, iles:config jsx: 'preact', iles:config root: '/Users/techakayy/Projects/iles/nature-delights-with-iles', iles:config base: '/', iles:config siteUrl: '', iles:config prettyUrls: true, iles:config ssg: [Object], iles:config configPath: '/Users/techakayy/Projects/iles/nature-delights-with-iles/iles.config.ts', iles:config assetsDir: 'assets', iles:config pagesDir: 'pages', iles:config srcDir: 'src', iles:config outDir: 'dist', iles:config layoutsDir: 'layouts', iles:config tempDir: '.iles-ssg-temp', iles:config modules: [], iles:config namedPlugins: {}, iles:config resolvePath: undefined, iles:config vitePlugins: [], iles:config vite: [Object], iles:config vue: [Object], iles:config extendFrontmatter: [AsyncFunction: extendFrontmatter], iles:config extendRoute: [Function: extendRoute], iles:config extendRoutes: [Function: extendRoutes], iles:config markdown: [Object], iles:config components: [Object] iles:config }, iles:config { iles:config name: '@islands/mdx', iles:config markdown: [Object], iles:config configResolved: [Function: configResolved] iles:config }, iles:config { iles:config name: 'user-config', iles:config jsx: 'preact', iles:config svelte: true, iles:config components: [Object], iles:config vite: [Object], iles:config siteUrl: 'https://pg-iles-tailwindcss.netlify.app', iles:config extendRoutes: [Function: extendRoutes], iles:config configPath: '/Users/techakayy/Projects/iles/nature-delights-with-iles/iles.config.ts' iles:config }, iles:config { iles:config name: '@pinegrow/iles-module', iles:config vite: [Object], iles:config config: [Function: config] iles:config }, iles:config { iles:config name: '@islands/pages', iles:config configResolved: [Function: configResolved] iles:config }, iles:config { iles:config name: 'iles:base-config', iles:config debug: true, iles:config drafts: true, iles:config turbo: false, iles:config jsx: 'preact', iles:config root: '/Users/techakayy/Projects/iles/nature-delights-with-iles', iles:config base: '/', iles:config siteUrl: '', iles:config prettyUrls: true, iles:config ssg: [Object], iles:config configPath: '/Users/techakayy/Projects/iles/nature-delights-with-iles/iles.config.ts', iles:config assetsDir: 'assets', iles:config pagesDir: 'pages', iles:config srcDir: 'src', iles:config outDir: 'dist', iles:config layoutsDir: 'layouts', iles:config tempDir: '.iles-ssg-temp', iles:config modules: [], iles:config namedPlugins: {}, iles:config resolvePath: undefined, iles:config vitePlugins: [], iles:config vite: [Object], iles:config vue: [Object], iles:config extendFrontmatter: [AsyncFunction: extendFrontmatter], iles:config extendRoute: [Function: extendRoute], iles:config extendRoutes: [Function: extendRoutes], iles:config markdown: [Object], iles:config components: [Object] iles:config }, iles:config { iles:config name: '@islands/mdx', iles:config markdown: [Object], iles:config configResolved: [Function: configResolved] iles:config }, iles:config { iles:config name: 'user-config', iles:config jsx: 'preact', iles:config svelte: true, iles:config components: [Object], iles:config vite: [Object], iles:config siteUrl: 'https://pg-iles-tailwindcss.netlify.app', iles:config extendRoutes: [Function: extendRoutes], iles:config configPath: '/Users/techakayy/Projects/iles/nature-delights-with-iles/iles.config.ts' iles:config }, iles:config { iles:config name: '@pinegrow/iles-module', iles:config vite: [Object], iles:config config: [Function: config] iles:config }, iles:config { iles:config name: '@islands/pages', iles:config configResolved: [Function: configResolved] iles:config } iles:config ], iles:config debug: true, iles:config drafts: true, iles:config turbo: false, iles:config jsx: 'preact', iles:config base: '/', iles:config siteUrl: 'https://pg-iles-tailwindcss.netlify.app', iles:config prettyUrls: true, iles:config ssg: { sitemap: true }, iles:config configPath: '/Users/techakayy/Projects/iles/nature-delights-with-iles/iles.config.ts', iles:config assetsDir: 'assets', iles:config pagesDir: '/Users/techakayy/Projects/iles/nature-delights-with-iles/src/pages', iles:config srcDir: '/Users/techakayy/Projects/iles/nature-delights-with-iles/src', iles:config outDir: '/Users/techakayy/Projects/iles/nature-delights-with-iles/dist', iles:config layoutsDir: '/Users/techakayy/Projects/iles/nature-delights-with-iles/src/layouts', iles:config tempDir: '/Users/techakayy/Projects/iles/nature-delights-with-iles/.iles-ssg-temp', iles:config namedPlugins: { iles:config components: { iles:config name: 'unplugin-vue-components', iles:config enforce: 'post', iles:config api: [Object], iles:config transformInclude: [Function: transformInclude], iles:config transform: [Function (anonymous)], iles:config vite: [Object], iles:config webpack: [Function: webpack], iles:config configResolved: [Function: configResolved], iles:config configureServer: [Function: configureServer] iles:config }, iles:config vue: { iles:config name: 'vite:vue', iles:config handleHotUpdate: [Function: handleHotUpdate], iles:config config: [Function: config], iles:config configResolved: [Function: configResolved], iles:config configureServer: [Function: configureServer], iles:config buildStart: [Function: buildStart], iles:config resolveId: [AsyncFunction: resolveId], iles:config load: [Function: load], iles:config transform: [Function: transform] iles:config }, iles:config pages: { iles:config name: 'iles:pages', iles:config enforce: 'pre', iles:config api: [Getter], iles:config configResolved: [AsyncFunction: configResolved], iles:config configureServer: [AsyncFunction: configureServer], iles:config buildStart: [AsyncFunction: buildStart], iles:config resolveId: [AsyncFunction: resolveId], iles:config load: [AsyncFunction: load], iles:config transform: [AsyncFunction: transform] iles:config } iles:config }, iles:config vitePlugins: [ iles:config [ [Object], [Object], [Object], [Object] ], iles:config [ [Object], [Object] ], iles:config { iles:config name: 'iles:mdx:compile', iles:config configResolved: [AsyncFunction: configResolved], iles:config transform: [AsyncFunction: transform] iles:config }, iles:config { name: 'iles:mdx:sfc', transform: [AsyncFunction: transform] }, iles:config { iles:config name: 'iles:mdx:hmr', iles:config apply: 'serve', iles:config transform: [Function: transform] iles:config }, iles:config { iles:config name: 'iles:pages', iles:config enforce: 'pre', iles:config api: [Getter], iles:config configResolved: [AsyncFunction: configResolved], iles:config configureServer: [AsyncFunction: configureServer], iles:config buildStart: [AsyncFunction: buildStart], iles:config resolveId: [AsyncFunction: resolveId], iles:config load: [AsyncFunction: load], iles:config transform: [AsyncFunction: transform] iles:config }, iles:config { iles:config name: 'iles:mdx:compile', iles:config configResolved: [AsyncFunction: configResolved], iles:config transform: [AsyncFunction: transform] iles:config }, iles:config { name: 'iles:mdx:sfc', transform: [AsyncFunction: transform] }, iles:config { iles:config name: 'iles:mdx:hmr', iles:config apply: 'serve', iles:config transform: [Function: transform] iles:config }, iles:config { iles:config name: 'iles:pages', iles:config enforce: 'pre', iles:config api: [Getter], iles:config configResolved: [AsyncFunction: configResolved], iles:config configureServer: [AsyncFunction: configureServer], iles:config buildStart: [AsyncFunction: buildStart], iles:config resolveId: [AsyncFunction: resolveId], iles:config load: [AsyncFunction: load], iles:config transform: [AsyncFunction: transform] iles:config } iles:config ], iles:config vite: { iles:config root: '/Users/techakayy/Projects/iles/nature-delights-with-iles', iles:config resolve: { alias: [Array], dedupe: [Array] }, iles:config server: { fs: [Object] }, iles:config build: { cssCodeSplit: false, assetsDir: 'assets' }, iles:config define: { 'import.meta.env.DISPOSE_ISLANDS': true }, iles:config optimizeDeps: { include: [Array], exclude: [Array] }, iles:config css: { preprocessorOptions: [Object] }, iles:config plugins: [ [Array], [b], [Object], [Array], [b], [Object] ], iles:config base: '/' iles:config }, iles:config vue: { iles:config reactivityTransform: true, iles:config template: { compilerOptions: [Object] } iles:config }, iles:config extendFrontmatter: [AsyncFunction (anonymous)], iles:config extendRoute: [AsyncFunction (anonymous)], iles:config extendRoutes: [AsyncFunction (anonymous)], iles:config markdown: { iles:config jsxRuntime: 'automatic', iles:config jsxImportSource: 'iles', iles:config providerImportSource: 'iles', iles:config rehypePlugins: [ [Array], [Array] ], iles:config remarkPlugins: [ iles:config [Array], [Array], iles:config [Array], [Array], iles:config [Array], [Array], iles:config [Array], [Array] iles:config ], iles:config recmaPlugins: [ iles:config [Function: recmaVueResolveComponents], iles:config [Function: recmaVueResolveComponents], iles:config [Function (anonymous)], iles:config [Function (anonymous)] iles:config ] iles:config }, iles:config components: { iles:config dts: true, iles:config extensions: [ iles:config 'vue', 'jsx', 'tsx', iles:config 'js', 'ts', 'mdx', iles:config 'svelte', 'vue', 'jsx', iles:config 'tsx', 'js', 'ts', iles:config 'mdx', 'svelte' iles:config ], iles:config include: [ iles:config /\.vue$/, iles:config /\.vue\?vue/, iles:config /\.mdx?/, iles:config /\.vue$/, iles:config /\.vue\?vue/, iles:config /\.mdx?/ iles:config ], iles:config dirs: 'src/components', iles:config resolvers: [ iles:config [Function: IlesComponentResolver], iles:config [Function (anonymous)], iles:config [Object], iles:config [Function: IlesComponentResolver], iles:config [Function (anonymous)], iles:config [Object] iles:config ], iles:config transformer: 'vue3' iles:config }, iles:config svelte: true iles:config } +0ms ```

Screenshots πŸ“·

Provide console or browser screenshots of the problem.

ElMassimo commented 1 year ago

Hi!

When running the app locally, and adding a debugger, the IntersectionObserver calls the hydration callback and isIntersecting is true.

Screen Shot 2023-04-07 at 13 33 00

Notice that Testimonials (the last section) is actually visible.


This happens because non-Vue islands are not "pre-rendered" in development, so these islands have "zero height" until hydrated, and in this case that means that sections beneath it also become "visible".

I'd suggest ignoring it, as once you build the site, the sections will be pre-rendered, and you wouldn't run into this scenario.

TechAkayy commented 1 year ago

Interesting. Thanks for looking into this & for the detailed explanation Max πŸ™πŸΎ! I build & deployed it to netlify and its hydrating fine as expected 😎