Optimizing Javascript & PHP performance of database-connected Google Maps
application?
I have a simple Google Maps application which displays a set of recurring,
standard polygons of equal size and shape within the confines of the map
viewport - it refreshes every time the user changes the bounds of the map
itself (I have a eventListener attached to idle for this).
All this is achieved by querying my database via a Javascript
XMLhttprequest to my page genxml.php, where PHP creates a new XML
document, queries the database for polygons within the set boundaries,
loops through them creating a new XML document with the layout:
<points>
<point id="number" lat="coordinate" long="coordinate" />
...
<point id="number" lat="coordinate" long="coordinate" />
</points>
This is done by a PHP while statement which iterates for every row
returned from my query:
while ($row = $stmt->fetch(PDO::FETCH_ASSOC)){
$node = $dom->createElement("point");
$newnode = $parnode->appendChild($node);
$newnode->setAttribute("id", $row['square_id']);
$newnode->setAttribute("lat", $row['ref_coord_lat']);
$newnode->setAttribute("lng", $row['ref_coord_long']);
}
It then saves the document (echo $dom->saveXML()) and runs a javascript
callback function when the XML document is returned successfully. This
anonymous callback function extracts the polygons via by creating an array
variable XMLpolygons which equals
data.responseXML.documentElement.getElementsByTagName("point") where data
is the parameter that is part of my callback.
To assign each XML point to a polygon, my Javascript code then runs along
the length of the XMLpolygons array via a for loop and sets the polygon's
ID and coordinates, and pushes it to an array of called PolyList which
holds all the others.
What is mentioned in the above 2 paragraphs is completed by this section
of code:
var xml = data.responseXML;
var XMLpolygons = xml.documentElement.getElementsByTagName("point");
for (var i = 0; i < XMLpolygons.length; i++) {
var id = XMLpolygons[i].getAttribute("id");
var topLeftLat = parseFloat(XMLpolygons[i].getAttribute("lat"));
var topLeftLong = parseFloat(XMLpolygons[i].getAttribute("lng"));
var polyCoords = [
new google.maps.LatLng(topLeftLat, topLeftLong),
new google.maps.LatLng(topLeftLat, topLeftLong + (0.5 / 60)),
new google.maps.LatLng(topLeftLat + (0.5 / 60), topLeftLong + (0.5 /
60)),
new google.maps.LatLng(topLeftLat + (0.5 / 60), topLeftLong),
];
var html = "<b>" + id + "</b> <br/>";
var polygon = new google.maps.Polygon({
map: map,
paths: polyCoords,
fillColor: 'rgba(0,0,0,0)',
strokeWeight: 2,
strokeOpacity: 0.2
});
PolyList.push(polygon);
// I will need to do this, but it currently isn't required.
// bindInfoWindow(polygon, map, infoWindow, html);
}
When the boundaries of the map are then changed, PolyList is emptied, and
the process repeats. The end user experience is quick, but not as quick as
I'd like - it takes a good second or two for the map to update at the
highest zoom level I allow it to perform this operation (zoomLevel = 7),
and it gets quicker as the user zooms in, becoming sufficiently fast at
zoomLevel 9. It's worth noting that at zoom-level 9, ~200 polygons are
being processed, at level 8, it becomes ~800, and at level 7 it's ~3300.
Not only would it be unwieldy to display polygons at level 6, it isn't
required because they're too small at that point to be useful.
Possible performance bottlenecks
I see three main areas where the system could be slowed down:
1) My database query; which fetches polygons within the viewport.
2) My PHP while loop; which assigns each returned polygon to a XML node.
3) My Javascript for loop; which takes each XML polygon and converts it to
a Javascript variable before creating a google.maps.Polygon() with it.
It definitely isn't #1. My queries are returned in 0.6-0.7ms from my
database (see my previous question here where I asked for methods of
increasing MySQL performance, before documenting my own answer in the body
of the question). Note, this performance from my database is for any size
query with any constraints - all are returned in under 1ms. But because my
map performance increases with zoom level, this makes me think it's
definitely #2 or #3 where my code is performing suboptimally - if it was
the db, the map would be slow at all zoom levels.
So, what I'm really looking for is ways to improve and optimize my
Javascript & PHP loops where additional processing takes place. Any ideas?
No comments:
Post a Comment