Skip to content

Conversation

@lucaswoj
Copy link
Contributor

@lucaswoj lucaswoj commented Nov 18, 2025

This PR brings some of the performance improvements we've added to GeoJSONSource#updateData in #4364 to the GeoJSONSource#setData method.

Specifically, it this PR removes the logic that passes the full serialized GeoJSON data from the worker thread to the main thread. In my benchmark, adding 100k points to a map, this makes setData about 22% faster vs main.

This changes some undocumented behavior of Map#getStyle. Prior to this PR, if you add a GeoJSON source with a data URL, wait for it to load, and then call Map#getStyle, you'd get the actual loaded GeoJSON features back, not the original source spec with the URL. Similarly, if you called setData with some improperly wound GeoJSON geometries, and then called Map#getStyle, you'd get the rewound geometries back. Even though this is undocumented behavior, I suspect at least a couple folks are relying on it. They will need to use the GeoJSONSource#getData method instead.

Launch Checklist

  • Confirm your changes do not include backports from Mapbox projects (unless with compliant license) - if you are not sure about this, please ask!
  • Briefly describe the changes in this PR.
  • Link to related issues.
  • Include before/after visuals or gifs if this PR includes visual changes.
  • Write tests for all new functionality.
  • Document any changes to public APIs.
  • Post benchmark scores.
  • Add an entry to CHANGELOG.md under the ## main section.


const options: LoadGeoJSONParameters = extend({type: this.type}, this.workerOptions);
if (data) {
if (data !== undefined) {
Copy link
Contributor Author

@lucaswoj lucaswoj Nov 21, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We need to explicitly check against undefined because null is a valid GeoJSON value.

for (const id of prevIds.values()) {
if (typeof id !== 'number' && this.promoteId == null) {
warnOnce(`GeoJSONSource "${this.id}": updateData is slower when using string GeoJSON feature IDs (e.g. "${id}"). Consider using promoteId or numeric IDs for better performance.`);
warnOnce(`GeoJSONSource "${this.id}": updateData is slower when using string GeoJSON feature IDs. Consider using promoteId or numeric IDs for better performance.`);
Copy link
Contributor Author

@lucaswoj lucaswoj Nov 21, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Providing an example ID in this warning message can cause log spew. warnOnce needs the warning message to be exactly the same across calls but the example ID could change in every call.

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Agreed.

// {} can be updated
if (data.type == null) {
return true;
}
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We have a couple dozen unit tests that pass {} as a GeoJSON data value. This isn't technically valid per the spec but I chose to allow the value rather than change all the tests.

@lucaswoj lucaswoj marked this pull request as ready for review November 21, 2025 17:23
@codecov
Copy link

codecov bot commented Nov 21, 2025

Codecov Report

✅ All modified and coverable lines are covered by tests.
✅ Project coverage is 92.23%. Comparing base (53cb799) to head (7c705c7).
⚠️ Report is 21 commits behind head on main.

Additional details and impacted files
@@            Coverage Diff             @@
##             main    #6738      +/-   ##
==========================================
+ Coverage   92.21%   92.23%   +0.01%     
==========================================
  Files         285      285              
  Lines       23742    23735       -7     
  Branches     5050     5043       -7     
==========================================
- Hits        21894    21891       -3     
+ Misses       1848     1844       -4     

☔ View full report in Codecov by Sentry.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • 📦 JS Bundle Analysis: Save yourself from yourself by tracking and limiting bundle sizes in JS merges.

@wayofthefuture
Copy link
Collaborator

wayofthefuture commented Nov 21, 2025

Looks good to me!

@HarelM HarelM merged commit a305826 into maplibre:main Nov 22, 2025
26 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants