nextcloud-vue icon indicating copy to clipboard operation
nextcloud-vue copied to clipboard

perf(NcEmojiPicker): open x1.5-x2 faster + doesn't impact page loading

Open ShGKme opened this issue 11 months ago • 1 comments

Improving NcEmojiPicker: part 3 of 3

☑️ Resolves

  • Part 2: https://github.com/nextcloud-libraries/nextcloud-vue/pull/6466
  • Improve page loading performance - 100ms -> 0ms (no more blocking)
  • Improve opening performance - x1.5 .. x2
    • The best we can do with emoji-mart-vue-fast
  • Occasionally
    • Fix https://github.com/nextcloud-libraries/nextcloud-vue/issues/3840
🥱 Boring details | Part 1: initial load 👇

NcEmojiPicker requires creating EmojiIndex with blocks the main thread for about 100ms or more!

We already improved it by:

  • Making it only once (instead of every component instance 😵)
  • Making it in setup (not blocking initial Nextcloud app loading)

However, it still blocks the main thread app to 100ms once there is the picker on the page...

Improvement (except Safari) - using requestIdleCallback.

In the best case - no blocking anymore at all.

In the worth case (it's Safari, or EmojiPicker renders initially) - works as in the past.

🏚️ Before 🏡 After
image image
🥱 Boring details | Part 2: opening 👇

Opening NcEmojiPicker is slow... But why? 🤔

  • Empty NcPopover is quite fast (30ms)
  • Raw emoji-mart-vue-fast is relatively acceptable (50-60ms)
Empty NcPopover Raw emoji-mart-vue-fast
~30ms ~60ms
Empty-NcPopover Raw-emoji-mart-vue-fast

But opening NcEmojiPicker = NcPopover + emoji-mart-vue-fast is 🐌 SLOW, up to:

  • 160ms..200ms - clean open
  • 120ms..150ms - quick reopen (optimized by NcPopover)

image

NcEmojiPicker

It looks like floating-vue (NcPopover) first renders everything, when makes it "hiddenly visible) to get size and calculate position, and then renders it visually. It causes unneeded reflow, slightly blocking the process (even on optimized reopening, when everything is in DOM already).

A solution - mount NcPopover with dummy empty div with the same size, and then render emoji-mart-vue-fast into a prepared container.

NcEmojiPicker - new

🏚️ Before 🏡 After
Clean open Clean open
200ms 95ms
image image
Quick reopen (optimized by NcPopover) .
100ms (even without Picker mounting!!!) 65ms full remount
image image

🖼️ Screenshots

Useless gifs. Better to test in real app like Talk
🏚️ Before 🏡 After
Clean open .
before-clean after-clean
Quick reopen
before-reopen after-reopen

🏁 Checklist

  • [ ] ⛑️ Tests are included or are not applicable
  • [x] 📘 Component documentation has been extended, updated or is not applicable
  • [x] 3️⃣ Backport to next requested with a Vue 3 upgrade

ShGKme avatar Jan 27 '25 18:01 ShGKme

Arr, gifs are not in sync

ShGKme avatar Jan 27 '25 18:01 ShGKme