Introduction
In today's rapidly evolving fintech landscape, real-time market data streaming for assets such as stocks, foreign exchange, and cryptocurrencies has become the core competitive advantage of financial information websites. Users seek trading opportunities amidst millisecond-level price fluctuations, placing extremely high demands on data real-time performance, accuracy, and display smoothness. Traditional HTTP polling solutions have long proven inadequate. This article systematically elaborates on the technical solutions and practical experiences for building production-grade financial information websites from three dimensions: market data integration, multi-asset market data display, and full-stack performance optimization for both frontend and backend.
I. Market Data Integration: REST + WebSocket Hybrid Architecture
1.1 Why WebSocket is Essential?
Traditional HTTP polling solutions suffer from three fatal flaws in financial market data streaming scenarios: severe resource waste—approximately 80% of polling requests return empty data, consuming substantial bandwidth and CPU; uncontrollable latency—shorter polling intervals exacerbate server load, while longer intervals fail to capture short-term fluctuations; obvious connection bottlenecks—difficult to support massive concurrent users receiving market data simultaneously in high-concurrency scenarios.
The WebSocket protocol establishes a persistent full-duplex communication channel through a single HTTP handshake, enabling servers to proactively push data to clients, perfectly matching the core requirements of financial scenarios: end-to-end latency can be reduced to within 100ms, bandwidth consumption decreased by 62% compared to HTTP polling, and a single node can easily support over 100,000 concurrent connections. Empirical data shows that WebSocket-based market data streaming systems can achieve availability exceeding 99.99%, with data loss rates below 0.0001%.
Dual-Link Collaborative Design: REST + WebSocket
A single interface invocation method cannot balance initial page loading and real-time streaming. The optimal practice adopts a cloud-native architecture with HTTP and WebSocket dual-link collaboration:
- HTTP Link: Handles historical data retrieval and initial snapshots, reducing repeated request pressure and enabling rapid first-screen data display.
- WebSocket Link: Responsible for tick-level real-time streaming, ensuring millisecond-level updates on the user side.
Taking iTick as an example, we demonstrate the core implementation of multi-category market data integration.
Frontend Integration: Using @itick/browser-sdk
iTick officially provides JavaScript/TypeScript SDKs with built-in automatic reconnection (5-second interval, configurable) and heartbeat keepalive (30-second Ping/Pong), eliminating the need for manual connection state management. The following code demonstrates how to subscribe to real-time quotes and trade data for BTCUSDT and ETHUSDT:
import { CryptoClient } from "@itick/browser-sdk";
const token = "your_api_token";
// Initialize client
const client = new CryptoClient(token);
// Create WebSocket connection and automatically subscribe to data
const socket = client.createSocket({
maxReconnectTimes: 10, // Maximum reconnection attempts, 0 for unlimited
pingInterval: 30000, // Ping interval (milliseconds), default 30 seconds
reconnectInterval: 5000, // Reconnection interval (milliseconds), default 5 seconds
subscribeData: {
codes: ["BTCUSDT$BA", "ETHUSDT$BA"],
types: ["quote", "tick"], // Subscription types: quote and tick
},
});
// Handle received real-time data
socket.onSocketMessage((res) => {
console.log("Received market data:", res);
});
// Handle errors
socket.onSocketError((error) => {
console.error("WebSocket error:", error);
});
If manual subscription timing management is required, you can establish the connection first and then invoke the subscription method:
const socket = client.createSocket();
socket.onSocketOpen(() => {
// Send subscription request after successful connection
socket.subscribeData({
codes: ["BTCUSDT$BA", "ETHUSDT$BA"],
types: ["quote", "tick"],
});
});
Upon successful subscription, WebSocket will stream real-time latest quotes and trade-by-trade records for selected instruments. Each message contains key fields such as price, volume, and timestamp, which can be parsed and directly rendered to frontend market lists or candlestick charts after processing.
Backend Integration: Using itick-sdk (Python / Java)
Backend services can also efficiently integrate market data streams through iTick SDK. Python version example:
from itick.sdk import Client
token = "your_api_token"
client = Client(token)
# Set message handling callback
def on_message(message):
print(f"Received market data: {message}")
def on_error(error):
print(f"WebSocket error: {error}")
client.set_message_handler(on_message)
client.set_error_handler(on_error)
# Connect to forex WebSocket
client.connect_forex_websocket()
# Send subscription request (major currency pairs like EURUSD)
client.send_websocket_message('{"action": "subscribe", "codes": ["EURUSD"]}')
The Java version is equally concise, with the SDK featuring built-in automatic reconnection and heartbeat keepalive mechanisms:
import io.itick.sdk.Client;
String token = "your_api_token";
Client client = new Client(token);
// Set callback functions
client.setMessageHandler(message -> {
System.out.println("Received market data: " + message);
});
client.setErrorHandler(error -> {
System.err.println("WebSocket error: " + error.getMessage());
});
// Connect to forex WebSocket
client.connectForexWebSocket();
// Send subscription message
client.sendWebSocketMessage("{\"action\": \"subscribe\", \"codes\": \"EURUSD\"}");
Whether using frontend or backend SDKs, iTick incorporates automatic reconnection and heartbeat keepalive capabilities, allowing users to focus on business-layer data processing and display without manually managing connection states. This architecture has been validated in multiple quantitative trading and production-grade financial information systems, supporting the full-link closed loop from real-time market monitoring to algorithmic trading strategies.
1.3 Connection Reliability Assurance
Financial market data reliability requirements far exceed those of ordinary web applications. Even when using mature third-party SDKs, comprehensive assurance mechanisms remain necessary in production environments:
- Application-layer heartbeats: The SDK's built-in 30-second Ping/Pong satisfies most scenarios. However, in extremely unstable network environments, it is recommended that the business layer additionally send custom ping messages. If no response is received after two consecutive attempts, the connection is deemed invalid, immediately triggering reconnection.
- Exponential backoff reconnection: While the SDK defaults to fixed-interval reconnection, advanced users can customize exponential backoff strategies based on SDK-provided reconnection callbacks. Start with a 1-second initial interval, doubling after each failure, capped at 30-60 seconds, with random jitter (0.8-1.2x coefficient) added to avoid "reconnection storms."
- Session recovery: Upon successful reconnection, automatically resubscribe to previous market instruments. Leverage iTick's message sequence number (seq) functionality to retrieve missing data during disconnection periods, ensuring market data is neither lost nor duplicated.
II. Multi-Asset Market Data Display: High-Performance Frontend Rendering Architecture
Financial information websites need to simultaneously display market data for various assets including stocks, forex, funds, and futures on a single page, often involving thousands of market data entries. Traditional full DOM rendering leads to page stuttering and surging memory consumption, necessitating multi-dimensional performance optimization.
2.1 Virtual Lists: Breaking Through Massive Market Data Item Rendering Bottlenecks
When market list data exceeds hundreds of entries, traditional rendering methods generate all DOM nodes at once, causing page stuttering and memory spikes. Virtual lists render only DOM nodes within the visible area and dynamically reuse these nodes to simulate complete lists, reducing actual rendered DOM count from thousands to dozens.
Core implementation logic of virtual lists:
- Visible area calculation: Calculate the range of list items visible on screen based on container total height, scroll position, and individual item height;
- Partial DOM rendering: Generate only DOM nodes within the visible area;
- Placeholder filling: Use placeholder containers to fill the entire list's total height, simulating a complete scrollbar;
- Dynamic reuse: Reuse existing DOM nodes and refresh content during scrolling instead of recreating them.
Taking the Vue ecosystem as an example, when using vue-virtual-scroller to handle 100,000 data entries, rendered nodes decrease from 100,000 to 20-30, memory consumption drops from 350MB+ to approximately 15MB, and scroll frame rate improves to 60fps.
<DynamicScroller :items="stocks" :min-item-size="48">
<template v-slot="{ item, index }">
<DynamicScrollerItem :item="item">
<div class="stock-row">
<span>{{ item.symbol }}</span>
<span :class="item.change >=0 ? 'up' : 'down'">
{{ item.price }}
</span>
</div>
</DynamicScrollerItem>
</template>
</DynamicScroller>
2.2 Candlestick Charts and Real-Time Chart Optimization
As core visualization components of financial information websites, candlestick charts face rendering challenges involving tens of thousands or even millions of data points.
Chart library selection: In professional-grade financial charting scenarios, Highcharts Stock offers unique advantages over ECharts. Highcharts Stock features a built-in Data Grouping mechanism that can compress tens of thousands of points into hundreds for rendering without sacrificing visual trends. When data reaches million-level scale, the WebGL Boost module enables GPU hardware acceleration, achieving smooth 60fps zooming.
Real-time data update pattern: Tick data streamed via WebSocket requires efficient chart update driving. Best practices avoid triggering complete chart redraws with every data change, instead utilizing incremental update methods (such as Highcharts' series.addPoint() combined with the shift parameter). This adds the latest price point to the data queue's end while removing old points from the front, maintaining a fixed-length sliding window.
// Highcharts real-time data incremental update
chart.series[0].addPoint([timestamp, price], true, true);
For ECharts solutions, combine the appendData method or directly update the series.data array and call setOption to achieve incremental data appending.
2.3 Debouncing and Throttling: Taming High-Frequency Events
In real-time market scenarios, WebSocket streaming frequency may reach dozens of times per second. Directly updating all UI components severely impacts performance. Debouncing and throttling are two powerful tools for controlling function execution frequency:
- Debouncing: Executes only the last invocation during continuous event triggering, suitable for scenarios with clear "pause points" such as search suggestions and form validation.
- Throttling: Ensures at most one execution within fixed time intervals, suitable for scenarios requiring "rhythmic execution" such as scroll event monitoring and chart data refreshing.
For market data updates, it is recommended to apply throttling to UI refresh operations, ensuring UI update frequency remains within perceptibly smooth ranges for users (e.g., 60fps means updating approximately every 16.7ms), avoiding interface stuttering caused by high-frequency streaming.
2.4 Local Caching and Incremental Updates
To reduce redundant data requests, integrate IndexedDB on the frontend to establish local market data caching. Historical data needs to be fetched from the server only once, stored in the local database, and subsequently read directly. Real-time market data adopts incremental update strategies where servers push only changed portions (such as latest prices, percentage changes, and volumes), with clients performing incremental merge updates, significantly reducing network transmission volume and frontend parsing overhead.
III. Performance Optimization: Full-Stack Acceleration from Edge to Core
3.1 CDN Acceleration: Proximity Access and Edge Distribution
Static resources (CSS, JS, images, etc.) of financial information websites deployed through CDNs enable proximity access and reduced latency. Modern Dynamic Content Delivery Network (DCDN) products further support dynamic resource acceleration beyond static resource acceleration, providing Layer 7 acceleration for protocols including HTTP, HTTPS, and WebSocket, adapting to diverse business scenarios such as financial information and real-time market data.
CDN's core value manifests in three aspects: extensive node deployment—users obtain resources from nearest edge nodes, reducing transmission distance; intelligent caching—popular resources cached at edge nodes improve hit rates and response speeds; traffic distribution—disperses origin server pressure, allowing core servers to focus on processing dynamic market requests.
Industry practices demonstrate that advanced CDN architectures can support peak concurrency of 250,000 requests per second when facing financial-grade traffic surges, ensuring stable business operations.
3.2 WebSocket Edge Acceleration for Cross-Border Scenarios
For cross-border financial information scenarios (such as overseas exchange market data distributed to domestic users), WebSocket persistent connections are highly susceptible to interruption due to network jitter in public internet environments. Cutting-edge practices adopt non-filing CDN architecture + WebSocket deep optimization: origin servers push market data only to nearest edge nodes, where edge nodes perform rapid fan-out among tens of thousands of user connections through high-performance in-memory message queues, reducing origin server pressure by three orders of magnitude. Meanwhile, UDP-based WebSocket encapsulation (similar to QUIC) is supported between edge nodes and clients, leveraging connection migration characteristics to achieve "seamless continuation" during network switches.
3.3 Server-Side High-Concurrency Streaming Architecture
Market data system server-side design must balance "high availability, scalability, and fault tolerance," constructing a layered architecture:
- Trigger Layer: Scheduled tasks or exchange push events ensure second-level data retrieval.
- Collection Layer: Prevent API rate limiting through proxy IPs and rotating User-Agents.
- Buffer Layer: Use Kafka / Redis Stream to temporarily store market data, preventing database congestion and supporting parallel multi-consumer processing.
- Storage Layer: MySQL stores historical data, Redis caches real-time market data, supporting second-level queries.
- Streaming Layer: WebSocket streams latest market data to users at second-level intervals.
The full link employs incremental updates and data compression techniques to optimize transmission, with built-in message deduplication mechanisms ensuring ordered, lossless, non-duplicated data in high-frequency market scenarios involving tens of thousands of messages per second.
IV. Results Summary and Future Outlook
Through comprehensive implementation of the above technical solutions, financial information websites can achieve the following core metrics:
| Metric | Optimization Result |
|---|---|
| Market data latency | <100ms (millisecond-level) |
| WebSocket concurrent connections | 100,000+ per node |
| Long list rendered DOM nodes | Reduced by over 99% |
| Scroll frame rate | Smooth 60fps experience |
| System availability | 99.99% |
| Data loss rate | <0.0001% |
Building financial information websites is a systematic engineering endeavor. From the dual-link hybrid architecture for data integration, to frontend virtual lists + chart optimization + debouncing/throttling, and finally to the full-stack CDN acceleration + server-side high-concurrency architecture, optimization at every stage directly correlates with user experience.
Looking ahead, the combination of WebSocket + HTTP/3 (QUIC) will bring lower latency and stronger stability to cross-border financial market data transmission. Meanwhile, WebAssembly's large-scale data processing capabilities on the client side promise to further break through frontend performance bottlenecks. Technological evolution knows no bounds; providing financial users with "what you see is what you get" real market pulse remains our unwavering pursuit as technologists.
Reference Documentation: https://docs.itick.org/sdk/python-sdk
GitHub: https://github.com/itick-org/
Top comments (0)