title: How do I display 400,000 or more points in Openlayers 3 using less than 200MB of memory?
body: <p>I created a standalone map to test this out for myself. I took a heap snapshot, using Chrome Developer Tools, of the page upon loading it and found it was using 882MB of memory. I'm looking to plot about an hours worth of lightning data and I would like for the user to be able to interact with it so Openlayers makes sense here. However its taking up a ton of memory and need a solution that is much more memory efficient.</p>
  
  <p>Below is the code I used to do this:</p>
  
  <pre><code>&lt;!doctype html&gt;
  &lt;html lang="en"&gt;
    &lt;head&gt;
      &lt;meta charset="utf-8"&gt;
      &lt;meta http-equiv="X-UA-Compatible" content="chrome=1"&gt;
      &lt;meta name="viewport" content="initial-scale=1.0, user-scalable=no, width=device-width"&gt;
      &lt;script src="https://cdnjs.cloudflare.com/ajax/libs/ol3/3.6.0/ol.js"&gt;&lt;/script&gt;
      &lt;link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/ol3/3.6.0/ol.css"&gt;
    &lt;/head&gt;
    &lt;body&gt;
  
      &lt;div class="container"&gt;
  
        &lt;div class="row"&gt;
          &lt;div class="md-12"&gt;
            &lt;div id="map" class="map"&gt;&lt;/div&gt;
          &lt;/div&gt;
        &lt;/div&gt;
        &lt;div id="span12"&gt; 
        &lt;/div&gt;
      &lt;/div&gt;
  
  
      &lt;script&gt;
  var iconInfo = [{
      points: 4,
      radius: 3,
      radius2: 0,
      angle: 0
  }, {
      points: 4,
      radius: 3,
      radius2: 0,
      angle: 0
  }, {
      points: 4,
      radius: 3,
      radius2: 0,
      angle: 0
  }, {
      points: 4,
      radius: 3,
      radius2: 0,
      angle: 0
  }];
  
  var i;
  
  var iconCount = iconInfo.length;
  var icons = new Array(iconCount);
  for (i = 0; i &lt; iconCount; ++i) {
    var info = iconInfo[i];
    icons[i] = new ol.style.RegularShape({
      points: info.points,
      radius: info.radius,
      radius2: info.radius2,
      angle: info.angle,
      fill: new ol.style.Fill({color: 'rgba(0, 0, 0, 0.9)'}),
      stroke: new ol.style.Stroke({width: 2, color: 'rgba(0, 0, 0, 0.9)'}),
    });
  }
  
  var featureCount = 350000;
  var features = new Array(featureCount);
  var feature, geometry;
  var e = 25000000;
  for (i = 0; i &lt; featureCount; ++i) {
    geometry = new ol.geom.Point(
        [2 * e * Math.random() - e, 2 * e * Math.random() - e]);
    feature = new ol.Feature(geometry);
    feature.setStyle(
        new ol.style.Style({
          image: icons[i % (iconCount - 1)]
        })
    );
    features[i] = feature;
  }
  
  var vectorSource = new ol.source.Vector({
    features: features
  });
  var vector = new ol.layer.Vector({
    source: vectorSource
  });
  
  
  var map = new ol.Map({
    layers: [vector],
    target: document.getElementById('map'),
    view: new ol.View({
      center: [0, 0],
      zoom: 5
    })
  });
  
  var overlayFeatures = [];
  for (i = 0; i &lt; featureCount; i += 30) {
    var clone = features[i].clone();
    clone.setStyle(null);
    overlayFeatures.push(clone);
  }
  
  var featureOverlay = new ol.layer.Vector({
    map: map,
    source: new ol.source.Vector({
      features: overlayFeatures
    }),
    style: new ol.style.Style({
      image: icons[iconCount - 1]
    })
  });
  
  map.on('click', function(evt) {
    var info = document.getElementById('info');
    info.innerHTML =
        'Hold on a second, while I catch those butterflies for you ...';
  
    window.setTimeout(function() {
      var features = [];
      map.forEachFeatureAtPixel(evt.pixel, function(feature, layer) {
        features.push(features);
        return false;
      });
  
      if (features.length === 1) {
        info.innerHTML = 'Got one butterfly';
      } else if (features.length &gt; 1) {
        info.innerHTML = 'Got ' + features.length + ' butterflies';
      } else {
        info.innerHTML = 'Couldn\'t catch a single butterfly';
      }
    }, 1);
  });
  
  map.on('pointermove', function(evt) {
    if (evt.dragging) {
      return;
    }
    var pixel = map.getEventPixel(evt.originalEvent);
    var hit = map.hasFeatureAtPixel(pixel);
    map.getTarget().style.cursor = hit ? 'pointer' : '';
  });
  
  &lt;/script&gt;
  &lt;/body&gt;
  &lt;/html&gt;
  </code></pre>
  
  <p>Any suggestions on how I could achieve better memory efficiency?</p>