Network Information API for PWAs

How to determine real network data in your web app

The Network Information API for PWAs

If you’ve ever been developing progressive web apps that require more detailed information about the current network state than just a simple online/offline boolean value, a new API is now available, called “Network Information API”.

As with basically every new modern browser feature, you can progressively enhance your web application with just a few lines of code to learn about the current connection’s speed.

A new property for the navigator

The navigator-object got enhanced with a new property called “connection”, which enables both a one-time read of the network state as well as a subscription to react to changes in the network type. Note that, as of writing, only Chrome fully supports the API. Safari and Firefox don’t support it at all. Other Chromium-based browsers such as Edge or Opera have nearly full support, including the most important metrics.

Real network data in your web application

The following code shows a complete example of how you can use this new Network Information API. For a real world demonstration, just scroll to the very bottom of a page of this PWA. If your browser supports the API, you’ll see a Signal-icon and a label showing the categorization of your current network speed. If the feature isn’t supported in your browser, an appropriate label is rendered as well.

Of course you can play around with this feature by opening the DevTools of your browser and simulating a network-throttle via the network tab.

//
// Description:
//
// This is the exact React-hook I'm
// using on flaming.codes to classify
// the current network state.
//
// Note that the 'Network Information API'
// doesn't provide a flag for offline
// scenarios, therefore I added one to
// the network state object.
//
// This hook also only uses a subset of all
// (possible) available information, please
// see the MDN-docs for more information:
// 👉 https://developer.mozilla.org/en-US/docs/Web/API/NetworkInformation
//

/**
 * Read the current network classification
 * provided by the browser via the navigator.
 * 
 * @returns   The network state.
 */
export function useNetworkInformation() {
  const [state, setState] = useState<{
    isEnabled?: boolean;
    type?: string;
    // Directly taken from
    // 👉 https://developer.mozilla.org/en-US/docs/Web/API/NetworkInformation/effectiveType
    effectiveType?: "slow-2g" | "2g" | "3g" | "4g" | "offline";
  }>({});

  useEffect(() => {
    const connection =
      // @ts-ignore
      navigator?.connection || navigator?.mozConnection || navigator?.webkitConnection;

    if (connection) {
      setState({
        isEnabled: true,
        type: connection.type,
        effectiveType: connection.effectiveType,
      });
    }

    function updateConnectionStatus() {
      setState({
        isEnabled: true,
        type: connection.type,
        effectiveType: navigator?.onLine ? connection.effectiveType : "offline",
      });
    }

    connection?.addEventListener("change", updateConnectionStatus);
    return () => {
      connection?.removeEventListener("change", updateConnectionStatus);
    };

    // Only run on mount explicitly.
    // eslint-disable-next-line react-hooks/exhaustive-deps
  }, []);

  return state;
}

Closing words

As you can see, the code required to gain a detailed insight into your clients’ network speeds is now easier than ever, thanks to advancements in the Chromium engine. There’s no need to keep polling a custom server and managing a history of data points to calculate the speed by yourself.

Suggestions

Related

Addendum

Languages