Skip to content

feat(geo-layers): Add getTileLoadingState for granular tile loading info#10372

Open
akre54 wants to merge 4 commits into
visgl:masterfrom
akre54:fix/tile-isloaded-bug
Open

feat(geo-layers): Add getTileLoadingState for granular tile loading info#10372
akre54 wants to merge 4 commits into
visgl:masterfrom
akre54:fix/tile-isloaded-bug

Conversation

@akre54

@akre54 akre54 commented Jun 12, 2026

Copy link
Copy Markdown
Collaborator

Summary

Adds a new utility function getTileLoadingState() that provides detailed information about tile loading progress in TileLayer instances.

Background

After investigating feedback from PR #10360, I discovered that deck.gl's layer.isLoaded behavior is intentional and correct:

  • layer.isLoaded returns true once all tile requests are "settled" (completed OR failed)
  • This prevents waiting forever for tiles that will never load (404s, network errors, etc.)
  • From the source code comments: "Error / empty tiles resolve to content === null. Once Tile2DHeader marks those requests as loaded, do not wait for generated sublayers because there is nothing to render for that tile and tile.layers will remain null."

However, this makes it impossible to distinguish between "loaded successfully" and "loaded with errors" using just the boolean isLoaded property.

Solution

getTileLoadingState() provides granular information:

const state = getTileLoadingState(tileLayer);
// {
//   total: 50,
//   loaded: 47,      // Successfully loaded with content
//   failed: 2,       // 404, network error, etc.
//   pending: 1,      // Still loading
//   percentLoaded: 94,
//   isComplete: false,  // pending > 0
//   isSuccess: false    // failed > 0
// }

Use Cases

1. Video Export

Wait for all tiles to settle (loaded or failed) before capturing frames:

const state = getTileLoadingState(layer);
if (state.isComplete) {
  captureFrame(); // Proceed even if some tiles failed
  if (state.failed > 0) {
    console.warn(`${state.failed} tiles missing in frame`);
  }
}

2. Progress Indicators

Show detailed loading progress with error counts:

<ProgressBar>
  <Progress width={`${state.percentLoaded}%`} />
  <Text>{state.loaded}/{state.total} tiles loaded</Text>
  {state.failed > 0 && <Error>{state.failed} failed</Error>}
</ProgressBar>

3. Error Recovery

Retry failed tiles up to N times:

const state = getTileLoadingState(layer);
if (state.isComplete && !state.isSuccess && retryCount < 3) {
  console.log(`${state.failed} tiles failed, retrying...`);
  layer.setNeedsUpdate(); // Trigger retry
}

Implementation

  • Pure utility function (no changes to core layer behavior)
  • Checks tile.content === null to identify failed tiles
  • Fully typed with TypeScript
  • Comprehensive tests covering all states
  • Complete documentation with examples

Comparison

Before (boolean only):

layer.isLoaded  // true - but did tiles load successfully or fail?

After (granular state):

const state = getTileLoadingState(layer);
state.loaded    // 47 tiles succeeded
state.failed    // 2 tiles failed (404, error)
state.pending   // 1 tile still loading

Related

This addresses the feedback from PR #10360 about improving tile loading observability. After investigation, I concluded that:

  1. The isLoaded behavior is correct by design (prevents deadlocks)
  2. A utility function is better than changing core behavior
  3. This belongs in @deck.gl/geo-layers (as suggested by @chrisgervang)

Testing

  • Unit tests for all state combinations (empty, loading, loaded, failed, mixed)
  • Validates that layer.isLoaded can be true while state.isSuccess is false
  • Tests percentage calculation and edge cases

Checklist

  • Pure utility function (no breaking changes)
  • Comprehensive TypeScript types
  • Full test coverage
  • Documentation with examples
  • Exported from @deck.gl/geo-layers

…oading info

Adds a new utility function getTileLoadingState() that provides detailed
information about tile loading progress in TileLayer instances.

Background:
-----------
deck.gl's layer.isLoaded returns true once all tile requests are 'settled'
(completed OR failed). This is intentional - it prevents waiting forever for
tiles that will never load (404s, network errors, etc.). However, this makes
it impossible to distinguish between 'loaded successfully' and 'loaded with
errors' using just the boolean isLoaded property.

Solution:
---------
getTileLoadingState() provides granular information:
- Total, loaded, failed, and pending tile counts
- Percentage loaded for progress indicators
- isComplete and isSuccess flags for state detection

This allows applications to:
- Show loading progress (e.g., '47/50 tiles loaded')
- Detect and handle failed tiles
- Implement retry logic for failed tiles
- Display appropriate error states

Use Cases:
----------
- Video export: Wait for all tiles to settle before capturing frames
- Progress indicators: Show percentage loaded with error counts
- Error recovery: Retry failed tiles up to N times
- Analytics: Track tile loading success rates

Related:
--------
This addresses feedback from PR visgl#10360 about improving tile loading
observability without changing the core isLoaded behavior (which is
correct by design).
- Convert from tape to vitest test framework
- Move test file to correct location (test/modules/geo-layers/)
- Add copyright headers
- Register test in index.ts
- Add getTileLoadingState to top-level imports test
Comment thread modules/geo-layers/src/tile-layer/get-tile-loading-state.ts Outdated
Comment thread docs/api-reference/geo-layers/get-tile-loading-state.md Outdated
Comment thread modules/geo-layers/src/tile-layer/get-tile-loading-state.ts Outdated
@coveralls

Copy link
Copy Markdown

Coverage Status

coverage: 83.401% (+0.01%) from 83.391% — akre54:fix/tile-isloaded-bug into visgl:master

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