perf(bundle): lazy-load emoji-mart picker (defer ~82 KB gzip from first paint)

@emoji-mart/data (~430 KB / ~82 KB gzip) was pulled into the initial load by three always-mounted views (catalog custom-prefix, nick-icon, chat-input emoji selector) importing it statically. Add LazyEmojiPicker — a Suspense wrapper that dynamically imports the data + Picker on first open — and use it in those three sites.

Verified via the build manifest: the entry chunk no longer imports vendor-emoji statically or dynamically; vendor-emoji is now a dynamicImport of src/index.tsx, loaded on first picker open. No behaviour change. typecheck 0, tests 545/545.
This commit is contained in:
simoleo89
2026-06-17 21:26:55 +02:00
parent 1b032bcd23
commit 4d81fe7c82
4 changed files with 38 additions and 11 deletions
@@ -1,6 +1,5 @@
import { AddLinkEventTracker, CustomPrefixPurchaseFailedEvent, ILinkEventTracker, PurchaseCatalogPrefixComposer, PurchaseNickIconComposer, PurchasePrefixComposer, RemoveLinkEventTracker, RequestNickIconsComposer, SetActiveNickIconComposer, SetActivePrefixComposer, SetDisplayOrderComposer, UserNickIconsEvent } from '@nitrots/nitro-renderer';
import data from '@emoji-mart/data';
import Picker from '@emoji-mart/react';
import { LazyEmojiPicker } from '../../common/LazyEmojiPicker';
import { FC, useEffect, useMemo, useState } from 'react';
import { INickIconItem, IPrefixItem, PRESET_PREFIX_EFFECTS, PRESET_PREFIX_FONTS, SendMessageComposer, getPrefixEffectStyle, getPrefixFontStyle, parsePrefixColors } from '../../api';
import { GetNickIconUrl } from '../../assets/images/user_custom/nick_icons';
@@ -575,8 +574,7 @@ export const CustomizeNickIconView: FC<{}> = () =>
<>
<div className="fixed inset-0 z-[999]" onClick={ () => setShowEmojiPicker(false) } />
<div className="fixed left-1/2 top-1/2 z-[1000] -translate-x-1/2 -translate-y-1/2 overflow-hidden rounded-xl shadow-2xl">
<Picker
data={ data }
<LazyEmojiPicker
locale="en"
onEmojiSelect={ (emoji: { native: string }) =>
{