Before diving deeper into the observers family supported by modern browsers, let’s try to understand what is observer in general?
What is Observer?
Observer is a programme which watches or notices something. Observers can be helpful to watch certain activities happening in the browser and respond accordingly. Observers are similar to dogs, watching certain activities and alerting us if something unusual happens. And it is our responsibility to take an action once we are alerted by dogs for certain activities.
Using observers we are able to watch different types of activities that occur in the browser, and take necessary actions. For eg. we can observe if a video is displayed within the view port and enable autoplay, if child element has been added or removed from the parent DOM element, if the size/dimensions of a box element has changed and so on.
Following are four different types of observers supported by modern browsers.
- Intersection Observer
- Mutation Observer
- Resize Observer
- Performance Observer
Intersection Observer :-
It is used to observe intersection between two HTML DOM elements. It is useful to watch an element in your DOM when it enters or leaves the visible viewport. Some of the use cases of Intersection Observer are described below
- Lazy-loading images or other resources when an element is visible within the viewport.
- Identifying visibility of advertisements and calculating ad revenues.
- Implementing “Infinite Scrolling” websites (eg. Forbes) when user scrolls down the page so that they don’t have to navigate through different pages.
- Loading and autoplaying, videos or animations when an element is within the viewport.
Browser support :- Currently, firefox and chrome supports Intersection observer but we can find polyfills for older browsers.
Using IntersectionObserver api mainly requires three steps
a) Creating Observer
b) Defining target object to observe
c) Defining callback handler
a) Creating Observer:-
Threshold of [0.3] means, when target element is 30% visible within the element specified by root element, invoke the handler function. It means handler/callback function is invoked whenever element is visible by 30%, 50%, 80% and 100%.
b) Defining target object to observe :-
We can define multiple target objects to observe. As mentioned in the example before, a dog should know what to observe before alerting everyone.
Any target element can be observed, simply by calling .observe(target) method of the respective observer.
c) Defining callback handler :-
This is the response to make when one notices an alert, for something unusual has happened. Callback handler is fired whenever, target element is intersected with the root element by threshold values.
I have prepared a demo which uses Intersection Observer to change the color of the target box when it is seen within the visible area as user scrolls up.
See the Pen intersectionObserverExample by jitendra kasaudhan (@jitubutwal144) on CodePen.
References: Demo , Intersection Observer API
Mutation Observer :-
Mutation observers are used to observe changes in the DOM elements. It is useful to observe changes such as addition or removal of child nodes in a parent node, changes in the value of attributes or data content etc. Before MutationObserver, DOM change events were handled by Mutation Events such as DOMAttrModified, DOMAttributeNameChanged, DOMNodeInserted.
Mutation observer is designed as a replacement for Mutation Events defined in the DOM3 events specification. The practical reasons to avoid the mutation events are performance issues and cross-browser support.
Probably the biggest audience for this new API is the people building JS frameworks, mainly to solve problems and create interactions. Another use case would be a situation where you are using frameworks that manipulate the DOM and need to react to these modifications efficiently ( and without setTimeout hacks).
Browser Support :- It has pretty good support across different browsers.
In general, implementation of MutationObserver requires three steps-
a) Creating Observer :-
It can be created, simply by calling its constructor and passing handler function and configuration options. We have an option to specify, what kind of changes do we want to track or observe.
childList: true, means observe changes related to child nodes, attributes: true means observe attribute change, characterData: true means observe changes in target element’s data content.
b) Defining target object to observe :-
observer.observe(…) method accepts target element which should be observed.
c) Defining callback handler :-
Depending upon the configuration used during observer creation process, callback function is executed whenever changes occur in the target element. Callback function is fired with mutation records object which contains the type of mutation occurred in the target element.
I have prepared a demo that fires mutation observer’s callback handler, whenever new child node is added or removed along with attribute change.
See the Pen mutationObserverExample by jitendra kasaudhan (@jitubutwal144) on CodePen.
Mutation Observer Demo
References: Demo, Mutation Observer API
Resize Observer :-
Resize Observer allows us to watch changes in content rectangle size (width, height) of a DOM elements and react accordingly. It is like document.onresize() or window.resize() events for elements. It is useful when the elements change their size without resizing the main window. For example, appending new children, setting element’s display property to none or similar actions can change the size of an element, its siblings or ancestors. It only watches the content box. Some of the behaviours of resize observers are described below
- observation will fire when watched Element is inserted/removed from DOM.
- observation will fire when watched Element display gets set to none.
- observations do not fire for non-replaced inline Elements.
- observations will not be triggered by CSS transforms.
- observation will fire when observation starts if Element has display, and Element’s size is not 0,0.
Resize observer notifies about the dimensions of content box as shown in the figure below
Browser Support :- Currently, it is not supported by most of the browsers except chrome ≥ 64.
Observer’s api can be used in three steps as other observers.
a) Creating Observer :-
It can be created, simply by calling its constructor and passing handler function.
b) Defining target object to observe :-
Define target object whose change in size should be observed.
c) Defining callback handler :-
See the Pen resizeObserverExample by jitendra kasaudhan (@jitubutwal144) on CodePen.
Risize Observer Demo
References: Resize Observer Usage
Performance Observer :-
It is used to observe the Performance Timeline and be notified of new performance entries as they are recorded by the browser. It can be used to measure certain performance metrics both in browser and node.js applications. In the browser we can access observer using Window object as window.PerformanceObserver and in node.js application we have to require perf_hooks to get performance object. Eg.const { performance } = require(‘perf_hooks’); It can be useful in following cases
- Measure processing time between request and response. (In browser)
- Calculate duration while retrieving data from database. (In nodejs app)
- Abstract precise timing information using Paint Timing API such as time for first paint or first contentful paint.
- Access performance metrics using User Timing API, Navigation Timing API, Network Information API, Resource Timing API, Paint Timing API
Implementation of PerformanceObserver requires three steps
a) Creating Observer :-
It can be created, simply by calling its constructor and passing handler function.
b) Defining target object to observe :-
observer.observe(..) method accepts valid set of entry types that can be observed. These entry types may belong to various performance API such as user timing or navigation timing API. Valid entryType values are: "mark”[USER-TIMING], "measure" [USER-TIMING], "navigation" [NAVIGATION-TIMING-2], "resource" [RESOURCE-TIMING].
c) Defining callback handler :-
Callback handler is fired whenever the observed event is used in the application. For eg. it can be used to mark the instant and measure the duration from start to end instant.
See the Pen performanceObserverExample by jitendra kasaudhan (@jitubutwal144) on CodePen.
Performance Observer Demo
Feel free to play around with a simple demo which uses PerformanceObserver API. When a button is clicked by a user, it will mark the instant as start and end and measure the duration the after 3000ms. Output can be viewed in console.
References: Demo , Irina Shestak: Storytelling With Performance Observers -JSConf.Asia 2018, Performance Observer API , NodeJS perf_hooks API
Please let me know if you have any thoughts/suggestions/improvements regarding these observers.
Leave a Reply
Your email address will not be published. Required fields are marked *