CloudCannon / pagefind

Static low-bandwidth search at scale
https://pagefind.app
MIT License
3.66k stars 120 forks source link

Modular UI fires loading event for a split second before rendering results #309

Open n-older opened 1 year ago

n-older commented 1 year ago

I'm running into an issue where the Modular UI renders the placeholder template for a split second after the results come back. So upon every resolved request the results list has a noticeable blip/CLS even if the total request duration was near instantaneous. This is not the case in the default UI.

I tested it on a custom network throttle (20 kb/s) to check if the loading state was active long enough to show the placeholder but it just shows the old results for a longer duration before the placeholder template flash.

Something like a default/configurable timeout to wait before rendering the placeholder template would be nice so that fast network connections don't show a blip on every keystroke.

https://github.com/CloudCannon/pagefind/assets/32823514/a8d3002c-ce0f-4cea-b4c6-429ed41b1bdc

bglw commented 1 year ago

Ah, yes that is an issue. I'll dig into a way to fix this 🤔

Currently the ResultsList component in the Modular doesn't reuse any content. When it gets new content it first clears itself out: https://github.com/CloudCannon/pagefind/blob/0b86436c8a47dca43e079c497120b724de86cfea/pagefind_ui/modular/components/resultList.js#L145

Then we add stubs for all results on the page: https://github.com/CloudCannon/pagefind/blob/0b86436c8a47dca43e079c497120b724de86cfea/pagefind_ui/modular/components/resultList.js#L148-L150

Then each of those stubs loads based on an IntersectionObserver: https://github.com/CloudCannon/pagefind/blob/0b86436c8a47dca43e079c497120b724de86cfea/pagefind_ui/modular/components/resultList.js#L86-L87

To fix this, I guess ideally we should a) Aim to keep any result nodes that are still a match where they are b) Skip the placeholder node step if the data is already loaded

n-older commented 1 year ago

To fix this, I guess ideally we should a) Aim to keep any result nodes that are still a match where they are b) Skip the placeholder node step if the data is already loaded

I agree, this seems like a good approach 👍🏼