I have created a jump'n'run browser-game based on SVG. The »World« grew large (~80px * ~20000px, before scaled to viewport height) and rendering went slow. In consequence I included a range searching algorithm to exclude elements from the render tree, if they are out of the visible area. To get all elements inside the viewport, I am using a range query on a AVL-Tree.
Basically the approach was very effective and increased the performance up to 40%, unfortunately it also results in flickering of the graphic if the player is in motion.
The initialization looks like this:
//for each element of type: path, rect, polygon, line, circle, polyline,use,text or tspan
var box = bbox.call(this, element, mtr),
data = {
style: element.style,
x1: box[0].x,
x2: box[1].x,
visible: false
}
this.tree.insert(box[0].x, data);
this.tree.insert(box[1].x, data);
element.style.display = 'none';
whereby bbox()
creates gets the bounding box in global coordinates.
Each time at rendering
the following is done:
var x1 = this.viewBox.x - 1,
x2 = this.viewBox.x + this.viewBox.width + 1,
result = this.tree.query(x1, x2),
visible = this.visible,
i = 0,
n = result.length,
data;
for (; i < n; i++) {
data = result[i];
if (!data.visible) {
data.style.display = 'block'
data.visible = true;
}
}
for (i = 0, n = visible.length; i < n; i++) {
data = visible[i];
if (data.x1 > x2 || data.x2 < x1) {
data.style.display = 'none';
data.visible = false;
}
}
this.visible = result;
As mentioned above, the framerate increased between 20% and 40% on each platform, but flickering and kind of sloppy rendering began.
What could I do to gain a more fluent rendering?