[Digging into the Observer API] 1. Observer API
[Digging into the Observer API] 1. Observer API
When developing frontends, you end up dealing with countless events.
Most of the time these are events driven by user interaction, but occasionally you also deal with events closely tied to DOM changes, such as scrolling or resizing.
In such cases, using the browser's Observer API lets you implement far more optimized, better-performing event handling than the typical Event Driven approach.
This series aims to explore the Observer API.
🖼️ Observer
The Observer API is an API that asynchronously detects specific events or DOM state changes, and lets you perform desired behavior in response.
Since it's a browser API, it can only be used on the client side.
There are 5 types of Observer APIs.
| API | Purpose |
|---|---|
| IntersectionObserver | Detects whether an element intersects with the browser viewport |
| ResizeObserver | Detects changes in an element's width and height |
| MutationObserver | Detects changes in the DOM tree |
| PerformanceObserver | Detects events related to page performance |
| ReportingObserver | Detects warnings and issues occurring in the browser |
In general, these are associated with interactions with page elements rather than user interaction.
Using the observer suited to your particular purpose enables high optimization and reliable event handling.
Due to their intended use, PerformanceObserver and ReportingObserver are rarely used in frontend development.
I said this allows for much more effective event management than Event Driven — but why exactly is that possible?
Let's take IntersectionObserver as an example. This observer is often used to detect whether an element is actually visible in the viewport.
First, without an observer, checking whether an element is displayed in the viewport requires code like the following.
TYPESCRIPT
document.addEventListener('scroll', () => { console.log('Check scroll position and act accordingly'); });
Since scrolling must occur first for an element to enter the viewport, you could detect this by adding a scroll event to the global document object.
This approach has the following drawbacks.
- The applied scope is far too broad relative to what you actually care about. Since it's applied to document, a potential action gets added on every scroll, regardless of whether the specific DOM element you care about is involved.
- It absolutely requires scrolling as a precondition. Even if a DOM element ends up displayed in the viewport without any scroll action occurring for some reason, the related event code won't run until a scroll happens.
- Unnecessary code keeps running continuously. Since the event fires excessively just from simply scrolling the document, unnecessary overhead is easy to incur.
Applying IntersectionObserver looks like this.
TYPESCRIPT
const observer = new IntersectionObserver((entries) => { entries.forEach((entry) => { if (entry.isIntersecting) { console.log('Element is in view!'); } }); }); observer.observe(document.getElementById('tag'));
Unlike Event Driven, the code above only fires the event at the moment the DOM element intersects the viewport. Unnecessary event waste essentially disappears. As the related computation is reduced, you can expect better performance.
Starting with IntersectionObserver in the next post, let's dig deeper into each observer.