Skip to content

Faster History Rendering - #205

Open
breakthestatic wants to merge 2 commits into
nathan-gs:mainfrom
breakthestatic:faster-history-rendering
Open

Faster History Rendering#205
breakthestatic wants to merge 2 commits into
nathan-gs:mainfrom
breakthestatic:faster-history-rendering

Conversation

@breakthestatic

Copy link
Copy Markdown

The primary purpose of this PR is to improve the initial rendering delay when subscribing to the history websocket endpoint. The prior (existing) implementation received new entity history information almost immediately from the websocket and recorded the info internally. However, it still waited for the next Lit render cycle to actually put those coordinates on the map. Depending on when the last render occurred, this could defer the history rendering up to 10 seconds in my experience; I'm guessing that's the rate that the hass object emits changes.

To address this, I've added an immediate, debounced update call to the EntityHistoryManager’s react() method. This allows the history to appear as soon as data starts coming in from the websocket while avoiding excessive renders. Since the history is now decoupled from the full Lit render cycle, I needed to manually update the Entity’s current marker position to ensure the marker remains “synced” with the most recent history coordinate (hence refactoring the Entity marker logic into a separate function).

Lastly, I found quite a few errors when trying to use this custom card within a parent “template” card (both decluttering-card and streamline-card) and have made some adjustments to the map/view initialization logic to address them:

  • firstUpdated() is initially called before Home Assistant has injected the hass property. Added a guard to ensure it exists before calling setup().

  • Removed a redundant render() call within the setup() function. Lit will automatically queue up another render due to changes inside setup().

  • Moved/updated the setup() call within the render() function to outside the if (this.map) guard. The old setup() call was inside the if (this.map) guard, creating a deadlock in template cards. After teardown, this.map is undefined so setup() never runs, but setup() is what creates this.map. Moving it outside with its own guards lets the card re-bootstrap itself regardless of prior map state.

  • Previously connectedCallback() called this.setup() directly if the #map DOM element existed. But after a disconnect/reconnect cycle (i.e. template cards), the shadow DOM may not be fully ready yet. Calling requestUpdate() instead defers to LitElement’s update cycle, which will call render(), and the new setup() guard there handles bootstrapping once the DOM and hass are actually available.

  • Removed the this.initialViewRenderService?.setup() call in the resize observer. This was resetting the user's zoom/pan on every resize event, overriding any manual map interaction.

  • Added a single, one-shot resize observer in the InitialViewRenderService to handle setting the view after the parent DOM has size.

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.

1 participant