Stencil version:
@stencil/[email protected]
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.
I'm also having this issue.
Could be worth it to revisit this issue as well, as I believe they're related.
@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.
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:
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.
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.
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
}
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');
}
};
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.
Most helpful comment
Currently, the visibility hidden functionality works with either a class or an attribute. This is configured via the
hydratedFlagstencil 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
:notselector 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:New option
"global"would let devs add these styles to the configuredglobalStylefile. This file would then receive the following CSS: