arrow_backTech Blog
insert_chart
insert_chartVisualization2025-12-10·5 min read

ECharts Large Dataset Rendering Performance Optimization

Optimization strategies for rendering 10K+ data points in ECharts charts across water management and transit projects — sampling, incremental rendering, and Canvas tuning.

EChartsPerformanceCanvas

Problem Scenario

In the smart water project, water pressure trend charts needed to display 30 days × 24 hours × 60 minutes ≈ 43,200 data points. Direct rendering caused visible lag.

Users don't care how your chart is drawn, but they'll instantly notice a 3-second loading delay and frame drops during dragging.

This problem is common across IoT monitoring, smart transit, and similar scenarios. Devices report data every minute — one month's trend chart means tens of thousands of points. With 4-6 such charts on a dashboard simultaneously, rendering issues are amplified.

Bottleneck Analysis

Before optimizing, identify the bottleneck:

  • DOM renderingIn SVG mode, each data point is a DOM node — tens of thousands of nodes freeze the browser
  • Canvas drawingCanvas mode is much better, but drawing 40K+ points at once still blocks the main thread for 2-3 seconds
  • Interaction responsedataZoom dragging needs to clip and redraw data, causing frame rate to plummet
  • Memory usageMassive data stored in memory — multiple charts stacking pushes usage over 500MB
  • 💡

    The first step is always "measure" not "guess." Use Chrome DevTools' Performance panel to record the rendering process and identify which phase takes the most time.

    Optimization Strategies

    1. Data Downsampling

    Used LTTB (Largest Triangle Three Bucket) algorithm to downsample 40K+ points to 1,000, preserving trend characteristics while drastically reducing render load.

    LTTB's advantage: it doesn't simply "take every Nth point" but selects points that best preserve trend features. Downsampled curves are visually indistinguishable from originals.

    Implementation:

  • Backend samplingAPI layer calculates optimal sample count based on requested time range and chart width
  • Frontend samplingCombined with dataZoom zoom level, request finer data when users zoom in
  • 2. Incremental Rendering

    Combined with `dataZoom` component, only render data within the visible area and dynamically load on scroll.

    Core strategy:

  • Initially load only the last 24 hours
  • When users drag dataZoom, load additional time ranges on demand
  • Use `appendData` API to append rather than full-replace
  • The key to incremental rendering isn't technical difficulty — it's needing backend API cooperation: paginated queries, time range filtering, downsampling parameters. Collaboratively designed APIs are far more effective than one-sided optimization.

    3. Canvas Layer Optimization

    Used `progressive` and `progressiveThreshold` for chunked rendering to avoid main thread blocking.

    Configuration:

  • `progressive: 400` (draw 400 points per frame)
  • `progressiveThreshold: 3000` (enable progressive rendering above 3000 points)
  • `animation: false` (disable animations for large datasets to reduce rendering overhead)

  • Additional Optimizations

    Virtualized Tooltip

    Default tooltips search for the nearest data point on every mouse move — linear search across 40K points is very slow. Solution: binary search on time-sorted data.

    On-demand ECharts Module Loading

    Don't import the full echarts package — only import needed chart types and components. This reduces bundle size by ~40%.

    Web Worker Preprocessing

    Move CPU-intensive tasks like data formatting and sampling to Web Workers, preventing UI thread blocking.

    ⚠️

    Don't manipulate Canvas in Web Workers. ECharts rendering must stay on the main thread, but data preprocessing can be offloaded.


    Results

    Initial render time dropped from 3.2s to 0.4s, interaction drag maintained stable 60fps.

    Specific metrics:

  • Initial render3.2s → 0.4s (-87%)
  • dataZoom drag FPS12fps → 60fps
  • Memory usage512MB → 180MB (-65%)
  • Bundle size-40% (on-demand loading)
  • Performance optimization isn't a one-time effort — it's an ongoing process. Post-launch, we built monitoring dashboards tracking each chart's render time and memory usage.

    Conclusion

    Core approach for large dataset chart rendering: reduce data volume (sampling) → reduce render volume (on-demand/incremental) → reduce blocking (chunking/Workers). This approach isn't ECharts-specific — it applies to any visualization scenario.

    💡

    If your dataset exceeds 10K points, don't render directly — downsample first. On a 1920px screen, users literally cannot distinguish between 1,000 and 40,000 points visually.

    insert_chart