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

Rehydration of prerendered page results in flashing of some components #2245

Closed
realityfilter opened this issue Mar 6, 2020 · 9 comments
Closed

Comments

@realityfilter
Copy link

Stencil version:

This affects also the current 1.8.x version of stencil.

I'm submitting a:
[x] bug report
[ ] feature request
[ ] support request => Please do not submit support requests here, use one of these channels: https://stencil-worldwide.herokuapp.com/ or https://forum.ionicframework.com/

Current behavior:
We prerender our site and have noticed flashing of parts of the site during rehydration.
For instance all stencil-route-link components toggle their visibility because of the
hydrated class getting removed and added again. We tried the new feature of specifying a hydratedFlag of null but this leads to even more flashing. One promising workaround is to remove the hydrated class from the final prerendered html. No flashing. But the first initial paint is now slower because the site is now visible after all components are loaded and rehydrated.

Expected behavior:
No flashing of components because of their visibility change during rehydration.
At least it would be nice to have an option for the prerender step to remove the hydrated flag from the final html output.

@ionitron-bot ionitron-bot bot added the triage label Mar 6, 2020
@harrysolovay
Copy link

harrysolovay commented Apr 9, 2020

I'm also having this issue.

Could be worth it to revisit this issue as well, as I believe they're related.

@harrysolovay
Copy link

@realityfilter I believe this issue is often caused by how the prerendered assets are served. If you're always serving the www/index.html, this is expected, as the first paint occurs before hydration, at which point the router/other dynamic components get to work. How are you serving your web pages? Are you by chance running a local serve -s www? That was the culprit in my case.

@realityfilter
Copy link
Author

Sorry for the late reply. The problem still exists with current stencil version 1.15.0.

@harrysolovay I checked the static site files the following way:

  • stencil build --perender
  • all pages are assets are now available in www folder
  • serving via
    • docker run --rm -p 8080:80 -v "$PWD":/usr/local/apache2/htdocs/ httpd:2.4
    • python -m SimpleHTTPServer

So the correct html file for that specific page gets served and no fallback root index.html.

The flickering is even visible when reloading the dev server.

@eriklharper
Copy link

I'm also having this issue and I'm running the latest stencil 2.0.3. I'm using the hydratedFlag config option and I see a flash of default styling. We're using this config option so that when our components are used, the consuming apps can set classNames on our elements without conflicting with the hydrated class.

@paulcpederson
Copy link

Currently, the visibility hidden functionality works with either a class or an attribute. This is configured via the hydratedFlag stencil config option. Either way, Stencil generates a set of styles for you and adds them to a <style> tag in the head of the document. Until this style tag is added, the content will be visible. So there will be a flash of content.

If possible, a great enhancement to stencil would be the ability to configure stencil to put these styles in your global CSS file. This would enable you to hide things prior to all the javascript running.

As for the content in the style tag, it would be much better to use a :not selector here so that you're not fighting these rules for components that should be hidden even when hydrated (ie. modals, tooltips, dropdown menus). Here is a proposed API + CSS set:

hydratedFlag: {
  selector: "attribute",
  name: "hydrated",
  property: "visibility",
  initialValue: "hidden",
  hydratedValue: "inherit",
  output: "inline" | "global"  // this is the new option that allows configuring where hydrated CSS lands
},

New option "global" would let devs add these styles to the configured globalStyle file. This file would then receive the following CSS:

component-1:not([hydrated]), component-2:not([hydrated]) {
  visibility: hidden
}

@antongvrlnkv
Copy link

antongvrlnkv commented Oct 26, 2020

My solution based on @realityfilter workaround to remove "hydrated" class from "html" tag:

prerender.config.ts:

import { PrerenderConfig } from '@stencil/core';

export const config: PrerenderConfig = { 
  afterHydrate(document, url) { 
    document.getElementsByTagName('html')[0].classList.remove('hydrated'); 
  } 
};

@driskull
Copy link

driskull commented Dec 7, 2020

Although the above solution works. Its not very elegant to have to remove the class or attribute after it's already been added to the node. Some components could be visible until that code has been executed.

It would be much more preferable if a component were able to not be automatically hydrated in the first place.

Currently, every component is expected to have visibility: visible by default. We have some components (alerts, tooltips, modals) that should not be visible by default.

@splitinfinities
Copy link
Contributor

Hey there, thank you for the patience getting back to you. The new team is getting started and we're working through the backlog now.

This should be addressed by PR #2989 once merged, allowing you to opt-out of the injected prehydrated style tag.

@rwaskiewicz
Copy link
Member

The fix for this issue has landed in the main codebase and is a part of the Stencil v2.8 release. Thanks for you patience!

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

No branches or pull requests

8 participants