A simple way to detect if your JS App is online/offline/or having a slow connection (+ Alerts, + Emulating the slow Internet)
Tags: javascript, webdev, tutorial
Published: 2020-06-22 19:56:01

---
title: A simple way to detect if your JS App is online/offline/or having a slow connection (+ Alerts, + Emulating the slow Internet)
published: true
description: Detect in Javascript if offline, online, back online, and auto-reconnect.
tags: javascript, webdev, tutorial
cover_image: https://dev-to-uploads.s3.amazonaws.com/i/cjv2nx2co222xi7w12pr.gif
---

In this article, we will cover 3 things:

1. How to detect your JS application (it can be SPA, PWA, Electron, or plain JS) is having a troubled connection (slow, offline), when it gets back online and how to re-download the data without a page refresh (in case it hasn't got enough time to finish while online).

2. Creating a simple JS application that downloads and displays a picture, where we would cover all the cases from a previous step.

3. Learning how to throttle the Internet connection in Chrome, and test the application we created.

---

## **Step 1.**

To detect if the application got offline, or back online, is quite simple:

```js
window.addEventListener("offline", () => {
  console.log("I am offline.");
});

window.addEventListener("online", () => {
  console.log("I am back online.");
});
```

If you are building a Chrome extension that requires the Internet connection, for example to upload a file to Google Drive, you can leverage following:

```js
if (!navigator.onLine) {
  return false;
}

// Upload the file...
```

To detect if the application is loading for too long, can be done by creating a timer and giving it a time, after which we assume the connection is slow, if not loaded yet. After the application is loaded, we reset the timer. Here's an example code:

```js
// Our simple App
const App = async (onstart, onload) => {
  onstart();

  // Loading...
  
  // The application is now loaded
  onload();
}

let isSlow;
let loaded;

App(
  () => {
    isSlow = setTimeout(() => {
      console.log("Thing are getting slow...");
    }, 10000); // 10 seconds
  },
  () => {
    clearTimeout(isSlow);
    loaded = true;
    console.log("Loaded.");
});
```

The logic by which we decide if the application is loading for too long, depends on our app.

Now, we can proceed to the next step.

## **Step 2.**

We will now create a simple app, that will load a random picture from https://picsum.photos. If the Internet connection will get slow, offline, or back online, we will display a particular message:

![Alt Text](https://dev-to-uploads.s3.amazonaws.com/i/re9hfmp79j94htxamf74.png)

![Alt Text](https://dev-to-uploads.s3.amazonaws.com/i/fyrmnohybgvdvhhumcyi.png)

![Alt Text](https://dev-to-uploads.s3.amazonaws.com/i/a43ggzix743j9dznqdno.png)

The app will look like this:

![Alt Text](https://dev-to-uploads.s3.amazonaws.com/i/38egzojmcldc34at7iwg.png)

The message will be displayed in the top center when needed. To make the loading of an image visually nicer, it will have a pulsing effect to it.

Let's start by creating `index.html`:

```html
<!DOCTYPE html>
<html>
<head>
  <meta charset="utf-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>App</title>
  <link rel="stylesheet" href="app.css">
</head>
<body>
  <div id="slow" class="message">Slow Internet Connection.</div>
  <div id="offline" class="message">No Internet Connection.</div>
  <div id="online" class="message">Back Online.</div>

  <div id="app"></div>

  <script src="app.js"></script>
</body>
</html>
```

Continue by creating `app.css`:

```css
body {
  margin: 0;
  padding: 4em;
  font-family: Arial, Helvetica, sans-serif;
}

@keyframes pulse {
  0% { background-color: #f1f1f1; }
  100% { background-color: silver; }
}

img {
  width: 640px;
  height: 480px;
}

img.loading {
  animation: pulse 1s ease-out alternate infinite;
}

.message {
  position: fixed;
  left: 50%;
  top: 0;
  font-size: 2em;
  font-weight: bold;
  padding: 1.5em;
  transform: translate(-50%, -100%);
  transition: transform .25s;
}

#slow {
  background: #FF9800;
  color: white;
}

#offline {
  background: #E91E63;
  color: white;
}

#online {
  background: #4CAF50;
  color: white;
}

body.slow #slow,
body.offline #offline,
body.online #online {
  transform: translate(-50%, 0);
}
```

Messages (or Alerts) have different color each, and are off the screen when not needed. When required, the message slides in from the top center.

And finally, create `app.js`:

```js
// Simple App that loads a picture.
const App = (onstart, onload) => {
  onstart();

  const h1 = document.createElement("h1");
  h1.innerText = "App";

  const img = document.createElement("img");
  img.src = "https://picsum.photos/640/480";
  img.className = "loading";
  img.onload = () => {
    img.className = "";
    onload();
  };

  const app = document.getElementById("app");
  app.innerHTML = "";
  app.append(h1);
  app.append(img);
}

let isSlow;
let loaded;

const loadApp = () => {
  App(
    () => {
      loaded = false;
      isSlow = setTimeout(() => {
        // Show "Slow Internet Connection." message.
        document.body.className = "slow";
        console.debug("slow");
      }, 1500); // Intentionally a low number for testing. Try some different values here, or play with different Internet Throttling setting.
    },
    () => {
      loaded = true;
      clearTimeout(isSlow);
      setTimeout(() => { document.body.className = ""; }, 1000); // Hide message after 1s.
      console.debug("loaded");
  });
};


// We are "offline".
window.addEventListener("offline", () => {
  // Show "No Internet Connection." message.
  document.body.className = "offline";
});


// When we back "online".
window.addEventListener("online", () => {
  // Show "Back online" message.
  document.body.className = "online";
  console.debug("online");

  // Hide message after 1s.
  setTimeout(() => { document.body.className = ""; }, 1000);

  // There was not enough time to load the App. Do it again.
  if (!loaded) {
    console.debug("Reconnecting...");
    loadApp();
  }
});


window.addEventListener("DOMContentLoaded", loadApp);
```

This simple App will load a picture and display it. While the picture is loading, it will have a `.loading` class added, to show the pulse effect. After the image is loaded, the `.loading` class will be removed, and the timer will be stopped. If the loading took longer than we specified, `Slow Internet Connection.` message will be shown.

If the Internet is off, `No Internet Connection.` message will be displayed, and once back online, `Back Online.` message will be displayed.

In case the picture wasn't loaded before we got offline, it will be loaded once again we are back online.

## **Step 3.**

Time to test our App under different network conditions. Open **Chrome -> DevTools -> Network**, look for **Throttling** section and click **Add...**.

![Alt Text](https://dev-to-uploads.s3.amazonaws.com/i/qj33dsyspej2ub9kja5t.png)

![Alt Text](https://dev-to-uploads.s3.amazonaws.com/i/p8las34m39jz2xlft63k.png)

Define 2 new **Throttling** profiles as seen below:

![Alt Text](https://dev-to-uploads.s3.amazonaws.com/i/pj8b34waa7e6w2m2mew1.png)

A random picture we are about to display, can range anywhere from **20KB** to **80KB** in size, that means, in **Very slow** profile that would take about 5 seconds to load, in **Incredibly slow** profile about 30 seconds. We basically adjust the speed to the size of content, to get a good testing.

Now, open `index.html` with the **DevTools** open (to have **Throttling** applied), keep refreshing the page with different initial **Throttling** setting (**Online**, **Offline**, **Very slow** or **Incredibly slow**), and try changing the profile while the page is loading (from **Offline** to **Online**; from **Incredibly slow** to **Offline** to **Online**; etc.).

It can look like this:

![Alt Text](https://dev-to-uploads.s3.amazonaws.com/i/mei2bjkd18s1wmp8m0ig.gif)

That's it. I hope you enjoyed the article and had fun!

**And. Thank you for reading!** 🙂