Frontmatter
| id | 9053 |
| title | Perf: Optimize CountryFlag to Prevent Grid Reflows |
| state | Closed |
| labels | bugaiperformance |
| assignees | tobiu |
| createdAt | Feb 8, 2026, 7:10 PM |
| updatedAt | Feb 8, 2026, 7:27 PM |
| githubUrl | https://github.com/neomjs/neo/issues/9053 |
| author | tobiu |
| commentsCount | 1 |
| parentIssue | 8930 |
| subIssues | [] |
| subIssuesCompleted | 0 |
| subIssuesTotal | 0 |
| blockedBy | [] |
| blocking | [] |
| closedAt | Feb 8, 2026, 7:27 PM |
Perf: Optimize CountryFlag to Prevent Grid Reflows

tobiu
Feb 8, 2026, 7:25 PM
Input from Gemini 3 Pro:
✦ Final Optimization Strategy:
To resolve the "Forced Reflow" violations caused by the CountryFlag component during rapid grid scrolling, we implemented a "Stable DOM" architecture.
Stable VDOM Structure:
- The component now always renders an
<img>tag, regardless of whether a flag URL exists.- Previously, switching between
<img>(flag) and<span>(placeholder) triggeredremoveNode/insertNodeoperations, causing layout thrashing.- Now, we toggle
visibility: hiddenand remove thesrcattribute when no flag is present. This is a zero-layout-cost operation (paint only).Layout Isolation:
- Applied
contain: layout paint style;to the.neo-country-flagwrapper in SCSS.- This isolates the component's internal layout reflows from the parent grid row.
- Note: We avoided
contain: strict(which includessize) because the component relies on its children for auto-sizing, andstrictwould have collapsed it to 0px height.Explicit Dimensions:
- The
imgtag now has explicitwidth="20"andheight="20"attributes in the VDOM to prevent layout shifts during image loading.Results: Tests confirm that removing the tag-swapping logic eliminates the forced reflows, restoring 60fps scrolling performance even with mixed data (rows with and without flags).
tobiu assigned to @tobiu on Feb 8, 2026, 7:27 PM
tobiu closed this issue on Feb 8, 2026, 7:27 PM
tobiu added parent issue #8930 on Feb 8, 2026, 7:50 PM
The
Neo.component.CountryFlagcomponent has been identified as the source of "Forced Reflow" violations during Grid scrolling. The current implementation switches the VDOM tag betweenimgandspandepending on whether a flag URL is available. This triggers frequent node removal/insertion during scrolling, which, combined with the lack of explicit dimension attributes on theimgtag, causes layout thrashing.Optimization Strategy:
contain: strictto.neo-country-flag(the container) to isolate layout calculations.img<->span), maintain a stable DOM structure to avoidremoveNode/insertNodeoperations.imgtag. If no flag is available, setsrcto a transparent pixel (or handle via CSS visibility) and potentially toggle a class like.neo-country-placeholder.width="20"andheight="20"attributes to theimgVDOM node to prevent layout shifts during image loading.Implementation Steps:
resources/scss/src/component/CountryFlag.scss: Addcontain: strictto the main wrapper.src/component/CountryFlag.mjs:afterSetLocationto maintain a stableimgtag.widthandheightattributes to theimgconfig.