perf(NcEmojiPicker): open x1.5-x2 faster + doesn't impact page loading
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
- The best we can do with
- 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 |
|---|---|
🥱 Boring details | Part 2: opening 👇
Opening NcEmojiPicker is slow... But why? 🤔
- Empty
NcPopoveris quite fast (30ms) - Raw
emoji-mart-vue-fastis relatively acceptable (50-60ms)
Empty NcPopover |
Raw emoji-mart-vue-fast |
|---|---|
~30ms |
~60ms |
But opening NcEmojiPicker = NcPopover + emoji-mart-vue-fast is 🐌 SLOW, up to:
- 160ms..200ms - clean open
- 120ms..150ms - quick reopen (optimized by NcPopover)
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.
| 🏚️ Before | 🏡 After |
|---|---|
| Clean open | Clean open |
| 200ms | 95ms |
| Quick reopen (optimized by NcPopover) | . |
| 100ms (even without Picker mounting!!!) | 65ms full remount |
🖼️ Screenshots
Useless gifs. Better to test in real app like Talk
| 🏚️ Before | 🏡 After |
|---|---|
| Clean open | . |
| Quick reopen | |
🏁 Checklist
- [ ] ⛑️ Tests are included or are not applicable
- [x] 📘 Component documentation has been extended, updated or is not applicable
- [x] 3️⃣ Backport to
nextrequested with a Vue 3 upgrade
Arr, gifs are not in sync