阿里云主机折上折
  • 微信号
Current Site:Index > Performance optimization configuration

Performance optimization configuration

Author:Chuan Chen 阅读数:3215人阅读 分类: ECharts

Performance Optimization Configuration

ECharts, as a powerful data visualization library, may encounter performance bottlenecks when handling large-scale data or complex charts. Reasonable configurations can significantly improve rendering efficiency and interactive experience.

Data-Level Optimization

Data sampling is a core optimization technique for big data scenarios. When data points exceed tens of thousands, it is recommended to enable dataSampling:

series: [{
  type: 'line',
  data: largeDataSet,
  sampling: 'lttb',  // Largest-Triangle-Three-Buckets algorithm
  progressive: 1e6,   // Progressive rendering threshold
  progressiveThreshold: 500
}]

Chunked loading is suitable for ultra-large datasets (>10MB):

function fetchData(page) {
  return fetch(`/api/data?page=${page}&size=10000`).then(res => res.json());
}

let currentPage = 0;
chart.showLoading();
fetchData(currentPage++).then(initData => {
  chart.hideLoading();
  const option = {
    dataset: { source: initData },
    series: [{ type: 'scatter' }]
  };
  chart.setOption(option);
  
  // Scroll to load more data
  window.addEventListener('scroll', async () => {
    if (shouldLoadMore()) {
      const moreData = await fetchData(currentPage++);
      chart.appendData({
        seriesIndex: 0,
        data: moreData
      });
    }
  });
});

Rendering Configuration Optimization

Animation strategy should be dynamically adjusted based on data volume:

animationDuration: dataLength > 1000 ? 0 : 1000,
animationEasing: 'elasticOut',
animationThreshold: 1500  // Disable animation if data points exceed 1500

Hybrid rendering combines the advantages of Canvas and SVG:

const option = {
  renderer: 'canvas',  // Use Canvas for large datasets
  useDirtyRect: true,  // Enable dirty rectangle rendering
  series: [{
    type: 'pie',
    renderAsImage: true  // Pre-render static charts as images
  }]
};

Visual Element Simplification

Visual mapping as an alternative to traditional legends:

visualMap: {
  type: 'continuous',
  dimension: 2,
  seriesIndex: 0,
  min: 0,
  max: 100,
  inRange: {
    color: ['#313695', '#4575b4', '#74add1', '#abd9e9', '#e0f3f8']
  },
  calculable: true
}

Label display strategy optimization:

label: {
  show: true,
  position: 'top',
  formatter: params => {
    return params.dataIndex % 5 === 0 ? params.value : '';
  },
  fontSize: dataLength > 500 ? 0 : 12
}

Interaction Performance Improvement

Debouncing high-frequency events:

let resizeTimer;
window.addEventListener('resize', () => {
  clearTimeout(resizeTimer);
  resizeTimer = setTimeout(() => {
    chart.resize();
  }, 200);
});

Area selection optimization:

tooltip: {
  trigger: 'axis',
  axisPointer: {
    type: 'shadow',
    shadowStyle: {
      color: 'rgba(150,150,150,0.1)'
    }
  },
  confine: true  // Restrict to chart area
}

Memory Management Techniques

Timely cleanup of unused instances:

// When unmounting the component
beforeUnmount() {
  this.chart.dispose();
  this.chart = null;
  window.removeEventListener('resize', this.handleResize);
}

Shared datasets to reduce memory usage:

const commonSource = [...];
const option = {
  dataset: [{
    id: 'sharedData',
    source: commonSource
  }],
  series: [{
    type: 'line',
    datasetId: 'sharedData'
  },{
    type: 'bar',
    datasetId: 'sharedData'
  }]
};

Advanced Optimization Techniques

WebWorker for compute-intensive tasks:

// worker.js
self.onmessage = function(e) {
  const result = heavyCompute(e.data);
  postMessage(result);
};

// Main thread
const worker = new Worker('worker.js');
worker.postMessage(largeData);
worker.onmessage = function(e) {
  chart.setOption({ dataset: { source: e.data } });
};

GPU acceleration configuration:

const option = {
  series: [{
    type: 'heatmap',
    progressive: true,
    itemStyle: {
      opacity: 0.8
    },
    emphasis: {
      itemStyle: {
        opacity: 1
      }
    }
  }],
  graphic: {
    elements: [{
      type: 'image',
      style: {
        image: '/texture.png',
        width: 400,
        height: 400
      },
      blend: 'lighter'  // Enable blending mode
    }]
  }
};

Mobile-Specific Optimization

Gesture interaction adaptation:

chart.on('touchstart', {
  throttle: 300,
  throttleType: 'fixRate'
}, e => {
  // Handle touch events
});

Responsive degradation strategy:

function getOptimizedOption() {
  const isMobile = window.innerWidth < 768;
  return {
    animation: !isMobile,
    tooltip: {
      show: isMobile ? false : true,
      trigger: isMobile ? 'none' : 'axis'
    },
    series: [{
      type: 'line',
      symbolSize: isMobile ? 2 : 4
    }]
  };
}

Server-Side Rendering Solutions

Pre-generating static content:

const echarts = require('echarts');
const { createCanvas } = require('canvas');

const canvas = createCanvas(800, 600);
const chart = echarts.init(canvas);
chart.setOption(/* ... */);

// Output as Base64
const imgData = canvas.toDataURL('image/png');
res.send(`<img src="${imgData}">`);

Incremental rendering protocol:

// Server-side
app.get('/chart-update', (req, res) => {
  const lastVersion = req.query.v;
  const deltaData = getDeltaData(lastVersion);
  res.json({
    version: currentVersion,
    data: deltaData
  });
});

// Client-side
function pollUpdates() {
  fetch(`/chart-update?v=${currentVersion}`)
    .then(res => res.json())
    .then(updateChart);
}

本站部分内容来自互联网,一切版权均归源网站或源作者所有。

如果侵犯了你的权益请来信告知我们删除。邮箱:cc@cccx.cn

Front End Chuan

Front End Chuan, Chen Chuan's Code Teahouse 🍵, specializing in exorcising all kinds of stubborn bugs 💻. Daily serving baldness-warning-level development insights 🛠️, with a bonus of one-liners that'll make you laugh for ten years 🐟. Occasionally drops pixel-perfect romance brewed in a coffee cup ☕.