Skip to content
This repository has been archived by the owner on Jun 29, 2023. It is now read-only.

Handling Component Updates after initial load

Harry Robbins edited this page Jun 25, 2019 · 6 revisions

Purpose

To identify various techniques for handling changes to the light dom (the content nested inside a custom element), and their pros and cons.

Assumptions

We're assuming that the author is using the Stencil.js library as a framework for building Web Components.

Key Considerations

  1. Complexity
  2. Performance
  3. Cross-browser compatibility
  4. Effectiveness

Methods

  1. Stencil Custom Events
    • Setup an event emitter in a child component and a companion event listener in the wrapping/parent component.
  2. Native SlotChange Event
    • Setup an event listener on one or more slot elements in a component that expects children.
  3. MutationObserver API
    • Setup a mutation observer in a component that expects children

Comparison

Stencil Custom Events

  • Pro: As part of the Stencil library, it should work in all target browsers
  • Pro: If needed, data specific to a child element can be passed from the event emitter, such as relevant metadata.
  • Con: API is complex. Depends on event emitters existing in child components, and may demand updates to child components to be effective.
  • Con: An event is fired for each child on initial load. This leads to multiple firings of the event listener in the parent on initial load when nothing is actually changing. If the Listener is mutating state - this leads to multiple calls to the render function of the wrapper element on initial load.
  • Con: Does not work with native elements. Only works when the children are other custom elements and if those elements contain event emitters during specific lifecycle events.
  • Con: The order the events fire in is inconsistent, requiring ordering of children be handled manually in order to be done properly in events where order is important.
  • Con: At the time of writing, there's a bug with event emitters called in cleanup lifecycle functions. This prevents us from being alerted when child Nodes are removed, such as via <element>.removeChild(childNode).

SlotChange Event

  • Pro: Works with native elements.
  • Pro: Does not require event emitters exist on a child component to properly detect changes.
  • Pro: Very simple API.
  • Con: An event is fired on initial load, which requires conditional wrapping to short circuit.
  • Pro: Only one event is fired when a change is made, including on initial load.
  • Con: Browser support is poor in Edge and IE11. A polyfill would be required.
  • Con: There may be other browser inconsistencies for when the event fires.
  • Con: The event object doesn't contain enough info to know what changed - comparing old and new light dom or shadow dom will have to be done manually.

Mutation Observer

  • Pro: Works with native elements.
  • Pro: Does not require event emitters exist on a child component to properly detect changes.
  • Pro: Only one event is fired on initial load, and only one event is fired when a change is made.
  • Pro: Has good browser support
  • Pro: The argument provided to the callback contains details about nodes that were added or deleted.
  • Con: An event is fired on initial load, which requires conditional wrapping to short circuit.
  • Con: API is more complex and would require more boilerplate.