Skip to content

Commit 361c44d

Browse files
authored
Speedup traverse_dynamic (#4199)
1 parent d5ba3a7 commit 361c44d

1 file changed

Lines changed: 51 additions & 24 deletions

File tree

lib/phoenix_live_view/diff.ex

Lines changed: 51 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -612,32 +612,59 @@ defmodule Phoenix.LiveView.Diff do
612612
end
613613

614614
defp traverse_dynamic(dynamic, children, pending, components, template, changed?) do
615-
Enum.reduce(dynamic, {0, %{}, children, pending, components, template}, fn
616-
entry, {counter, diff, children, pending, components, template} ->
617-
child = Map.get(children, counter)
618-
619-
{serialized, child_fingerprint, pending, components, template} =
620-
traverse(entry, child, pending, components, template, changed?)
621-
622-
# If serialized is nil, it means no changes.
623-
# If it is an empty map, then it means it is a rendered struct
624-
# that did not change, so we don't have to emit it either.
625-
diff =
626-
if serialized != nil and serialized != %{} do
627-
Map.put(diff, counter, serialized)
628-
else
629-
diff
630-
end
615+
traverse_dynamic(dynamic, 0, %{}, children, pending, components, template, changed?)
616+
end
631617

632-
children =
633-
if child_fingerprint do
634-
Map.put(children, counter, child_fingerprint)
635-
else
636-
Map.delete(children, counter)
637-
end
618+
defp traverse_dynamic(
619+
[entry | entries],
620+
counter,
621+
diff,
622+
children,
623+
pending,
624+
components,
625+
template,
626+
changed?
627+
) do
628+
child = Map.get(children, counter)
638629

639-
{counter + 1, diff, children, pending, components, template}
640-
end)
630+
{serialized, child_fingerprint, pending, components, template} =
631+
traverse(entry, child, pending, components, template, changed?)
632+
633+
# If serialized is nil, it means no changes.
634+
# If it is an empty map, then it means it is a rendered struct
635+
# that did not change, so we don't have to emit it either.
636+
diff =
637+
if serialized != nil and serialized != %{} do
638+
Map.put(diff, counter, serialized)
639+
else
640+
diff
641+
end
642+
643+
children =
644+
if child_fingerprint do
645+
Map.put(children, counter, child_fingerprint)
646+
else
647+
if child do
648+
Map.delete(children, counter)
649+
else
650+
children
651+
end
652+
end
653+
654+
traverse_dynamic(
655+
entries,
656+
counter + 1,
657+
diff,
658+
children,
659+
pending,
660+
components,
661+
template,
662+
changed?
663+
)
664+
end
665+
666+
defp traverse_dynamic([], counter, diff, children, pending, components, template, _changed?) do
667+
{counter, diff, children, pending, components, template}
641668
end
642669

643670
defp traverse_keyed(

0 commit comments

Comments
 (0)