Skip to content

Memory leak: render_template subscription re-created every render, never unsubscribed #11

Description

@jason-curtis

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

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions