Observing Your Web App - A Quick Round Up
Tags: webdev, javascript
Published: 2018-12-30 11:28:46

---
title: Observing Your Web App - A Quick Round Up
published: true
description: A a quick round up on ways to monitor changes and updates on your web apps using various Web APIs
tags: webdev, javascript 
---

As web developers we write a lot of code to detect changes in our web app and do manipulations based on those changes. Today, the web has lots of APIs for *"observing"* your web app for many types of changes and letting you perform actions based on them.

Here's a quick round up-

## 1. Observing the DOM through event listeners

The most classic way to detect changes by using `addEventListener`. This can be used to listen to native as well and custom events.

```javascript
window.addEventListener('scroll', e => { ... });  // user scrolls the page.

el.addEventListener('focus', e => { ... });  // el is focused.

img.addEventListener('load', e => { ... });  // img is done loading.

el.addEventListener('custom-event', e => { ... });  // catch custom event fired on el.

```

-------------------------------

## 2. Check for DOM tree modifications

The [MutationObserver](https://developer.mozilla.org/en-US/docs/Web/API/MutationObserver) interface provides the ability to watch for changes being made to the DOM tree.

```javascript
var target = document.querySelector('#div_id');
 
var observer = new MutationObserver(mutations => {
    mutations.forEach(mutation => {
        console.log(mutation.type);
    });
});
 
var config = { 
    attributes: true, 
    childList: true, 
    characterData: true 
} 
observer.observe(target, config);
```

-------------------------------

## 3. Check when an element comes into view

The [Intersection Observer API](https://developer.mozilla.org/en-US/docs/Web/API/Intersection_Observer_API) provides an easy way to watch and register callbacks to trigger when elements on a page come into view.

```javascript
const images = document.querySelectorAll('.animate');

observer = new IntersectionObserver(entries => {
  entries.forEach(entry => {
    if (entry.intersectionRatio > 0) {
      console.log('in the view');
    } else {
      console.log('out of view');
    }
  });
});

images.forEach(image => {
  observer.observe(image);
});

```

Using this API we can trigger animations, lazy load images etc., when they come into view.

-------------------------------

## 4. Check when the elements in DOM are re-sized

The [ResizeObserver](https://wicg.github.io/ResizeObserver/) allows for elements to be notified when their size changes.

```javascript
const myObserver = new ResizeObserver(entries => {
  entries.forEach(entry => {
    console.log('width', entry.contentRect.width);
    console.log('height', entry.contentRect.height);
  });
});

const el = document.querySelector('.some-element');
myObserver.observe(el);
```

With each entry, we get an object with properties - `contentRect` and `target`. The target is the DOM element itself, and contentRect is an object with the following properties: `width`, `height`, `x`, `y`, `top`, `bottom`, `left` and `right`.

-------------------------------

## 5. Check if your web app is on full-screen mode

Using the [Fullscreen API](https://developer.mozilla.org/en-US/docs/Web/API/Fullscreen_API) makes this possible.

```javascript
var el = document.getElementById("myvideo");
if (el.requestFullscreen) {
  el.requestFullscreen();
}
```

Not just detection of full-screen mode but this API also allows the turning off and on of full-screen mode.

-------------------------------

##6. Check if the tab is in focus

```javascript
document.addEventListener('visibilitychange', e => {
    if(document.hidden) {
        // .... do something
    } else {
        // .... dome something else
    }
});
```
I am still including this in the list even if this is not a new API but rather a technique. One use case can be to draw user attention back to the abandoned tab.

-------------------------------

## 7. Check for device orientation changes

The [Screen Orientation API](https://www.w3.org/TR/screen-orientation/) makes this possible.

```javascript

window.addEventListener('orientationchange', e => {
  console.log(screen.orientation.angle, screen.orientatio.type)
});

```

We can also check to see if the current orientation matches to a particular orientation.

```javascript
const media = window.matchMedia('(orientation: portrait)');
media.addListener(mql => console.log(mql.matches));
```

-------------------------------

## 8. Check for network status and changes

The [Network Information API](https://developer.mozilla.org/en-US/docs/Web/API/Network_Information_API) provides information about user's network connection. Using this information it’s possible to conditionally load images, videos, fonts and other resources. 

```javascript

navigator.connection.addEventListener('change', e => {
  console.log(navigator.connection.effectiveType, navigator.connection.downlink);
});
```
Apart from properties `effectiveType` and `downlink` mentioned above, it also provides `downlinkMax`, `rtt`, `saveData`, `type`.

-------------------------------

## 9. Check status of the device battery

This is possible using the [Battery Status API.](https://www.w3.org/TR/battery-status/)

```javascript

navigator.getBattery().then(battery => {
  console.log(
    battery.level * 100 + '%',
    battery.charging,
    battery.chargingTime,
    battery.dischargingTime
    ); 
});

```

-------------------------------

## 10. Check when your web app uses a deprecated API or hits a [browser intervention](https://github.com/WICG/interventions)

The [Reporting API](https://w3c.github.io/reporting/) makes it possible

```javascript
const observer = new ReportingObserver((reports, observer) => {
  reports.map(report => {
    console.log(report);
    // ..... send report to analytics etc..
  });
}, {buffered: true});

observer.observe();
```

I believe, currently, the `ReportingObserver` has only been shipped in latest Chrome.

-------------------------------

## 11. Check the performance of you web app

The [PerformanceObserver] (https://developers.google.com/web/updates/2016/06/performance-observer) interface is used to observe performance measurement events and be notified of new performance entries as they are recorded in the browser's performance timeline. 

```javascript
const observer = new window.PerformanceObserver(list => {
    list.getEntries().forEach(({name, startTime}) => {
        console.log({name, startTime});
    });
});
observer.observe({
    entryTypes: [{'paint', 'resource', 'mark', 'measure'}]
});
```

-------------------------------

It's really amazing that the web has so many great APIs at our disposal. Using these we can create web apps with better performance and greater user experience.

**Note**: Always check the browser support before using the modern APIs.

-------------------------------

## Useful Resources

1. [Watch the Best web features of 2018 face-off against each other](https://www.youtube.com/watch?v=adgI8-W1VjE)
2. [Lazy Loading Images for Performance Using Intersection Observer](https://scotch.io/tutorials/lazy-loading-images-for-performance-using-intersection-observer)
3. [Use Network Information API to Improve Responsive Websites]
(https://www.sitepoint.com/use-network-information-api-improve-responsive-websites/)
4. [ResizeObserver Sample](https://googlechrome.github.io/samples/resizeobserver/) 
5. [PerformanceObserver and Paint Timing API](https://jmperezperez.com/paint-timing-api/)