@@ -98,6 +98,9 @@ export class SunsynkPowerFlowCard extends LitElement {
9898
9999 private durationPrev : { [ name : string ] : number } = { } ;
100100 private durationCur : { [ name : string ] : number } = { } ;
101+ // Batch animation speed changes to minimize DOM work
102+ private _pendingSpeedUpdates : Map < string , number > = new Map ( ) ;
103+ private _speedRafId : number | null = null ;
101104
102105 // Performance: track only entities we care about and last seen states
103106 private _trackedEntityIds : Set < string > = new Set ( ) ;
@@ -2835,19 +2838,40 @@ export class SunsynkPowerFlowCard extends LitElement {
28352838
28362839 changeAnimationSpeed ( el : string , speedRaw : number ) {
28372840 const speed = speedRaw >= 1 ? Utils . toNum ( speedRaw , 3 ) : 1 ;
2838- const flow = this [ `${ el } Flow` ] as SVGSVGElement ;
28392841 this . durationCur [ el ] = speed ;
2840- if ( flow && this . _isVisible && this . durationPrev [ el ] != speed ) {
2841- // console.log(`${el} found, duration change ${this.durationPrev[el]} -> ${this.durationCur[el]}`);
2842- // this.gridFlow.pauseAnimations();
2843- requestAnimationFrame ( ( ) => {
2844- flow . setCurrentTime (
2845- flow . getCurrentTime ( ) * ( speed / this . durationPrev [ el ] ) ,
2846- ) ;
2847- } ) ;
2848- // this.gridFlow.unpauseAnimations();
2842+ // Defer DOM mutation: queue update and flush once per frame
2843+ if ( this . _isVisible ) {
2844+ this . _pendingSpeedUpdates . set ( el , speed ) ;
2845+ if ( this . _speedRafId == null ) {
2846+ this . _speedRafId = requestAnimationFrame ( ( ) => {
2847+ this . _flushAnimationSpeedUpdates ( ) ;
2848+ } ) ;
2849+ }
2850+ } else {
2851+ // If hidden, just record the new duration; apply when visible
2852+ this . durationPrev [ el ] = this . durationCur [ el ] ;
2853+ }
2854+ }
2855+
2856+ private _flushAnimationSpeedUpdates ( ) {
2857+ this . _speedRafId = null ;
2858+ if ( ! this . _isVisible || this . _pendingSpeedUpdates . size === 0 ) {
2859+ this . _pendingSpeedUpdates . clear ( ) ;
2860+ return ;
2861+ }
2862+ for ( const [ el , speed ] of this . _pendingSpeedUpdates ) {
2863+ const flow = this [ `${ el } Flow` ] as SVGSVGElement | undefined ;
2864+ const prev = this . durationPrev [ el ] ?? 1 ;
2865+ if ( flow && prev !== speed ) {
2866+ try {
2867+ flow . setCurrentTime ( flow . getCurrentTime ( ) * ( speed / prev ) ) ;
2868+ } catch {
2869+ // ignore if SVG is not ready
2870+ }
2871+ }
2872+ this . durationPrev [ el ] = this . durationCur [ el ] ;
28492873 }
2850- this . durationPrev [ el ] = this . durationCur [ el ] ;
2874+ this . _pendingSpeedUpdates . clear ( ) ;
28512875 }
28522876
28532877 get isCompactCard ( ) {
0 commit comments