thomasloven / lovelace-card-mod

🔹 Add CSS styles to (almost) any lovelace card
MIT License
1.12k stars 167 forks source link

Styling stage-badge inside picture-elements causes freezes #154

Closed ildar170975 closed 2 years ago

ildar170975 commented 2 years ago

My Home Assistant version: 2021.11.1

My lovelace configuration method (GUI or yaml): yaml

What I am doing: Styling state-badges inside Picture elements card.

What I expected to happen: Styling is performed, UI elements respond to user's actions.

What happened instead: Styling is performed, UI elements DO NOT respond to user's actions.

Minimal steps to reproduce: Create 2 views: view 1: This view causes freezes.

title: pic-ele-state-badge-1
path: test-card-mod-pic-ele-state-badge-1
panel: false
badges: []
cards:
  - type: picture-elements
    image: /local/images/white.jpg
    card_mod:
      style:
        hui-state-badge-element:
          $:
            ha-state-label-badge:
              $:
                ha-label-badge:
                  $: |
                    .badge-container .label-badge .label span {
                      border-style: solid;
                      border-color: green;
                      color: blue;
                      background-color: magenta;
                    }
              .: |
                ha-state-label-badge {
                  color: orange;
                  --label-badge-background-color: yellow;
                  --label-badge-text-color: red;
                  --label-badge-red: cyan;
                }
    elements:
      - type: state-badge
        entity: sensor.cleargrass_1_co2
        style:
          top: 8%
          left: 10%

      - type: state-badge
        entity: binary_sensor.updater
        style:
          top: 8%
          left: 30%

      - type: state-badge
        entity: sensor.cleargrass_1_co2
        style:
          top: 8%
          left: 50%

      - type: state-badge
        entity: sensor.cleargrass_1_co2
        style:
          top: 8%
          left: 70%

Which produces this view: image

view 2: This view works fine.

title: pic-ele-state-badge-2
path: test-card-mod-pic-ele-state-badge-2
panel: false
badges: []
cards:

  - type: picture-elements
    image: /local/images/white.jpg
    card_mod:
      style: |
        ha-card {
          height: 130px !important;
        }
    elements:

      - type: state-badge
        entity: sensor.cleargrass_1_co2
        style:
          top: 8%
          left: 10%
        card_mod:
          style:
            ha-state-label-badge:
              $:
                ha-label-badge:
                  $: |
                    .badge-container .label-badge .label span {
                      border-style: solid;
                      border-color: green;
                      color: blue;
                      background-color: magenta;
                    }
            .: |
              :host {
                color: orange;
                --label-badge-background-color: yellow;
                --label-badge-text-color: red;
                --label-badge-red: cyan;
              }

      - type: state-badge
        entity: binary_sensor.updater
        style:
          top: 8%
          left: 30%
        card_mod:
          style: |
            :host {
              color: orange;
              --label-badge-background-color: yellow;
              --label-badge-text-color: red;
              --label-badge-blue: cyan;
            }

      - type: state-badge
        entity: sensor.cleargrass_1_co2
        style:
          top: 8%
          left: 50%

      - type: state-badge
        entity: sensor.cleargrass_1_co2
        style:
          top: 8%
          left: 70%

Which produces this view: image

Styling for the both views is same: view 1 - styling made for ALL badges; view 2 - styling made for SOME badges.

Error messages from the browser console: No error messages, only verbose messages: "[Violation] Forced reflow while executing JavaScript took ms"

view 1: Number of verbose messages quickly increases, may become >1000 within several minutes. The view 1 freezes, this was observed just recently. image

If card-mod is removed - no verbose messages, no freezes: image

view 2: Number of verbose messages is usually not more than 2, no freezes: image


By putting an X in the boxes ([]) below, I indicate that I:

thomasloven commented 2 years ago

I can reproduce this, so that's... something.

I don't get any freezing, but some noticeable slowdown. It's much better if the number of steps are limited, though:

card_mod:
  style:
    hui-state-badge-element:
      $ ha-state-label-badge:
        $ ha-label-badge $: |
          .badge-container .label-badge .label span {
            border-style: solid;
            border-color: green;
            color: blue;
            background-color: magenta;
          }
        .: |
          ha-state-label-badge {
            color: orange;
            --label-badge-background-color: yellow;
            --label-badge-text-color: red;
            --label-badge-red: cyan;
          }
ildar170975 commented 2 years ago

This is a new info for me, thank you! Could you answer these questions:

1) Is there any difference between:

element$:
  element$:
    ...

and

element:
  $element$:
    ...

?

2) If styling ONE element, not like "all similar elements" - shall I use this:

element$:
  element$:
    ...

instead of this:

element:
  $:
    element:
      $:
        ...

?

thomasloven commented 2 years ago

element $ will find the first instance of element and then all shadowRoots in it (which is one). element will find all instances of element.

For every complete step in the chain, card-mod creates a new card-mod element, which monitors its parent for changes so it can update itself if something happens. That means if you do

element-a:
  $:
    element-b:
    $:

There will be one card-mod created in each element-a, one in the shadowRoot of each element-a, one in each element-b in every element-a and one in the shadowRoot of every element-b in each element-a.

Meanwhile

element-a:
  $ element-b $:

will create one card-mod element in each element-a, and one in the shadowRoot of the first element-b in the each element-a. That may up to 50% less elements that have to do stuff when things change.

You can inspect the differences using the debugging tips at the end of the dom-navigation section.

Side note - I really should change it so that element-b $ selects the shadowRoot of all element-b... :thinking: So, for your second question: Yes, that would be more efficient. Or even element $ element $ if it's only one instance.

ildar170975 commented 2 years ago

Thomas, very clear explanation! Thank you.