Jump to content

Realtime Map - Performance Improvements


Recommended Posts

Suggestion Name

Realtime Map - Performance Improvements

 

Suggestion Description

As a frequent user of the map, I have noticed the sluggish performance of the map. I made some adjustments to the map that improve the FPS by 2 to 3 times (see images below). The code used for this can be found in the spoiler below and can easily replace the old code.

 

Technical Details

Tile has been replaced, because the memory consumption of this function was really high for two reasons:

  • Methods of Tile didn't use the prototype property
  • Each call to Tile.draw created a new Image object

 

The new Tile caches the Image object after the first call to Tile.draw and reduces the stress on the garbage collector, leading to more FPS.

 

The second improvement is rather small. The start() function has been replaced and uses requestAnimationFrame instead of setInterval for the following improvements:

  • requestAnimationFrame intelligently determines the appropriate framerate based on the screen’s refresh rate and the device’s capabilities
  • requestAnimationFrame does not fire when the user isn't viewing the map (e.g. on another tab) and reduces background resource usage
  • requestAnimationFrame increases animation smoothness

 

Images

I am using a 75Hz monitor for this test and tested it in Google Chrome on Windows 10 as well as my Samsung phone (images not included).

 

Without modification: https://i.imgur.com/0FUxtjh.png

With modification: https://i.imgur.com/MHlJ2Vj.png

 

 

 

Code

Spoiler

function Tile(x, y, path, zoomLevel) {
  this.x = x;
  this.y = y;
  this.path = path;
  this.zoomLevel = zoomLevel;
  this.tileZoomLevel = tileSize * Math.pow(3, zoomLevel - 1);
  this.image = undefined;
}

Tile.prototype.draw = function(ctx) {
  var screenCoords = coordToScreen(this.x, this.y, 0, 0, false);
  var zoomLevelNormalized = Math.round(zoom * this.tileZoomLevel);

  if (currentZoomLevel === this.zoomLevel && screenCoords.x + zoomLevelNormalized > 0 && screenCoords.x - zoomLevelNormalized < screenWidth && screenCoords.y + zoomLevelNormalized > 0 && screenCoords.y - zoomLevelNormalized < screenHeight) {
    if (!this.image) {
      this.image = new Image();
      this.image.src = this.path;
    }

    var coords = coordToScreen(this.x, this.y, this.tileZoomLevel, this.tileZoomLevel, false);
    ctx.drawImage(this.image, Math.round(coords.x), Math.round(coords.y), zoomLevelNormalized, zoomLevelNormalized);
  }
}

var initialized = false;
function start() {
  if (!initialized) {
    initialized = true;
    init();
  }

  run();
  requestAnimationFrame(start);
}

 

 

  • Upvote 1
  • Woah! 3
Link to comment
Share on other sites

  • 2 weeks later...
  • 3 years later...
Guest
This topic is now closed to further replies.
×
×
  • Create New...

Important Information

We have placed cookies on your device to help make this website better. You can adjust your cookie settings, otherwise we'll assume you're okay to continue.