DEV Community

Cover image for Real-time updates in Vue apps with Polling
Jakub Andrzejewski
Jakub Andrzejewski

Posted on

Real-time updates in Vue apps with Polling

When I first discovered a concept of Frontend Polling, I wasn't sure if it is a good idea or not. I was a bit affraid of overloading the server with too many consecutive requests that do not bring value (because we know that the data is not there yet right?)

But the reality is, that when implemented correctly, such polling is not as destructive for the server as it may seem from the first example while they can deliver a lot of value to the users as it allows them to get up to date information without the need to refresh the page.

Frontend Polling

In this article, I would like to introduce you to the concept of Frontend Polling so that you can try it out in your project and see for yourself if it will be useful in your case 😉

🤔 What is Frontend Polling?

There is a really good article about how to achieve it in pure JavaScript that you can check out here

In general, the idea is to have persistent connection with server, that doesn’t use any specific protocol like WebSocket or Server Sent Events.

There are two major ways of achieving polling:

  1. Regular -> This method triggers polling after certain amount of time, called interval. It will work in several cases (we are using it in Vue Storefront). This is usually achieved by using setInterval built in JS function. Let's take a look at following code to see how it works:
const fetchPosts = async () => {
  try {
    console.log('Fetching new data...');

    const response = await (await fetch(url)).json();

    console.log('Data fetched!')

  } catch(err) {
    console.log('Request failed: ', err.message);
  }
}

setInterval(fetchPosts, 5000);
Enter fullscreen mode Exit fullscreen mode
  1. Long -> Triggering polling after certain response from the endpoint. The best way of explaining how it works is by looking at the following code sample:
async function subscribe() {
  let response = await fetch("/subscribe");

  if (response.status == 502) {
    // Status 502 is a connection timeout error,
    // may happen when the connection was pending for too long,
    // and the remote server or a proxy closed it
    // let's reconnect
    await subscribe();
  } else if (response.status != 200) {
    // An error - let's show it
    showMessage(response.statusText);
    // Reconnect in one second
    await new Promise(resolve => setTimeout(resolve, 1000));
    await subscribe();
  } else {
    // Get and show the message
    let message = await response.text();
    showMessage(message);
    // Call subscribe() again to get the next message
    await subscribe();
  }
}

subscribe();
Enter fullscreen mode Exit fullscreen mode

In general, this polling is really useful to display up to date data to the user without them needing to refresh the page.

If you would like to learn more about Server Side Events or Web Sockets that can bring even more value, check out this link.

🟢 How do we use Polling at Vue Storefront?

At Vue Storefront, we utilize the concept of Polling in the VSF Console project which is a storefront hosting and monitoring platform.

You can check out VSF Console documentation here if you are interested.

There is a feature called Performance Auditing that allows to run an audit against a website to get performance insights gathered from Page Speed Insights API and displayed in a visually attractive form:

VSF Console Polling

This allows to deliver users up to date performance audit information without them needing to refresh the page which is really good for User Experience.

Apart from just creating this polling locally (if you are staying at the same page) we decided to implement this polling as a global function that utilizes usage of local storage (by using Vue Use that I talked about in my previous article). This allows users to trigger Performance Audit and navigate to another page. When the audit will be successfully finished, user will receive a toast notification that the audit is ready for review.

What is more, if a user decides to close the website (tab) and reopen it, they will still receive the notification about the audit that was finished because it was saved to check this audit in the local storage. This is another step forward in utilizing polling.

The next step (not necesarily related to polling) would be to implement notification system that requires database, backend endpoints, and whole new desing in the frontend to utilize these notifications as an alternative to toasts. But this is a topic for another article 😃

📖 Learn more

If you would like to learn more about Vue, Nuxt, JavaScript or other useful technologies, checkout VueSchool by clicking this link or by clicking the image below:

Vue School Link

It covers most important concepts while building modern Vue or Nuxt applications that can help you in your daily work or side projects 😉

✅ Summary

Well done! You have just learned about the concept of polling and how you can utilize it in Vue to let user have up to date information in your app.

Take care and see you next time!

And happy coding as always 🖥️

Top comments (7)

Collapse
 
ygorbunkov profile image
ygorbunkov • Edited

There's no proper way to implement polling since it is a flawed concept on its own:

  • for a busy web app thousands of users bumping into API endpoint every few seconds WILL create considerable load onto backend
  • every server response is still a chunk of data sent to client down the wire which may be an issue for slow mobile connection
  • finding a good balance of polling interval (not too often, to create too much overload and not too rare, to get slow response) is nearly impossible, let alone to reconcile it with all the moving parts depending on polling

The bottom line - do Server Sent Events (for unidirectional data flow) or Web Sockets (for bidirectional), instead of polling at all times.

Collapse
 
jacobandrewsky profile image
Jakub Andrzejewski

Hey @ygorbunkov

Thanks for this comment. I completely agree with your points. This is for sure not a solution for very big applications that handle a lot of traffic. In our case, we have about 100 users where only about 10-20 of them use the feature that utilizes the polling. They need to trigger the audit manually and after triggering it, they will be blocked from triggering another one until the first one finishes.

This means that even if all of them at the same time decides to trigger polling, it will result in max 20 requests in the similar time.

I haven't used Server Sent Events yet but after your comment I am eager to try it :)

Collapse
 
ygorbunkov profile image
ygorbunkov

Regardless of the scale, polling, as a measure of implementing asynchronous data transfer, adds complexity to your front-end code. Which is never a good strategy: you should keep your client bundle as lightweight as possible and offload all the heavy lifting to big and powerful back-end hardware.

Collapse
 
fyodorio profile image
Fyodor

100% true, polling is a poor man’s pseudo real-time update implementation for cases when you (for some reason) cannot implement anything else (but need the fresh data). It’s definitely not a recommended practice.

Collapse
 
jacobandrewsky profile image
Jakub Andrzejewski

Hey @fyodorio

Thanks for your comment. This is our first take on implementation of real time updates in our app. It works well for the amount of users we have right now and our needs but after your comments, I think it would be reasonable to take a look at Websockets/Server Sent Events for a better implementation :)

Collapse
 
zmandel profile image
Zig Mandel

noooo this is a terrible example. do NOT use polling its a very bad practice that wont scale past your sample project. And these days its SO easy so use websockets or firebase realtime updates among many many other choices.

Collapse
 
jacobandrewsky profile image
Jakub Andrzejewski

Hey @zmandel

Thanks for the comment.

As I have mentioned in the comment above, in our case where we dont have that many users so this solution works well for us.

This is also a first take at implementing the polling from frontend for real time data. After getting some feedback from our users, we will probably refactor it to support the usage of local storage or server sent events/websockets.

We don't use Firebase realtime updates so this won't work for us.

In this article, I wanted to show the example how such polling could be implemented but now I see that I need to examine both web sockets and server sent events and write another article about it :)