@@ -60,40 +60,42 @@ func (ui *ContainerHelper) RenderContainer(e *core.Element, w io.Writer, outerHT
6060}
6161
6262func (ui * ContainerHelper ) UpdateContainer (e * core.Element ) {
63- var toRemove , toAppend []* core.Element
64- var orderData []core.Jid
63+ var toAppend []* core.Element
6564
66- oldMap := make (map [core.UI ]* core.Element )
67- newMap := make (map [core.UI ]struct {})
68- newContents := ui .Container .JawsContains (e )
69- for _ , childUI := range newContents {
70- newMap [childUI ] = struct {}{}
71- }
65+ wantContents := ui .Container .JawsContains (e )
66+ newOrder := make ([]core.Jid , 0 , len (wantContents ))
7267
7368 ui .mu .Lock ()
69+ // build pool of reusable Elements keyed by UI, preserving duplicates
70+ pool := make (map [core.UI ][]* core.Element , len (ui .contents ))
7471 oldOrder := make ([]core.Jid , len (ui .contents ))
7572 for i , elem := range ui .contents {
7673 oldOrder [i ] = elem .Jid ()
77- oldMap [elem .Ui ()] = elem
78- if _ , ok := newMap [elem .Ui ()]; ! ok {
79- toRemove = append (toRemove , elem )
80- }
74+ pool [elem .Ui ()] = append (pool [elem .Ui ()], elem )
8175 }
76+
77+ // build new contents, reusing pooled Elements where possible
8278 ui .contents = ui .contents [:0 ]
83- for _ , childUI := range newContents {
84- elem := oldMap [childUI ]
85- if elem == nil {
79+ for _ , childUI := range wantContents {
80+ var elem * core.Element
81+ if elems := pool [childUI ]; len (elems ) > 0 {
82+ elem = elems [0 ]
83+ pool [childUI ] = elems [1 :]
84+ } else {
8685 elem = e .Request .NewElement (childUI )
8786 toAppend = append (toAppend , elem )
8887 }
8988 ui .contents = append (ui .contents , elem )
90- orderData = append (orderData , elem .Jid ())
89+ newOrder = append (newOrder , elem .Jid ())
9190 }
9291 ui .mu .Unlock ()
9392
94- for _ , elem := range toRemove {
95- e .Remove (elem .Jid ().String ())
96- e .Request .DeleteElement (elem )
93+ // remove leftover Elements not present in new contents
94+ for _ , elems := range pool {
95+ for _ , elem := range elems {
96+ e .Remove (elem .Jid ().String ())
97+ e .Request .DeleteElement (elem )
98+ }
9799 }
98100
99101 for _ , elem := range toAppend {
@@ -102,7 +104,7 @@ func (ui *ContainerHelper) UpdateContainer(e *core.Element) {
102104 e .Append (template .HTML (sb .String ())) // #nosec G203
103105 }
104106
105- if ! slices .Equal (oldOrder , orderData ) {
106- e .Order (orderData )
107+ if ! slices .Equal (oldOrder , newOrder ) {
108+ e .Order (newOrder )
107109 }
108110}
0 commit comments