mirror of
https://github.com/duckietm/Nitro-V3.git
synced 2026-06-19 15:06:20 +00:00
Merge pull request #253 from simoleo89/feat/code-splitting
perf(bundle): lazy-load emoji-mart picker (defer ~82 KB gzip from first paint)
This commit is contained in:
@@ -0,0 +1,32 @@
|
||||
import { ComponentType, FC, lazy, Suspense } from 'react';
|
||||
|
||||
type EmojiPickerProps = Record<string, unknown>;
|
||||
|
||||
/**
|
||||
* emoji-mart's data bundle (`@emoji-mart/data`) is ~430 KB (~82 KB gzip) and was
|
||||
* pulled into the initial app bundle by three always-mounted views that import it
|
||||
* statically. The picker itself opens rarely, so we load both the data and the
|
||||
* `<Picker>` component on demand via a dynamic import — deferring that payload out
|
||||
* of first paint. Drop-in for `<Picker data={data} … />` (the `data` prop is
|
||||
* injected here; forward every other prop unchanged).
|
||||
*/
|
||||
const PickerWithData = lazy(async () =>
|
||||
{
|
||||
const [ dataModule, pickerModule ] = await Promise.all([
|
||||
import('@emoji-mart/data'),
|
||||
import('@emoji-mart/react')
|
||||
]);
|
||||
|
||||
const data = (dataModule as { default: unknown }).default;
|
||||
const Picker = (pickerModule as { default: ComponentType<EmojiPickerProps> }).default;
|
||||
|
||||
const Wrapped: ComponentType<EmojiPickerProps> = props => <Picker data={ data } { ...props } />;
|
||||
|
||||
return { default: Wrapped };
|
||||
});
|
||||
|
||||
export const LazyEmojiPicker: FC<EmojiPickerProps> = props => (
|
||||
<Suspense fallback={ <div className="px-2 py-1 text-[11px] text-white/60">…</div> }>
|
||||
<PickerWithData { ...props } />
|
||||
</Suspense>
|
||||
);
|
||||
@@ -2,8 +2,7 @@ import { PurchasePrefixComposer } from '@nitrots/nitro-renderer';
|
||||
import { FC, useEffect, useMemo, useRef, useState } from 'react';
|
||||
import { LocalizeText, SanitizeHtml, SendMessageComposer, PRESET_PREFIX_EFFECTS, parsePrefixColors, getPrefixEffectStyle, PREFIX_EFFECT_KEYFRAMES } from '../../../../../api';
|
||||
import { CatalogLayoutProps } from './CatalogLayout.types';
|
||||
import data from '@emoji-mart/data';
|
||||
import Picker from '@emoji-mart/react';
|
||||
import { LazyEmojiPicker } from '../../../../../common/LazyEmojiPicker';
|
||||
|
||||
const PRESET_COLORS: string[] = [
|
||||
'#FF0000', '#FF6600', '#FFCC00', '#33CC00', '#00CCFF',
|
||||
@@ -222,8 +221,7 @@ export const CatalogLayoutCustomPrefixView: FC<CatalogLayoutProps> = props =>
|
||||
<>
|
||||
<div className="fixed inset-0" style={ { zIndex: 999, background: 'rgba(0,0,0,0.5)' } } onClick={ () => setShowIconPicker(false) } />
|
||||
<div className="fixed rounded-xl overflow-hidden" style={ { zIndex: 1000, top: '50%', left: '50%', transform: 'translate(-50%, -50%)', boxShadow: '0 8px 32px rgba(0,0,0,0.6)' } }>
|
||||
<Picker
|
||||
data={ data }
|
||||
<LazyEmojiPicker
|
||||
locale="it"
|
||||
onEmojiSelect={ (emoji: { native: string }) =>
|
||||
{
|
||||
|
||||
@@ -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 }) =>
|
||||
{
|
||||
|
||||
@@ -1,6 +1,5 @@
|
||||
import data from '@emoji-mart/data';
|
||||
import Picker from '@emoji-mart/react';
|
||||
import * as Popover from '@radix-ui/react-popover';
|
||||
import { LazyEmojiPicker } from '../../../../common/LazyEmojiPicker';
|
||||
import { FC, useState } from 'react';
|
||||
|
||||
interface ChatInputEmojiSelectorViewProps
|
||||
@@ -26,7 +25,7 @@ export const ChatInputEmojiSelectorView: FC<ChatInputEmojiSelectorViewProps> = p
|
||||
</Popover.Trigger>
|
||||
<Popover.Portal>
|
||||
<Popover.Content className="z-[1070]" side="top" sideOffset={ 8 }>
|
||||
<Picker data={ data } onEmojiSelect={ handleEmojiSelect } />
|
||||
<LazyEmojiPicker onEmojiSelect={ handleEmojiSelect } />
|
||||
</Popover.Content>
|
||||
</Popover.Portal>
|
||||
</Popover.Root>
|
||||
|
||||
Reference in New Issue
Block a user