alexanderby / malevic

Malevič.js - minimalistic reactive UI library
MIT License
30 stars 0 forks source link

Change behavior of onCreate/onRender #17

Open Gusted opened 3 years ago

Gusted commented 3 years ago

At this moment at the very start malevic will render every child/node and thus calling onCreate once and on every node changes, every thing that specified onRender will also be executed.

as https://github.com/darkreader/darkreader/pull/5926 indicates, it doesn't need to be this way. Especially when certain functions like rendering a canvas can be quite on the heavy side for the rendering.

Could the same technique be used to just execute(maybe even create these nodes) until they are visible?

alexanderby commented 3 years ago

But you will not find out if it is visible or not until you create a node. To perform some kind of lazy rendering, you have to subscribe on window resize and scroll events (not applicable to Dark Reader's UI), and do some custom logic inside a component, to check if it is visible and to render its content separately, for example:

import {m} from 'malevic';
import {sync, render, getContext} from 'malevic/dom';

export default function LazyContainer(props, ...content) {
    const context = getContext();
    context.onRender((node) => {
        if (node.offsetHeight === 0) { // or maybe some more stable check
            render(node, content);
        }
    };
    if (!context.node) {
        const element = context.node || document.createElement('div');
        sync(element, <div class="lazy-element"></div>);
        return element;
    }
    return context.node;
}
Gusted commented 3 years ago

Sounds about right and good for now. Considering that it the execute function is in most cased under a millisecond and that these big render functions can be mitigated to check the offsetXXX property.