Description
TailwindTemplateCard.processAndRender() calls this._hass.connection.subscribeMessage({ type: 'render_template', ... }) on every render and discards the returned unsubscribe function. The card also has no disconnectedCallback / teardown, so nothing ever closes these subscriptions.
Home Assistant calls a card's set hass setter on every state change, so a card with parse_jinja: true re-subscribes constantly (whenever a watched entity changes). Every leaked subscription stays live on the WebSocket connection and keeps pushing render_template results, which trigger further renders. Memory and CPU grow superlinearly the longer the dashboard stays open.
Impact
Fatal on an always-on kiosk. On a Galaxy Tab A7 Lite (3 GB) running the HA Companion app, the WebView renderer grew from ~490 MB to over 1 GB in a few minutes and Android's low-memory killer then killed the app (dashboard showed "Reload UI", then relaunched). A manual dashboard reload dropped the renderer straight back to ~490 MB, confirming the growth is leaked subscriptions, not the bundle.
Location
src/elements/TailwindTemplateCard.tsx, processAndRender() (v3.1.1):
this._hass.connection.subscribeMessage(
(msg) => { this._htmlContent = msg.result; this._renderHtmlContent(); },
{ type: "render_template", template: content },
); // return value (unsubscribe) discarded; a new one is created on every render
Suggested fix
Store the unsubscribe handle, close the previous subscription before opening a new one, and tear it down in disconnectedCallback() — bounding it to one live subscription per card. PR to follow. Prebuilt fork for anyone hit by this meanwhile: https://github.com/jason-curtis/tailwindcss-template-card-leakfix
Environment
- tailwindcss-template-card v3.1.1
- HA Companion (Android), WebView (Chromium) 150
Issue and written with Claude Opus but verified by @jasoncurtis
Description
TailwindTemplateCard.processAndRender()callsthis._hass.connection.subscribeMessage({ type: 'render_template', ... })on every render and discards the returned unsubscribe function. The card also has nodisconnectedCallback/ teardown, so nothing ever closes these subscriptions.Home Assistant calls a card's
set hasssetter on every state change, so a card withparse_jinja: truere-subscribes constantly (whenever a watched entity changes). Every leaked subscription stays live on the WebSocket connection and keeps pushingrender_templateresults, which trigger further renders. Memory and CPU grow superlinearly the longer the dashboard stays open.Impact
Fatal on an always-on kiosk. On a Galaxy Tab A7 Lite (3 GB) running the HA Companion app, the WebView renderer grew from ~490 MB to over 1 GB in a few minutes and Android's low-memory killer then killed the app (dashboard showed "Reload UI", then relaunched). A manual dashboard reload dropped the renderer straight back to ~490 MB, confirming the growth is leaked subscriptions, not the bundle.
Location
src/elements/TailwindTemplateCard.tsx,processAndRender()(v3.1.1):Suggested fix
Store the unsubscribe handle, close the previous subscription before opening a new one, and tear it down in
disconnectedCallback()— bounding it to one live subscription per card. PR to follow. Prebuilt fork for anyone hit by this meanwhile: https://github.com/jason-curtis/tailwindcss-template-card-leakfixEnvironment
Issue and written with Claude Opus but verified by @jasoncurtis