DRAFT: (FEAT) implement progressive tile loading to reduce white-screen time Open#4253
Draft
grab-liyanjin wants to merge 2 commits into
Draft
DRAFT: (FEAT) implement progressive tile loading to reduce white-screen time Open#4253grab-liyanjin wants to merge 2 commits into
grab-liyanjin wants to merge 2 commits into
Conversation
… time Emit geometry (fill/line/circle) buckets immediately after parse() completes, before glyph/image dependencies for symbol layers are resolved. This lets tiles appear on screen with road/polygon/water data right away; text and icons follow in a second full onLayout call once all deps are ready. - GeometryTileWorker: add comingFromParse flag; finalizeLayout() emits a partial LayoutResult (isPartialResult=true) on first load when deps are still pending and renderData is non-empty (geometry-only buckets available) - GeometryTile: onLayout() accepts isPartialResult — suppresses pending=false and EndParse event for partial results so the tile stays pending until symbols arrive Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
for more information, see https://pre-commit.ci
Contributor
Bloaty Results 🐋Compared to main Full report: https://maplibre-native.s3.eu-central-1.amazonaws.com/bloaty-results/pr-4253-compared-to-main.txtCompared to d387090 (legacy) Full report: https://maplibre-native.s3.eu-central-1.amazonaws.com/bloaty-results/pr-4253-compared-to-legacy.txt |
Contributor
Bloaty Results (iOS) 🐋Compared to main Full report: https://maplibre-native.s3.eu-central-1.amazonaws.com/bloaty-results-ios/pr-4253-compared-to-main.txt |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
This PR implements two-phase (progressive) tile loading to reduce white-screen
time when panning or zooming to unloaded areas.
Previously, a tile remained invisible (
renderable=false) until all layoutwork completed — including network fetches for glyphs/images required by symbol
layers (text labels, icons). On slow networks or cold cache this could leave
large blank areas for several seconds, even though fill/line/circle geometry was
already parsed and ready to draw.
After this change, geometry buckets are emitted to the render thread
immediately after
parse()completes. Symbol buckets follow in a secondonLayoutcall once all glyph/image dependencies are resolved.Demo
normal_loading.mp4
progressive_loading.mp4
How it works
GeometryTileWorkercomingFromParseboolean flag (reset after eachfinalizeLayout()call).
parse()setscomingFromParse = truebefore callingfinalizeLayout().finalizeLayout()gains an early-exit path: when dependencies are stillpending and
firstLoad && comingFromParse && !renderData.empty(), itcopies the already-populated
renderData(geometry-only buckets, cheapshared_ptrcopy) and invokesGeometryTile::onLayoutwithisPartialResult=true. This partial result is skipped whenrenderDataisempty (symbol-only tilesets) to avoid marking a tile as renderable with
nothing to show.
GeometryTileonLayout()gains abool isPartialResult = falseparameter.loaded = trueandrenderable = trueso the tileappears on screen immediately, but does not clear
pendingor fire theEndParseevent — the tile stays pending until the full symbol result arrives.isPartialResult=false) replaceslayoutResultnormally andclears
pendingas before.Behaviour unchanged for
firstLoadis false, progressivepath is skipped entirely.
hasPendingDependencies()returnsfalse, existing code path taken unchanged.
renderData.empty()guard prevents an empty partialresult from being sent.
pendingis onlycleared on the full result.
Testing
Verified on Android (arm64) with a style containing road labels and POI icons:
geometry (roads, water, buildings) appears within the first render frame after
tile data arrives; text and icons fade in once glyphs are downloaded.