Delete-Agency/dc

data-dc-ondemand attribute

Closed this issue · 5 comments

Sometimes in you markup you have components which don't immediately visible for users. Maybe they are within tooltips/modals or you have a tabs component and only one will be shown to user. Simply speaking those cases require specific action to make some components visible and interactive.

Current factory will instantiate those components anyway because it doesn't know about their visibility and your UI logic.
If you have many of those hidden components you can end up with performance problems despite visually there are not many components on the page.

To address this we could introduce additional data attribute which can flag that a particular node and its children should be ignored during initialization phase. Then the only way to instantiate them would to call dcFactory.init with additional flag to indicate that all components including ignored should be created.

init(element, demand = false){
   ...
}

Example:

<button data-dc-modal-trigger='{"target": "#example-modal"}'>
    Show the map
</button>
<div id="example-modal" class="modal" data-dc-ondemand>
    <div data-dc-gmap='{"lat": 55.123, "lng": 56.321}'></div>
</div>
Modal.setOptions({
    onModalInit: (modal) => {
        // call init with the second (demand=true) argument
        dcFactory.init(modal.element, true);
    }
})

With described logic in place only modal-trigger component will be created on first dcFactory.init() call. Map component within modal will not because of data-dc-ondemand attribute. When button is clicked and Modal.create() is called then gmap component will be created.

Pros: components that are not needed right away won't be created so it is good for the performance.

Cons:

  • more complexity to init method - in case demand=false before creating any found component we should go up the tree to find out if any of its parents have data-dc-ondemand
  • testing: testing can be tricky because in case map component from the example above is broken we won't know that until clicking on button. But you can easily debug all components if you pass demand=true to your first dcFactory.init call (you can even make it dependent form you current environment: dcFactory.init(document.body, IS_DEVELOPMENT_ENVIRONMENT))

Possible variations of naming and default value:

  • data-dc-ondemand + init(element, demand = false)
  • data-dc-ondemand + init(element, demand = true)
  • data-dc-lazy + init(element, withLazy = false)
  • data-dc-lazy + init(element, withLazy = true)
  • any other?



Looks really feasible from my point of view.
Is it possible to pass this flag through the options object to reduce amount of data attributes?

@danilDelete Original idea was about attribute which is not connected to any of your component. In my example, data-dc-ondemand is not on data-dc-gmap component element it is on its parent. So you can have any number of components within that modal and none of them will be created with demand=false init call.
Imagine you have also a gallery and accordion after the map. You will have to pass this argument to every component so it means additional complexity in rendering process.
Essentially the only thing that defines your component as ondemand is the fact that it is placed within modal.

Also data-dc-ondemand is a part of the dcFactory and relates to a searching and creation process, whereas options (data-dc-{namespace}={options}) is a part of component instance itself so anyway I would rather not to mix them within a single options object

It can be good choice. I think lazy would be nice naming, because it refers to lazy images, they're load as they need. Also, its not complexity, it is explicit way to initialize. And its better then implicit.

@dubaua Yes, lazy makes sense to me as well as ondemand which is widely used name for something that shouldn't do any work until it is directly called.
Let's create a poll and make a decision that way

UPD: I've created a poll in the original post

Do you guys have any thoughts about the default value of that withLazy/demand argument in dcFactory.init(element, withLazy/demand)? To be honest, I am not sure which one should be taken.

We can implement any of them and see how it suits us