Best practices to improve performance?

We're using FNC maps. 4.1.0.0
While google maps has it's innate performance issues, the delphi component seems to really struggle with excessive map markers.

1st: The clusterer component used, should be updated. But, that doesn't give more than a few ms extra performance.
2nd: When adding about a thousand map markers (this seems like a lot, but that's where the clusterer comes in), performance seems to really tank.

The initial "adding" of the markers takes a notable amount of time.
The resulting HTML file is (for obvious reasons) a lot larger (90 KB -> 1.1 MB)
Scrolling and zooming the map seems to consume significant CPU.

We don't so much mind the first issues, but the CPU usage is something we would really like to address.
I've tried hiding markers with visible:=False, while mousedrag is being done, and setting them to visible:=true afterwards, but this seems to have more negative effects than benefits.

What can we do to ensure the CPU usage is drastically reduced for large numbers of markers?

Our tests show no problematic performance issues when adding up to 1000 markers on a map. Both with and without using clusters.
Can you please make sure to place code that interacts with the map inside BeginUpdate/EndUpdate calls?

Example:

var
  I: Integer;
begin
  TMSFNCGoogleMaps1.BeginUpdate;
  TMSFNCGoogleMaps1.Clear;
  TMSFNCGoogleMaps1.Clusters.Add;
  for I := 0 to 1000 do
  begin
    TMSFNCGoogleMaps1.AddMarker(TMSFNCGoogleMaps1.Options.DefaultLatitude + Random(20), TMSFNCGoogleMaps1.Options.DefaultLongitude + Random(20)).Cluster := TMSFNCGoogleMaps1.Clusters[0];
  end;
  TMSFNCGoogleMaps1.EndUpdate;

Hi Bart, yes you're correct.
It turns out it was around 2200 items on the latest test, but that shouldn't make a lot of difference.

We do the beginUpdate/endUpdate as described.
Once that is done, it takes about 3 seconds for the markers to show up on the map. And then another 2 seconds for them to be clustered.

This seems to happen in a thread some time after the endUpdate is called, as it's not being picked up in the debugger right away. Which is a good thing - for performance - but does make debugging a little tricky.

The first part (3 sec):

  • Still looking for this.

The second part (2 sec) seems to happen in:

  • VCL.TMSFNCGoogleMaps: TTMSFNCCustomGoogleMaps.EndUpdate -> .DoUpdateClusters -> .ExecuteJavaScript

I understand it takes a little time to output 2200 strings to a .html file, but 5 seconds seems longer than it should need to?

I shaved off a bit under 100 ms by updating the earlier mentioned cluster js, and a few more by replacing the marker .svg with .png as recommended by google's best practices. But the main chunk in initial loading time still seems to be in the tms code which writes the .html file.

Hi Wilfred,

Can you please compare the performance between your application and the sample code provided in my previous message?
Even with the marker count increased to 2500 it doesn't take longer than 1 second before the clusters are displayed on the map when tested here.

If you are seeing worse performance in your own app, can you please provide a ready to run sample project that demonstrates the issue so I can further investigate this?

Thanks,
Using the "TMS FNC Maps\Demos\VCL\Google Maps Features" and adding the above code under a new button does result in a pretty rapid clustering. I'll have a look at what the differences are.

Unrelated to the above, issue (still looking), but related to the performance issues.

When starting:

  • TMS FNC Maps\Demos\VCL\Google Maps Features\

The demo project outputs two identical .html files in:

  • c:\Users[username]\AppData\Local\Temp
    (Our application does this as well, and in our case that's 2 files with each 2000 map markers, contributing to the slow startup time.)

I've hooked in to the event using the following code in FormCreate, to make it easier to debug:

  • TMSFNCGoogleMaps1.OnCustomizeLocalAccessFileName := MapMainCustomizeLocalAccessFileName;

The two files are created as follows:

  • The first is created after FormCreate -> SetLocalFileAccess -> InitializeHTML -> GetLocalAccessFileName -> DoCustomizeLocalAccessFileName
  • The second is created after a processMessages event which hits the EdgeWebView -> [code] -> TTMSFNCCustomMaps.Initialized -> InitializeMap -> InitializeHTML -> The rest of the path is the same as above.

This seems like something that might be optimized / unintentional?

The files only appear to be used at startup, adding the 2000 markers does not cause a new .html file to be written to disk, though I would have expected it to? Is the view handled in memory?

Hi,

The local file access when true, creates a file once during startup with the initial HTML inside, based on settings in designtime. Then afterwards, runtime changes are dynamically created in memory. The local file access is required to as the name implies give access to local files such as icons, but you can also add icons in base64, so it's not required to have it enabled.