Skip to main content
WebSockets Tutorial
CHAPTER 15 Beginner

Live Dashboard and Data Streaming

Updated: May 14, 2026
30 min read

# CHAPTER 15

Live Dashboard and Data Streaming

1. Introduction

WebSockets are not just for typing messages to other humans; they are incredible for machine-to-human communication. When dealing with rapidly changing data—such as server CPU usage, stock market prices, or live voting results—traditional HTTP polling is too slow and heavy. In this chapter, we will learn how to stream data rapidly over WebSockets to power a live, updating visual dashboard.

2. Learning Objectives

By the end of this chapter, you will be able to:
  • Understand the concept of data streaming.
  • Receive rapid numeric updates via WebSockets.
  • Integrate WebSockets with a JavaScript charting library.
  • Optimize the UI to prevent lag when receiving high-frequency messages.

3. Beginner-Friendly Explanation

Imagine watching a speedometer in a car. It doesn't update once every 10 seconds; the needle glides smoothly as your speed changes instantly. A Live Dashboard on the web aims for this exact feeling. A backend machine constantly "streams" tiny pieces of data over the WebSocket (e.g., {"speed": 65}... {"speed": 67}). The frontend instantly takes that number and moves the needle on a visual chart, giving the user a real-time view into what is happening under the hood.

4. Real-World Examples

  • Cryptocurrency Exchanges: Binance and Coinbase use WebSockets to update the order book and price charts multiple times a second.
  • Admin Dashboards: Monitoring tools like Grafana show live graphs of memory usage and server traffic.
  • Live Sports: Real-time possession stats and score updates during a football match.

5. Step-by-Step Tutorial

Let's build a live Bitcoin price tracker using a charting library called Chart.js.

Step 1: Include Chart.js via CDN. Step 2: Create an HTML <canvas> element for the chart. Step 3: Initialize an empty Line Chart in JavaScript. Step 4: Connect to a public WebSocket that streams live crypto prices (e.g., Binance's public stream). Step 5: In the onmessage event, extract the new price, push it to the chart's dataset, and call chart.update().

6. The Live Dashboard Example

Here is a complete, working example connecting to Binance's live trade stream for BTC/USDT.

7. HTML, Tailwind & Chart.js Example

html
12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Live Crypto Dashboard</title>
    <script src="https://cdn.tailwindcss.com"></script>
    <script src="https://cdn.jsdelivr.net/npm/chart.js"></script>
</head>
<body class="bg-gray-900 text-white p-10 font-sans">

    <div class="max-w-4xl mx-auto">
        <h1 class="text-3xl font-bold text-center mb-2">Live BTC/USDT Price</h1>
        <p class="text-center text-gray-400 mb-8" id="live-price">Waiting for data...</p>

        <!-- Chart Container -->
        <div class="bg-gray-800 p-4 rounded-lg shadow-xl">
            <canvas id="priceChart"></canvas>
        </div>
    </div>

    <script>
        // 1. Setup the Chart
        const ctx = document.getElementById(&#039;priceChart').getContext('2d');
        const priceChart = new Chart(ctx, {
            type: &#039;line',
            data: {
                labels: [], // Time labels
                datasets: [{
                    label: &#039;Bitcoin Price ($)',
                    data: [], // Price data
                    borderColor: &#039;#3b82f6',
                    backgroundColor: &#039;rgba(59, 130, 246, 0.2)',
                    borderWidth: 2,
                    tension: 0.4, // Curvy lines
                    pointRadius: 0
                }]
            },
            options: {
                responsive: true,
                scales: { x: { display: false } },
                animation: false // Disable animation for high-frequency updates!
            }
        });

        // 2. Connect to Binance Public WebSocket
        // Streams every single trade that happens in real-time
        const socket = new WebSocket(&#039;wss://stream.binance.com:9443/ws/btcusdt@trade');
        const priceText = document.getElementById(&#039;live-price');

        // Keep maximum 50 data points on the screen to prevent lag
        const MAX_DATA_POINTS = 50;

        socket.onmessage = function(event) {
            const data = JSON.parse(event.data);
            
            // Binance payload has 'p' for price
            const currentPrice = parseFloat(data.p).toFixed(2);
            priceText.innerText = `$${currentPrice}`;

            // Add new data to chart
            const time = new Date().toLocaleTimeString();
            priceChart.data.labels.push(time);
            priceChart.data.datasets[0].data.push(currentPrice);

            // Remove oldest data point if we exceed max
            if (priceChart.data.labels.length > MAX_DATA_POINTS) {
                priceChart.data.labels.shift();
                priceChart.data.datasets[0].data.shift();
            }

            // Tell Chart.js to redraw
            priceChart.update();
        };
    </script>
</body>
</html>

8. Performance Considerations (Throttling)

In the example above, Binance might send 10 messages per second. Calling chart.update() 10 times a second can heavily tax the browser's CPU. When streaming high-frequency data, use Throttling. Update the data array immediately, but only call chart.update() once every second using a setInterval.

9. Throttling Example

javascript
1234567891011
// Accumulate data as it arrives
socket.onmessage = function(event) {
    const newPrice = JSON.parse(event.data).p;
    priceChart.data.datasets[0].data.push(newPrice);
    // Note: Do NOT call update() here!
};

// Update the visual chart only twice a second
setInterval(() => {
    priceChart.update();
}, 500);

10. Best Practices

  • Turn off visual animations: Charting libraries try to animate lines smoothly. If you are updating the chart multiple times a second, these animations will queue up and cause severe visual lag. Always set animation: false in your chart config.
  • Garbage Collection: Always shift() (remove) old data points from your arrays (as shown in the example with MAXDATAPOINTS). If you let arrays grow infinitely for hours, the browser will crash from memory exhaustion.

11. Common Mistakes

  • Rendering too much data: Humans cannot comprehend data that changes 50 times a second. It just looks like a blur. It is entirely acceptable for the server to send data at 50hz, but for the UI to only average out and display that data at 2hz.

12. Mini Exercises

  1. 1. Save the code in Section 7 to an HTML file and run it. You will see a professional-looking cryptocurrency chart updating live in front of your eyes!
  1. 2. Change the btcusdt@trade in the URL to ethusdt@trade to see Ethereum prices instead.

13. Coding Challenges

Challenge 1: Modify the code so that if the currentPrice is higher than the previous price, the live-price text turns green (text-green-500). If it is lower, it turns red (text-red-500).

14. MCQs with Answers

Question 1

Why should you disable animations (animation: false) in charting libraries when streaming live WebSocket data?

Question 2

What happens if you continuously push data into a chart array without removing old data points?

15. Interview Questions

  • Q: What is "Throttling" and why is it important when rendering high-frequency WebSocket streams in the browser UI?
  • Q: Explain how you would manage memory when keeping a live dashboard open for 24 hours straight.

16. FAQs

Q: Can I use D3.js or Highcharts instead of Chart.js? A: Yes! WebSockets just deliver the JSON. Once the data is in your onmessage function, you can pass it to absolutely any charting, 3D, or mapping library you prefer.

17. Summary

In Chapter 15, we built a highly visual data-streaming dashboard. We learned that WebSockets excel at delivering high-frequency data, but as frontend developers, we must carefully manage browser memory (by deleting old data) and CPU usage (by turning off animations and throttling updates) to ensure a smooth user experience.

18. Next Chapter Recommendation

Handling 10 messages a second for one user is easy. But what if you have 10,000 users all watching that same chart? Proceed to Chapter 16: Scaling WebSocket Applications to understand the architectural challenges of massive scale.

Finish this Chapter

Save your progress on your learning path and prepare for coding interview challenges.

Discussion

Join the discussion

Log in or create a free account to participate.

Sort: ·