DEV Community

Cover image for Modern Browser APIs - Part 1
Shafiqul Islam Shuvo
Shafiqul Islam Shuvo

Posted on • Edited on

Modern Browser APIs - Part 1

The modern browsers have created a handful of APIs which can help the developers to build applications that can perform better, work offline, and provide a better user experience. Today we are going to check 5 APIs of Modern Browsers that we can use for web applications development and save ourselves from a lot works and troubles:

  1. Window.requestAnimationFrame
  2. Resource Prefetch
  3. Resource Preload
  4. Navigator.sendBeacon
  5. Intersection Observer

Window.requestAnimationFrame

Window.requestAnimationFrame() api can be used to call a function every time display frame changes/updates which is approximately 60 per second or more. Using this method we can create a smooth animation or make a polling function.

requestAnimationFrame has the following benefits:

  1. Browser has the ability to optimize the performance
  2. Execution will be stopped for the inactive browser tabs
  3. More accurate than setTimeout/setInterval

Demo:

function animate() {

  // your code goes here

  //the will be called repeatedly by requestAnimationFrame
  requestAnimationFrame(animate);
}
// Intial call to the function
animate();
Enter fullscreen mode Exit fullscreen mode

We also can stop animation using the window.cancelAnimationFrame method:

window.cancelAnimationFrame(animate);
Enter fullscreen mode Exit fullscreen mode

A polling function to wait for an HTML element using requestAnimationFrame:

const waitForElement = function (elem) {
    if (typeof elem === 'string') {
        return new Promise(function (resolve) {
            var wfelem = function () {
                if (null != document.querySelector(elem)) {
                    resolve(document.querySelector(elem));
                } else {
                    window.requestAnimationFrame(wfelem);
                }
            };
            wfelem();
        });
    }
};

// You can use the function in following way:

waitForElement('body').then(function(body){
    body.style.background = 'red';
});
Enter fullscreen mode Exit fullscreen mode

Resource Prefetch

Resource prefetching is a technique that we can use to tell the browser to download a page or resource even before the users are going to access them. This technique can be used for the pages that the users are most likely going to visit. The browser will download and cache the resource in the background with a low priority, so it won't interfere with more important resources.

<link rel="prefetch" href="/your-resource-link" />
Enter fullscreen mode Exit fullscreen mode

Resource Preload

Resource preloading is similar to Resource prefetching but the difference is that Prefetching is a way to tell the browser what resource to download that likely to be accessed on the next navigation and Preloading is to load a resource that will be needed for the current page. The syntax is similar but we also need to provide the resource type in as attribute.

<link rel="preload" href="/images/background.jpg" as="image" />
Enter fullscreen mode Exit fullscreen mode

Navigator.sendBeacon

Sometimes we may need to send data to server when a visitor leaves a page. When a user leaves a page, JavaScript fires an event called unload and it is not an easy task to send an Ajax request during this event.
We can use XMLHttpRequest in an unload handler. But it will prevent the browser to load the next page until the request is completed.

window.addEventListener("unload", function() {
  var xhr = new XMLHttpRequest();
  xhr.open("POST", "/log", false); // third parameter of `false` means synchronous
  xhr.send(data); 
});
Enter fullscreen mode Exit fullscreen mode

But Navigator.sendBeacon() is here to solve that problem. This method is useful when you need to send a data through Ajax but don't expect a response. And the request is executed asynchronously when the browser gets a chance to send the data during the idle processing time.

Navigator.sendBeacon() takes two parameters: first one is the url and second one is the data. The function will return a true response when the data is successfully sent to server or false if the request isn't successful.

window.addEventListener("unload", function() {
  if (navigator.sendBeacon) {
      // Send the beacon
      var status = navigator.sendBeacon(url, data);
      // Log the result
      console.log(status);
  }
};
Enter fullscreen mode Exit fullscreen mode

Intersection Observer

It is hard to find a Developer who didn't write/use a code to check if an element is visible in the viewport.
We usually create a function and attach it to the scroll event and check if the target element pops up in the screen. Check the following snippet in jQuery:

$(window).scroll(function() {
    var top_of_element = $("#element").offset().top;
    var bottom_of_element = $("#element").offset().top + $("#element").outerHeight();
    var bottom_of_screen = $(window).scrollTop() + $(window).innerHeight();
    var top_of_screen = $(window).scrollTop();

    if ((bottom_of_screen > top_of_element) && (top_of_screen < bottom_of_element)){
        // the element is visible, do something
    } else {
        // the element is not visible, do something else
    }
});
Enter fullscreen mode Exit fullscreen mode

Whew! Lots of calculations is going on there which I have never been able to remember. But, we now have IntersectionObserver() method which can save us from all of these troubles.

const observer = new IntersectionObserver(function(elements) {
    console.log(elements);
});

observer.observe(document.querySelectorAll('p'));
Enter fullscreen mode Exit fullscreen mode

The first argument of IntersectionObserver is a function that can take an array of HTML elements. There is a second optional argument that takes an object of options:

const observer = new IntersectionObserver(function(elements) {
    elements.forEach(function(element) {
        if (element.intersectionRatio >= 0.5 && element.intersectionRatio < 1) {
            element.style.opacity = "0.5";
        } else if (element.intersectionRatio >= 1) {
            element.style.opacity = "1";
        }
    });
}, {
    // You can use a single value
    threshold: 0.5 // The observer's callback will be once the target element is 50% visible
    // Or you can use an array of value
    threshold: [0.5, 1.0] // The callback will run when target element is 50% and 100% visible
});

observer.observe(document.querySelectorAll('p'));
Enter fullscreen mode Exit fullscreen mode

Top comments (0)