Edit: Problem narrowed down to the use of the Anime stone theme on Chrome based browsers, likely unrelated to the g transform code below, but unknown.
TL;DR: There's a performance hit from per-stone <g transform="translate(...)"> on large/long game boards.
Summary
Rendering Go boards currently creates a <g> group, each with its own transform="translate(x, y)", for every stone. On some browsers (notably Edge on Mac), this leads to significant lag and slow rendering, especially on pages with multiple boards or previews, or during games with more than a hundred moves.
Example of current output:
<g transform="translate(208,16)">
<use href="#anime-black-8-59" x="-0.5" y="-0.5"></use>
</g>
<g transform="translate(128,80)">
<use href="#anime-white-8-58" x="-0.5" y="-0.5"></use>
</g>
If I modify the output to instead use direct x and y positions on the <use>, and skip the per-stone <g transform="...">, performance seems to improve:
<g>
<use href="#anime-black-8-59" x="208" y="16"></use>
<use href="#anime-white-8-58" x="128" y="80"></use>
<!-- ...and so on... -->
</g>
Proposal
- Instead of generating a
<g> for every stone, batch all <use> elements under a single <g>.
- Set the actual board coordinates using
x and y attributes on the <use> element, eliminating the need for transform="translate(...)" per stone.
- This approach appears to render much faster and solves the performance issue in Edge on Mac, while maintaining the visual output, based on my manual testing. On boards with hundreds of stones, the SVG DOM gets very deep and browsers on lower powered machines struggle with many nested groups and transforms.
- I think this change will happen in SVGRenderer but I'm not 100% sure I'm in the right place.
Thanks for reading!
Edit: Problem narrowed down to the use of the Anime stone theme on Chrome based browsers, likely unrelated to the g transform code below, but unknown.
TL;DR: There's a performance hit from per-stone
<g transform="translate(...)">on large/long game boards.Summary
Rendering Go boards currently creates a
<g>group, each with its owntransform="translate(x, y)", for every stone. On some browsers (notably Edge on Mac), this leads to significant lag and slow rendering, especially on pages with multiple boards or previews, or during games with more than a hundred moves.Example of current output:
If I modify the output to instead use direct
xandypositions on the<use>, and skip the per-stone<g transform="...">, performance seems to improve:Proposal
<g>for every stone, batch all<use>elements under a single<g>.xandyattributes on the<use>element, eliminating the need fortransform="translate(...)"per stone.Thanks for reading!