emberjs / emberjs/rfcs

Allow modifiers to interact with the element before it is insert into the DOM

Open
#652 11 comments 13 reactions 0 assignees View on GitHub
Dominant language
No language data
Stars
801
Forks
409
PR merge metrics
No merged PRs in 30d

Description

Modifier Manager should provide a hook, which has access to the DOM element but is executed *before* the element is insert into the DOM.

The `installModifier` hook is executed *after* the element is insert into the DOM:

> This hook has the following timing semantics:
>
> Always
>
> - called after all children modifier managers installModifer hook are called
> - called after DOM insertion
>
> https://github.com/emberjs/rfcs/blob/master/text/0373-Element-Modifier-Managers.md#installmodifier

The `createModifier` hook does not have access to the DOM element. Accordingly to [Modifier Manager RFC](https://github.com/emberjs/rfcs/blob/master/text/0373-Element-Modifier-Managers.md#createmodifier) "called as discovered during DOM construction". Not sure if the element is created yet and just not passed in or does not even exist yet.

I have two use cases for a hook, which has access to the DOM element but is executed *before* it's insert into the DOM:

1. A `set-attribute` and `set-property` modifier, which sets values as attributes or properties on the element before it's insert into the DOM.
2. The existing [`ember-style-modifier`](https://github.com/jelhan/ember-style-modifier), which manipulates the CSS styles of an element using CSSOM.

For both of them running before the element is insert into the DOM is important from a performance perspective. If executed *after* the element has been insert into the DOM the browser may do an unnecessary layout calculation in between. E.g. if `Element.getBoundingClientRect()` or a similar function is called in between.

It's even worse as there isn't any garantuee if the modifier is executed in the same tick as the DOM insertion:

> May or May Not
>
> - be called in the same tick as DOM insertion

If it's executed in the next queue the Browser paint the state before the modifiers has been run. This may be visible to the end-user as an inconsistent and flickering UI.

Especially for `set-attribute` and `set-property` the timing is also important if considering [custom elements](https://developer.mozilla.org/en-US/docs/Web/Web_Components/Using_custom_elements). Custom elements are part of the web components feature set. Similar to `@ember/component` they have lifecycle hooks. One of them is the `connectedCallback`. It's executed when the element is insert into the DOM.

As modifiers are called only after the DOM element has been insert into the DOM manipulation attributes or properties set on the element using them are not available yet in `connectedCallback`. I have created a JSFiddle to illustrate the timing relevance: https://jsfiddle.net/jv0Lk3sb/ It's creating a custom element, which implements the `connectedCallback`. It sets two attributes on the custom element. One before and one after it has been insert into the DOM. Only the first one is available in `connectedCallback`.

The limitation for custom elements is especially relevant as one can not rely on Glimmer VM always setting values passed as attributes as attributes. Depending on the custom element it may be set as an attribute or a property. It may even change between first and subsequent runs. See [this issue](https://github.com/emberjs/ember.js/issues/15709#issuecomment-619209607) for more details. Modifier would be a good solution to get full control if the values are set as an attribute or a property on the element. But due to their timing issue with `connectedCallback` this is not possible in many cases.

While going this route we may want to consider allowing to run code with a modifier on destruction *before* the element is removed from DOM.

Thanks a lot to @rwjblue for the [input on Discord](https://discord.com/channels/480462759797063690/489814042031161344/739753468503523349), which helped creating this issue. I hope I got everything right.

Contributor guide

No contributing guide indexed for this repository

Assessment

This issue has not been assessed yet.

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.