Skip to content

perf(ui): defer off-screen layout/paint on entry and feed list rows#4384

Open
jvoisin wants to merge 1 commit into
miniflux:mainfrom
jvoisin:content-visibility
Open

perf(ui): defer off-screen layout/paint on entry and feed list rows#4384
jvoisin wants to merge 1 commit into
miniflux:mainfrom
jvoisin:content-visibility

Conversation

@jvoisin

@jvoisin jvoisin commented Jun 2, 2026

Copy link
Copy Markdown
Collaborator

Miniflux' default user.EntriesPerPage value is 100, so people with a lot of feeds/feed items might have 100 items displayed by default, which is a ton of DOM elements: multiple inline SVG icons, two , optional , optional reading-time chip, category tag, … the browser had to lay out and paint all of it on initial render even though there are only a handful of rows visible at once.

Setting content-visibility: auto on .entry-item and .feed-item lets the browser skip layout, paint, and accessibility-tree work for rows that fall outside the viewport, doing it lazily as the user scrolls. contain-intrinsic-size: auto reserves a placeholder using each row's last rendered size so the scrollbar and anchor scrolling stay consistent after first measurement.

This doesn't introduced any regressions in keyboard shortcuts, both from miniflux and from the browser. The two CSS properties are supported in current modern browsers, and are simply ignored in those that don't.

Sources used:

Comment thread internal/ui/static/css/common.css Outdated
Miniflux' default user.EntriesPerPage value is 100, so people with a lot of
feeds/feed items might have 100 items displayed by default, which is a ton of
DOM elements: multiple inline SVG icons, two <button>, optional <time>,
optional reading-time chip, category tag, … the browser had to lay out and
paint all of it on initial render even though there are only a handful of rows
visible at once.

Setting content-visibility: auto on .entry-item and .feed-item lets
the browser skip layout, paint, and accessibility-tree work for rows
that fall outside the viewport, doing it lazily as the user scrolls.
contain-intrinsic-size: auto reserves a placeholder using each row's
last rendered size so the scrollbar and anchor scrolling stay
consistent after first measurement. The value 100px was picked as on my
machine/screen/…, a feed-item is a bit less than 100px, and an entry-item is
a bit more than 80px.

This doesn't introduced any regressions in keyboard shortcuts, both from
miniflux and from the browser. The two CSS properties are supported in current
modern browsers, and are simply ignored in those that don't.

Sources used:

- https://developer.mozilla.org/en-US/docs/Web/CSS/Reference/Properties/content-visibility
- https://developer.mozilla.org/en-US/docs/Web/CSS/Reference/Properties/contain-intrinsic-size
@jvoisin jvoisin force-pushed the content-visibility branch from bd1ea46 to 50ee813 Compare June 3, 2026 06:30
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Development

Successfully merging this pull request may close these issues.

2 participants