Updating V3 Polygon Paths - Leaking Memory

3,147 views
Skip to first unread message

John Mick

unread,
Dec 1, 2010, 5:42:17 PM12/1/10
to google-map...@googlegroups.com
I am the developer of an existing Maps V2 (and GEE) application that displays Polygonal data in real-time, updating every 25 seconds.  V2's GPolygon Objects would leak browser memory (that would never be retained) so I ultimately was forced to write my own custom proprietary library to meet the needs of updating SVG Polygons every 25 seconds without dealing with browser memory leaks.  

Now that V3 has been around for awhile I am starting the process of migrating my application over to V3 and was hoping that the new Polygon objects would have alleviated this problem : I've noticed that they have changed quite a bit.

I devised three different methods to update an existing Polygon object when new data arrives:
  • Method 1 - Using the "setPaths" function
    • poly.setPaths(newMultiDimensionalArrayOfLatLngs)
  • Method 2 - Setting the Polygon's Map to Null, then assigning the old Polygon object to a new Polygon, then finally adding it to the map
    • poly.setMap(null)
    • poly = new google.maps.Polygon({options})
    • poly.setMap(map)
    • This method causes the Polygon Object to Visibly "Flicker" as it is removed and recreated on the map and is not really desirable 
  • Method 3 - Setting the "paths" option to a new multi-dimensional array of LatLngs
    • poly.setOptions({paths:newMultiDimensionalArrayOfLatLngs})
I started testing these three methods yesterday on a Windows 7 64 bit machine with IE8, Chrome 7.0.517.44, and Firefox 3.6.12.  Unfortunately in every browser it appears that a memory leak is occurring.  

Both Firefox and Chrome will allow their memory consumption to rise for a period of time then, I'm presuming, the JS Garbage Collector comes around and cleans up lowering the memory usage in the browser process back down to a level close to where it was initially, however it isn't the same - so after a period of a few hours there is a very apparent leak. 

Internet Explorer 8's leak is much easier to identify - as the memory usage will constantly increase into the hundreds of MBs until the browser is closed.

I have made my test applications available to the public here:
The source code is easily readable as well.  I'm posting my findings here because I'm hoping that perhaps somebody has some experience with this, specifically with V3 Polygons, and could point out something simple that I am doing incorrectly to cause the leak.  Otherwise I am going to revert back to using the library I already have - but I was really hoping to migrate over to the Google API for Polygons.

Chad Killingsworth

unread,
Dec 2, 2010, 10:17:45 AM12/2/10
to Google Maps JavaScript API v3
I would highly suggest that instead of removing and re-adding the
poly, or manually setting the path, you instead make the initial path
array an MVCArray. Then as you change the points in the array, the
polygon will automatically update.

See http://code.google.com/apis/maps/documentation/javascript/reference.html#MVCArray

Chad Killingsworth

On Dec 1, 4:42 pm, John Mick <reco...@gmail.com> wrote:
> I am the developer of an existing Maps V2 (and GEE) application that
> displays Polygonal data in real-time, updating every 25 seconds. V2's
> GPolygon Objects would leak browser memory (that would never be
> retained) so I ultimately was forced to write my own custom proprietary
> library to meet the needs of updating SVG Polygons every 25 seconds
> without dealing with browser memory leaks.
>
> Now that V3 has been around for awhile I am starting the process of
> migrating my application over to V3 and was hoping that the new Polygon
> objects would have alleviated this problem : I've noticed that they
> have changed quite a bit.
>
> I devised three different methods to update an existing Polygon object
> when new data arrives:
>
> - Method 1 - Using the "setPaths" function
> - poly.setPaths(newMultiDimensionalArrayOfLatLngs)
> - Method 2 - Setting the Polygon's Map to Null, then assigning the old
> Polygon object to a new Polygon, then finally adding it to the map
> - poly.setMap(null)
> - poly = new google.maps.Polygon({options})
> - poly.setMap(map)
> - This method causes the Polygon Object to Visibly "Flicker" as it is
> removed and recreated on the map and is not really desirable
> - Method 3 - Setting the "paths" option to a new multi-dimensional
> array of LatLngs
> - poly.setOptions({paths:newMultiDimensionalArrayOfLatLngs})
> I started testing these three methods yesterday on a Windows 7 64 bit
> machine with IE8, Chrome 7.0.517.44, and Firefox 3.6.12. Unfortunately
> in every browser it appears that a memory leak is occurring.
>
> Both Firefox and Chrome will allow their memory consumption to rise for
> a period of time then, I'm presuming, the JS Garbage Collector comes
> around and cleans up lowering the memory usage in the browser process
> back down to a level close to where it was initially, however it isn't
> the same - so after a period of a few hours there is a very apparent
> leak.
>
> Internet Explorer 8's leak is much easier to identify - as the memory
> usage will constantly increase into the hundreds of MBs until the
> browser is closed.
>
> I have made my test applications available to the public here:
>
> - Method 1
>
> - Method 2
>
> - Method 3

bratliff

unread,
Dec 2, 2010, 10:54:32 AM12/2/10
to Google Maps JavaScript API v3


On Dec 2, 3:17 pm, Chad Killingsworth
<chadkillingswo...@missouristate.edu> wrote:
> I would highly suggest that instead of removing and re-adding the
> poly, or manually setting the path, you instead make the initial path
> array an MVCArray. Then as you change the points in the array, the
> polygon will automatically update.
>
> Seehttp://code.google.com/apis/maps/documentation/javascript/reference.h...
>
> Chad Killingsworth

Or try using a standard JavaScript array instead of a MVC array. I
suspect MVC arrays have a whole bunch of backward / forward links to
facilitate expansion / contraction / navigation of the array. It may
contain many small memory fragments. Both conditions will frustrate
the garbage collector. I single linear chunk of memory is much less
likely to cause leaks. Releasing the entire array in one shot will
also help the garbage collector.

I am unable to see your "Method 1", "Method 2", "Method 3" links.
Could you repost ?

bratliff

unread,
Dec 2, 2010, 11:16:28 AM12/2/10
to Google Maps JavaScript API v3
On Dec 2, 3:54 pm, bratliff <bratl...@umich.edu> wrote:

> Or try using a standard JavaScript array instead of a MVC array. I
> suspect MVC arrays have a whole bunch of backward / forward links to
> facilitate expansion / contraction / navigation of the array. It may
> contain many small memory fragments. Both conditions will frustrate
> the garbage collector. I single linear chunk of memory is much less
> likely to cause leaks. Releasing the entire array in one shot will
> also help the garbage collector.
>
> I am unable to see your "Method 1", "Method 2", "Method 3" links.
> Could you repost ?

Also, the requirement of individual "new google.maps.LatLng()"
constructors for every point of the poly adds extra junk for the
garbage collector to reclaim.

John Mick

unread,
Dec 2, 2010, 11:32:20 AM12/2/10
to google-map...@googlegroups.com
I'm not sure why you aren't able to resolve those "Method 1, 2 3" links - but I can include the JavaScript source code from the example I put together here:

(function(){
	function generateRandomPoints()
	{
		var points = [];
		for (var i=0;i<10;i++)
		{
			var somePoints = [];
			for (var k=0;k<50;k++)
			{
				var lat = Math.floor(Math.random()*90);
				var lng = Math.floor(Math.random()*180);
				somePoints.push(new google.maps.LatLng(lat, lng));
			}
			points[i] = somePoints;
		}
		return points;
	}


	$(document).ready(function(){
		var map = new google.maps.Map(document.getElementById("MAP"), {
				zoom:3,
				center: new google.maps.LatLng(50, -90),
				mapTypeId: google.maps.MapTypeId.TERRAIN,
				backgroundColor: "#99B3CC",
				keyboardShortcuts:false
			});

		var poly = new google.maps.Polygon({
			paths: generateRandomPoints(),
			strokeColor: "#000000",
			strokeOpacity: 0.0,
			strokeWeight: 1,
			fillColor: "#00FF00",
			fillOpacity: 1 
		});

		poly.setMap(map);

		window.setInterval(function(){
			/* Method 1 - Use API Provided setPaths */
				poly.setPaths(generateRandomPoints());

			/* Method 2 - Assign Polygon Object to A New One */
			/*
				poly.setMap(null);
				poly = new google.maps.Polygon({
					paths: generateRandomPoints(),
					strokeColor: "#000000",
					strokeOpacity: 0.0,
					strokeWeight: 1,
					fillColor: "#00FF00",
					fillOpacity: 1 
				});
				poly.setMap(map);
			*/
			
			/* Method 3 - Assign New Path Using API Provided Set Options */
			/*
				poly.setOptions({
					paths:generateRandomPoints()
				});
			*/

		}, 3000);

	});
})();

John Mick

unread,
Dec 2, 2010, 11:43:13 AM12/2/10
to google-map...@googlegroups.com
I have thought that that requiring the creation of new LatLng objects could cause an issue - however I have implemented my own solution (not using GPolygons) in V2 that constantly creates new LatLng objects and does not suffer from leaks.  

I'm sort of restarting my approach from scratch with V3 - looking at what the API provides and hoping that there is a simple way to do this.  

John Mick

unread,
Dec 2, 2010, 11:44:03 AM12/2/10
to google-map...@googlegroups.com
Ah I missed the MVCObject/MVCArray section in the API - I'm going to work on putting together a sample application today to test this approach and I'll be back with my findings soon.  Thank you for this tip.  :)

Andrew Leach

unread,
Dec 2, 2010, 11:59:14 AM12/2/10
to google-map...@googlegroups.com
On 2 December 2010 16:32, John Mick <rec...@gmail.com> wrote:
> I'm not sure why you aren't able to resolve those "Method 1, 2 3" links -

It's because not everyone uses HTML email. Including Google Groups:
the web interface at
http://groups.google.com/group/google-maps-js-api-v3/browse_thread/thread/f11e3f7fa2112624
doesn't cope.

Method 1: http://www.johnmick.net/maps/v3polyupdate_method1/
Method 2: http://www.johnmick.net/maps/v3polyupdate_method2
Method 3: http://www.johnmick.net/maps/v3polyupdate_method3

bratliff

unread,
Dec 2, 2010, 12:05:33 PM12/2/10
to Google Maps JavaScript API v3
The "setPath" / "setPaths" methods also accept standard JavaScript
arrays. Unless you are planning to do interactive editing of your
polys, I can see no reason to use MVC arrays. It is just extra
overhead to frustrate the garbage collector. A total rebuild of your
polys is less likely to cause leaks.

I might have an alternative to using API polys:

http://www.polylib.us

but I cannot link to your application to test it first. I am looking
for a clickable link, not raw code.

Chad Killingsworth

unread,
Dec 2, 2010, 12:08:09 PM12/2/10
to Google Maps JavaScript API v3
The clickable links from the new forums don't translate over to the
group interface. Here they are:

http://www.johnmick.net/maps/v3polyupdate_method1/
http://www.johnmick.net/maps/v3polyupdate_method2/
http://www.johnmick.net/maps/v3polyupdate_method3/

Chad Killingsworth

John Mick

unread,
Dec 2, 2010, 3:16:37 PM12/2/10
to Google Maps JavaScript API v3
I'm not sure if using MVCArrays are going to solve this issue.

Consider the nature of my program will have an entirely new set of
LatLng points every 25 seconds or so. None of the points in the multi-
dimensional MVCArray will be reused. I do not see any way to remove
all of the values inside the existing MVCArrray object and recreate
them without throwing a ton of redraw events - which essentially hangs
the browser in one shot.

I'm not sure if I'm missing it, but I haven't found much information
on the behavior of this MVCObjects either - I'm not sure that this is
the type of solution I am looking for.

On Dec 2, 12:08 pm, Chad Killingsworth
<chadkillingswo...@missouristate.edu> wrote:
> The clickable links from the new forums don't translate over to the
> group interface. Here they are:
>
> http://www.johnmick.net/maps/v3polyupdate_method1/http://www.johnmick.net/maps/v3polyupdate_method2/http://www.johnmick.net/maps/v3polyupdate_method3/

bratliff

unread,
Dec 2, 2010, 4:40:52 PM12/2/10
to Google Maps JavaScript API v3
On Dec 2, 8:16 pm, John Mick <reco...@gmail.com> wrote:
> I'm not sure if using MVCArrays are going to solve this issue.
>
> Consider the nature of my program will have an entirely new set of
> LatLng points every 25 seconds or so. None of the points in the multi-
> dimensional MVCArray will be reused. I do not see any way to remove
> all of the values inside the existing MVCArrray object and recreate
> them without throwing a ton of redraw events - which essentially hangs
> the browser in one shot.
>
> I'm not sure if I'm missing it, but I haven't found much information
> on the behavior of this MVCObjects either - I'm not sure that this is
> the type of solution I am looking for.

The only reason I can see to ever use MVC arrays with polys is for
interactive editing. It is inherently inefficient. Otherwise, it is
just extra bloat. Perhaps I am missing another use for it.

I have built a simple test using PolyCluster:

http://www.polylib.us/polycluster/fixleak

I have run it in Firefox for over an hour without crashing. I have
not tested it in other browsers.

John Mick

unread,
Dec 2, 2010, 5:05:02 PM12/2/10
to Google Maps JavaScript API v3
Ah excellent - it looks like PolyCluster is a lot similar to the same
solution I had to write for my V2 app - at a quick glance PolyCluster
looks nice!. I made a SVG/VML library that managed the creation of
the Vector objects on a Custom Overlay and handled pretty much
everything manually. I was hoping to avoid having to do that again -
leveraging V3 - but it is starting to look like I won't be able to
from this point.

I'm heading out of the office now - I'm going to leave your test page
open on the same browsers I mentioned testing earlier, IE 8, Chrome,
and FF, overnight and I'll let you know what I find in the morning.

Thanks for the information!

John Mick

unread,
Dec 3, 2010, 10:33:47 AM12/3/10
to Google Maps JavaScript API v3
Okay so here is what I observed on your PolyCluster test:

At 5:00PM EST on 12/2/2010:
-Firefox was using about 52,000K of Memory (This number would
increase quickly into a low 100,000K then lower itself back down to
around 52,000K)
-Google Chrome was using about 35,000K of Memory (This number was
also increasing and then lowering itself back down to around 35,000K)
-Internet Explorer 8 was using about 33,504K of Memory (Unlike
Firefox and Chrome, this memory usage only fluctuated slighting around
33,504K)

At 10:25AM EST on 12/3/2010:
-Firefox was using about 168,000K of Memory (This number would
increase very quickly to as high as 303,000K then reduce itself back
down to a little higher than 168,000K)
-Google Chrome was using 1,242,840K of Memory and steadily
increasing - I never observed this to go back down
-Internet Explorer 8 was using only 43,000K of Memory and was
still only slightly fluctuating around that number

It looks like the VML implementation in PolyCluster seems to work
better than the SVG implementation - as far as memory usage goes.
Unfortunately by now it has become obvious to me that I won't be able
to use the Google Maps V3 Polygon objects and it seems that I'll have
to continue to use a proprietary SVG/VML solution to keep my real-time
application running.

If I didn't have a requirement of this application remaining open in a
web browser 24 hours a day, 7 days a week - these memory leaking
issues wouldn't be such a huge concern of mine.

bratliff

unread,
Dec 3, 2010, 12:50:52 PM12/3/10
to Google Maps JavaScript API v3
Thanks John,

At least nothing crashed, correct ?

Garbage collection is performed "Just-in-time". Perhaps you caught
Firefox & Chrome close to their high water marks. I will try to
figure out what I might be doing to leave debris.

Internally, the paths are stored as arrays rather than as objects. It
is machine friendly but not human friendly. Perhaps the little
{x:,y:} objects in the application itself are causing fragmentation of
the memory pool. I will experiment.

If you are successful, please let me know what you did. I will be
happy to share some of my code with you too. For what it is worth, I
am using CANVAS for Firefox & Chrome if neither "setClick()" nor
"setCover()" is called to establish event listeners. Otherwise, SVG
is used.

I have made a change to the test case to force the use of SVG where
appropriate. Be sure to clear your cache.

http://www.polylib.us/polycluster/fixleak

Let me know if it helps. Thanks again,

Berry

John Mick

unread,
Dec 3, 2010, 1:07:55 PM12/3/10
to Google Maps JavaScript API v3
No problem Berry - I'm actually pleased to finally touch base with
somebody who has some experience working on a similar issue as I have
so running a test is the least I can do!

Nothing crashed, though IE8 did crash when I closed it - which I
wouldn't really worry about.

It's really a pain to know if the garbage-collector was going to come
around or not in Chrome in FF - but I usually assume that I catch it
when you see a huge peak in memory usage and then it drops down.

I had explored this issue a lot a when I was developing on V2 about 2
years ago - browsers have changed a lot since then - and I strayed
away from using CANVAS because it seemed like Garbage Collectors had a
harder time reclaiming memory used on CANVAS objects after a redraw
compared to SVG objects.

Also, I figured SVG objects would use less memory than CANVAS objects
for especially large Polygons - since they are Vector based as opposed
to bitmap based.

I noted that V3 creates SVG and VML for their Polygon objects - but
they create a series of Viewboxes - one for each 256 x 256 grid on the
map. I guess that makes sense since the map will only draw the
portions of the SVG/VML that it needs (and from a purely design
principle it seems to fit in with the rendering of everything else on
the map ) - but I think it also could be a source of the leaking,
since the implementation has to create events for each square grid
viewpoint and constantly remove and create new ones as the map is
dragged around.

I'll be leaving for the weekend in a few hours - when I leave today
I'll clear out all my cache and make sure I am loading your SVG
version test and let that run over the weekend, so we'll have several
days of usage to look at on Monday.

At this point I've completely given up on using Google's Polygon
objects (at least in the state they are in now) - but I'm happy to
continue our conversation on custom implementations of this.

bratliff

unread,
Dec 3, 2010, 2:01:04 PM12/3/10
to Google Maps JavaScript API v3
On Dec 3, 6:07 pm, John Mick <reco...@gmail.com> wrote:
> No problem Berry - I'm actually pleased to finally touch base with
> somebody who has some experience working on a similar issue as I have
> so running a test is the least I can do!
>
> Nothing crashed, though IE8 did crash when I closed it - which I
> wouldn't really worry about.
>
> It's really a pain to know if the garbage-collector was going to come
> around or not in Chrome in FF - but I usually assume that I catch it
> when you see a huge peak in memory usage and then it drops down.
>
> I had explored this issue a lot a when I was developing on V2 about 2
> years ago - browsers have changed a lot since then - and I strayed
> away from using CANVAS because it seemed like Garbage Collectors had a
> harder time reclaiming memory used on CANVAS objects after a redraw
> compared to SVG objects.

You could be right. I am willing to scrap CANVAS if it is failing to
release its memory. I implemented CANVAS first because I could
combine a lot of polys in the same element. SVG requires "path" sub-
elements. CANVAS does not. CANVAS dragging, panning & zooming is
fast but mouse events are not supported.

You can see the performance differences in several of the
"experimental" demos at:

http://www.polylib.us

Click the "Examine" button to observe changes in the DOM structure.

> Also, I figured SVG objects would use less memory than CANVAS objects
> for especially large Polygons - since they are Vector based as opposed
> to bitmap based.

But it still has to render individual pixels. For CANVAS, the bitmap
is displayed directly.

> I noted that V3 creates SVG and VML for their Polygon objects - but
> they create a series of Viewboxes - one for each 256 x 256 grid on the
> map. I guess that makes sense since the map will only draw the
> portions of the SVG/VML that it needs (and from a purely design
> principle it seems to fit in with the rendering of everything else on
> the map ) - but I think it also could be a source of the leaking,
> since the implementation has to create events for each square grid
> viewpoint and constantly remove and create new ones as the map is
> dragged around.

PolyCluster also builds tiles. It is to improve performance during
dragging, panning & zooming. Individual tiles are built on demand
depending on what is in view. An internal cache reduces the grunt
work.

> I'll be leaving for the weekend in a few hours - when I leave today
> I'll clear out all my cache and make sure I am loading your SVG
> version test and let that run over the weekend, so we'll have several
> days of usage to look at on Monday.
>
> At this point I've completely given up on using Google's Polygon
> objects (at least in the state they are in now) - but I'm happy to
> continue our conversation on custom implementations of this.

I agree. The use of the "new google.maps.LatLng()" constructor for
every point is absurd. The use of MVC arrays also seems to be
overkill except for interactive editing. Rebuilding a poly one point
at a time is very inefficient.

bratliff

unread,
Dec 4, 2010, 1:40:19 PM12/4/10
to Google Maps JavaScript API v3
What you are seeing may be normal. The garbage collector does not
kick in immediately. The point at which it does kick in may be
different among browsers. It may depend on the size of the heap in
your particular configuration.

The reclaimed memory may never be returned to the heap but instead
saved for future allocations. Allocation requests will be filled
initially from reclaimed memory. If not enough is available and/or it
is too fragmented, additional memory must be allocated from the heap.
Once the equilibrium level is reached, memory usage ought to remain
stable.

If memory usage at the end of an hour is not significantly different
from memory usage at the end of a day, I do not believe you are
experiencing memory leaks. Just to be safe, I have made a change to
the test case. Instead of a large array of a lot of small {x:,y:}
objects, it is using a small {x:,y:} object of large arrays. It ought
to reduce fragmentation by keeping everything contiguous. The garbage
collector will have less work to do to coalese little fragments. The
actual workings of individual garbage collectors are only known by the
browser designers. What is important is for an application to be able
to run for a long time without crashing.

bratliff

unread,
Dec 6, 2010, 12:05:02 PM12/6/10
to Google Maps JavaScript API v3
On Dec 3, 6:07 pm, John Mick <reco...@gmail.com> wrote:
> I'll be leaving for the weekend in a few hours - when I leave today
> I'll clear out all my cache and make sure I am loading your SVG
> version test and let that run over the weekend, so we'll have several
> days of usage to look at on Monday.

Did anything crash ?

I added five copies of each poly to the test case. I ran it overnight
on a very old computer. It was still running in the morning with no
change in speed.

I have made several improvements. SVG is the default. I might
discard CANVAS.

Your application is fairly unique. It helped me isolate & fix some
bugs. It is not safe to simply rebuild dirty tiles. It causes the
zIndex order to change. Adjacent tiles with different zIndex orders
are apparent. If a poly changes position, I have to do a full
rebuild. I believe it is working now.

Your custom solution will provide the best performance. Both
PolyCluster & the API build tiles to expedite dragging, panning &
zooming. Since you are doing none, tiles are overkill for you.
PolyCluster builds an internal cache to reduce the effort to rebuild
tiles previously in view. Again, because you quickly discard your
polys, an internal cache is overkill for you.

Thanks again for your help.

John Mick

unread,
Dec 8, 2010, 3:09:17 PM12/8/10
to Google Maps JavaScript API v3
Hey sorry for the delay - I ended up getting pretty sick over the
weekend and haven't been back into the office until today.

I was all setup to run your test on Friday under IE8 - Chrome - and
Firefox, but the interval on calling Cycle was changed from the
previous 3 seconds to 0 ms. Opening the test in those 3 browsers
(each full-screen on one of 3 monitors) had my CPU usage hanging out
at around 60%+. I didn't really want to tax the work machine that
badly over the weekend so I elected to not run the test.

Anyhow I am glad that our discussions helped you find some ways to
improve your library - it is a very impressive.

I definitely recommend using SVG as a default over CANVAS. Though
both SVG and CANVAS require the browser to render the individual
pixels when they are displayed - CANVAS, being bitmap based, has to
store a value for what it is that it is going to draw on every point -
unlike SVG which uses a more mathematical vector approach. In testing
- I found that very very very large CANVAS objects took significantly
more memory to render than SVG objects of the same size.

I also found that increasing the scale of an SVG object doesn't
necessarily increase the memory usage - if we are only talking about
rendering - when the SVG object falls outside of the viewpoint of the
browser itself (if the object was being drawn off-screen).

I am going to continue working on tweaking my own custom solution -
which overlays very large SVG objects over the map once - then alters
those objects directly whenever data changes, instead of deleting and
re-creating new ones. Time to refresh my memory on how to embed those
VML script and namespace tags.

Thanks again for your help as well - it feels significantly better
knowing that somebody else out there has some real experience with
problems like this. (I've felt so alone for awhile! Haha)

bratliff

unread,
Dec 15, 2010, 1:40:09 PM12/15/10
to Google Maps JavaScript API v3
On Dec 8, 8:09 pm, John Mick <reco...@gmail.com> wrote:
> Hey sorry for the delay - I ended up getting pretty sick over the
> weekend and haven't been back into the office until today.
>
> I was all setup to run your test on Friday under IE8 - Chrome - and
> Firefox, but the interval on calling Cycle was changed from the
> previous 3 seconds to 0 ms. Opening the test in those 3 browsers
> (each full-screen on one of 3 monitors) had my CPU usage hanging out
> at around 60%+. I didn't really want to tax the work machine that
> badly over the weekend so I elected to not run the test.

Feel free to make changes to the test case. I was trying to compare
CANVAS, SVG & VML rendering speeds.

> Anyhow I am glad that our discussions helped you find some ways to
> improve your library - it is a very impressive.
>
> I definitely recommend using SVG as a default over CANVAS. Though
> both SVG and CANVAS require the browser to render the individual
> pixels when they are displayed - CANVAS, being bitmap based, has to
> store a value for what it is that it is going to draw on every point -
> unlike SVG which uses a more mathematical vector approach. In testing
> - I found that very very very large CANVAS objects took significantly
> more memory to render than SVG objects of the same size.

For dragging, panning & zooming, CANVAS is much quicker. But CANVAS
does not support mouse events. If a browser supports both, the choice
depends on whether event listeners are specified.

You can see the performance differences at:

http://www.polylib.us

if you choose the experimental "United States" demo. Toggle
"Clickable - true" / "Clickable - false" to switch between SVG &
CANVAS respectively.

> I also found that increasing the scale of an SVG object doesn't
> necessarily increase the memory usage - if we are only talking about
> rendering - when the SVG object falls outside of the viewpoint of the
> browser itself (if the object was being drawn off-screen).
>
> I am going to continue working on tweaking my own custom solution -
> which overlays very large SVG objects over the map once - then alters
> those objects directly whenever data changes, instead of deleting and
> re-creating new ones. Time to refresh my memory on how to embed those
> VML script and namespace tags.

Are you making progress ? I will be happy to help.

John Mick

unread,
Jan 11, 2011, 12:09:10 PM1/11/11
to Google Maps JavaScript API v3
Hello again!

I have been making progress since the last time we discussed the
issue. I believe I have solved my issue by finishing the development
of a JavaScript Abstraction Library for SVG and VML. With the library
I designed I am able to generate either SVG/VML polygons and then
change whatever attributes I'd like on them once they have been
rendered on the map.

My initial tests suggest that this does at the very least
significantly slow the rate at which memory usage increases in
browsers, (and may in some cases stop leaks all-together), because I
am able to take an approach where I create just the elements that I
need then only modify attributes on them. It seems removing,
creating, and then adding elements (with no events or any
complications) still isn't perfect in terms of having memory
reclaimed.

Anyhow I have a test application hosted here:
http://www.nstb.tc.faa.gov/v3jsvgvml/

It generates 10 Polygons on the map, then after 2 seconds begins to
change the points on the polygons randomly every second. The test
also has a slider which allows the user to change the opacity value on
all of the polygons while this is happening. I have tested this to at
least render and work in IE6, IE7, IE8, Safari 5, Opera 11, Chrome 8,
and FF 3. Tonight I intend to begin examining specifically how much
this approach helps with memory usage, by allowing the browsers to run
this page for extended periods of time.

I'd love to share my source code for the library, but unfortunately
I'm not able to. But Bratliff, thank you for your insights, our
conversation definitely helped reinforce my motivation that this was
something that I needed to complete, because the V3 API is not going
to do what I need.

bratliff

unread,
Jan 11, 2011, 1:40:16 PM1/11/11
to Google Maps JavaScript API v3
On Jan 11, 5:09 pm, John Mick <reco...@gmail.com> wrote:
> Hello again!
>
> I have been making progress since the last time we discussed the
> issue. I believe I have solved my issue by finishing the development
> of a JavaScript Abstraction Library for SVG and VML. With the library
> I designed I am able to generate either SVG/VML polygons and then
> change whatever attributes I'd like on them once they have been
> rendered on the map.

CANVAS cannot change attributes in place because it does not have a
"path" or a "shape" sub-element to tweak, just one CANVAS element per
tile. For many polys, it is advantageous because of the light weight
DOM. For just a few polys, it is less flexible. I have figured out a
way to process mouse events which CANVAS does not support directly.
It is quicker than the built-in support for SVG.

I am trying to deal with a different situation - hundreds of polys
with thousands of vertices. I am trying to make dragging / panning /
zooming fast enough to replace tile layer overlays. Google has the
resources to build tiles for many different zoom levels but few
developers do.

> My initial tests suggest that this does at the very least
> significantly slow the rate at which memory usage increases in
> browsers, (and may in some cases stop leaks all-together), because I
> am able to take an approach where I create just the elements that I
> need then only modify attributes on them. It seems removing,
> creating, and then adding elements (with no events or any
> complications) still isn't perfect in terms of having memory
> reclaimed.

I am not sure how you determine memory leakage except by running the
application for a long period of time in different browsers. Garbage
collection works within a range just like the thermostat in your
home. The actual memory usage fluctuates. If it runs for hours
without crashing, it is good enough for me. I do not have a working
Internet Explorer installation to test.

> Anyhow I have a test application hosted here:
> http://www.nstb.tc.faa.gov/v3jsvgvml/
>
> It generates 10 Polygons on the map, then after 2 seconds begins to
> change the points on the polygons randomly every second. The test
> also has a slider which allows the user to change the opacity value on
> all of the polygons while this is happening. I have tested this to at
> least render and work in IE6, IE7, IE8, Safari 5, Opera 11, Chrome 8,
> and FF 3. Tonight I intend to begin examining specifically how much
> this approach helps with memory usage, by allowing the browsers to run
> this page for extended periods of time.
>
> I'd love to share my source code for the library, but unfortunately
> I'm not able to. But Bratliff, thank you for your insights, our
> conversation definitely helped reinforce my motivation that this was
> something that I needed to complete, because the V3 API is not going
> to do what I need.

I protect mine too but mainly to prevent others from mangling my
code. I have recently added "light weight" markers. Unfortunately, I
do not have a demo ready. I discovered a bug I introduced several
months ago which broke internal caching. I fixed it yesterday.
Reply all
Reply to author
Forward
0 new messages