Skip to content

Commit

Permalink
docs(coding-convention): note on optimizing layout query (carbon-desi…
Browse files Browse the repository at this point in the history
…gn-system#5013)

### Related Ticket(s)

Refs carbon-design-system#4993.

### Changelog

**New**

- Implementation notes for optimizing layout query, so that new developers can do the same optimization and won't cause performance issues.
  • Loading branch information
asudoh authored Jan 30, 2021
1 parent 0016be2 commit 7751ce0
Showing 1 changed file with 11 additions and 0 deletions.
11 changes: 11 additions & 0 deletions packages/web-components/docs/coding-conventions.md
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,7 @@
- [Private properties](#private-properties)
- [Preferring class inheritance pattern over React composition pattern](#preferring-class-inheritance-pattern-over-react-composition-pattern)
- [Limiting components that works with complex data](#limiting-components-that-works-with-complex-data)
- [Optimizing layout query](#optimizing-layout-query)

<!-- END doctoc generated TOC please keep comment here to allow auto update -->

Expand Down Expand Up @@ -568,3 +569,13 @@ But there are certain kind of components that have to work with complex data, wh
- **Container components**: Ones that manage application-level states and/or do data fetching/storing. The elements has `<dds-*-container>` naming rule. Container components may work with dedicated state manager like Redux (often recommended).
- **Leaf components**: Ones that represents user interface/interaction. Most of our components are in this category.
## Optimizing layout query
`onscroll` and `onresize` event handlers fire as user scrolls and resizes the window, respectively. The event handlers of those event tend to query for layout of DOM elements that is known as [expensive](https://gist.github.com/paulirish/5d52fb081b3570c81e3a). To avoid excessive number of calls with such heavy thing [debouncing/throttling/caching, etc. are known as old best practices](https://felixgerschau.com/javascript-event-loop-call-stack/#event-loop), but doing the right thing with it, especially determining when is the right timing to query for layout, is very hard.
`@carbon/ibmdotcom-web-components` codebase uses [`IntersectionObserver`](https://developer.mozilla.org/en-US/docs/Web/API/Intersection_Observer_API) and [`ResizeObserver`](https://developer.mozilla.org/en-US/docs/Web/API/ResizeObserver) as new best practices. Those APIs leverages browser's layout information it calculates at the right timing so that application doesn't need to run another query that may not be at the right timing.
Be mindful of [lifecycle management](#lifecycle-management). For example, we don't want to keep observing intersection of DOM elements that are no longer there inside `<body>`, like ones that are removed as routing happens. An example of lifecycle management code can be found at [here](https://github.com/carbon-design-system/carbon-for-ibm-dotcom/blob/v1.15.0/packages/web-components/src/components/masthead/top-nav.ts#L109-L136), which is called from `connectedCallback()` and `disconnectedCallback()`.
> 💡 Creating `IntersectionObserver`/`ResizeObserver` may require waiting for the target DOM to be created. Leverage `lit-element`'s lifecycle methods, e.g. [`firstUpdated()`](https://lit-element.polymer-project.org/guide/lifecycle#firstupdated)/[`updated()`](https://lit-element.polymer-project.org/guide/lifecycle#updated), for that.

0 comments on commit 7751ce0

Please sign in to comment.