Active-CSS / active-css

The epic event-driven browser language for UI with functionality in one-liner CSS. Over 100 incredible CSS commands for DOM manipulation, ajax, reactive variables, single-page application routing, and lots more. Could CSS be the JavaScript framework of the future?
https://activecss.org
Other
42 stars 7 forks source link

Add option to component syntax to start component up only when visible. #307

Closed bob2517 closed 1 year ago

bob2517 commented 1 year ago

It might be worth doing this with intersection observer. Seems a waste to run an animation component when no one can see it. If it can be done easily it should be on the branch by the end of tomorrow as I could use it for a work project next week.

This will be a full rendering, starting with beforeComponentOpen, only when the element becomes visible on the page. Until then it will just look like a container element, it won't contain a shadow DOM, or anything else.

bob2517 commented 1 year ago

Working on this. A handling may or may not be needed when child elements are present, to make them invisible until the component is drawn. Need to implement fully to see if there is a flicker in transition or not. If it's noticeable then the handling will be necessary.

bob2517 commented 1 year ago

If IntersectionObserver is not supported in browser, the render-when-visible option will be skipped.

bob2517 commented 1 year ago

render-when-visible is now on the branch.

Needs trying out in production when I'm back at work next week, but as far as I can tell it works ok. Clean-ups are in place also.

bob2517 commented 1 year ago

Example use:

@component my-component render-when-visible strictlyPrivate {
...
bob2517 commented 1 year ago

Could put in a margin threshold option. Will do that if requested. Otherwise unless it comes up as a problem I won't be bothering with it.

bob2517 commented 1 year ago

This is pretty neat. Obviously there are instant performance improvements, as there always are with intersection observer, especially when images are involved. I'll put this in the docs, but care should be taken to size the component element correctly so that everything doesn't lump together through having a zero height and width and unintentionally get rendered right away.

bob2517 commented 1 year ago

Spotted an error with multiple components - pulling back - don't use yet.

bob2517 commented 1 year ago

Fix is now on the branch - the earlier bug was that it was only intersecting the last render-when-visible component on the page.

bob2517 commented 1 year ago

Make sure to leave the really important note with intersection observer, is that if you observe an element or component, its outer element, the element being observed, needs to have a height and a CSS display property that works with height.

This came up on the rotating display of lazy loaded images, the height (auto) of which only gets known once the image has loaded. And if it's waiting for intersection observer to start the load, with the src attribute effectively empty until the loading starts, then an unloaded img of height auto will have a default height of 0... The solution for me was to set a min-height for the img CSS (display: inline-block).

bob2517 commented 1 year ago

Pulling back - I'm getting a related bug on one example which isn't showing in the compiled version of the docs site. Investigating.

bob2517 commented 1 year ago

Fix is now on branch. Switched method use from intersectionRatio to isIntersecting. An unrendered component at the very edge of the screen would bring back a ratio of 0 and not be run until it went out and back in again regardless of its height, whereas isIntersecting just gives a true or false and seems reliable.

bob2517 commented 1 year ago

Closing pending release.