Merge pull request 'perf: load the Settings dialog on demand; entry chunk 351.8 → 277.1 kB gzip' (#420) from perf/lazy-settings into lotus
CI / Build & Quality Checks (push) Successful in 2m10s
CI / Docker image build & smoke test (push) Skipped
CI / Secret scan (gitleaks) (push) Successful in 21s
CI / Trigger Desktop Build (push) Successful in 17s
CI / Playwright smoke (e2e) (push) Successful in 14m42s
CI / Build & Quality Checks (push) Successful in 2m10s
CI / Docker image build & smoke test (push) Skipped
CI / Secret scan (gitleaks) (push) Successful in 21s
CI / Trigger Desktop Build (push) Successful in 17s
CI / Playwright smoke (e2e) (push) Successful in 14m42s
This commit was merged in pull request #420.
This commit is contained in:
@@ -33,16 +33,9 @@ import { About } from './about';
|
||||
import { UseStateProvider } from '../../components/UseStateProvider';
|
||||
import { stopPropagation } from '../../utils/keyboard';
|
||||
import { LogoutDialog } from '../../components/LogoutDialog';
|
||||
import { SettingsPages } from './pages';
|
||||
|
||||
export enum SettingsPages {
|
||||
GeneralPage,
|
||||
AccountPage,
|
||||
NotificationPage,
|
||||
DevicesPage,
|
||||
EmojisStickersPage,
|
||||
DeveloperToolsPage,
|
||||
AboutPage,
|
||||
}
|
||||
export { SettingsPages };
|
||||
|
||||
type SettingsMenuItem = {
|
||||
page: SettingsPages;
|
||||
|
||||
@@ -0,0 +1,43 @@
|
||||
import React, { lazy, Suspense } from 'react';
|
||||
import { Box, Spinner, config } from 'folds';
|
||||
import type { SettingsPages } from './pages';
|
||||
|
||||
// Settings is a large, rarely-open dialog (all its pages, pickers, the
|
||||
// denoise tester…). Load it on first open instead of in the entry chunk, and
|
||||
// warm the chunk once the app is idle so opening it rarely waits.
|
||||
const loadSettings = () => import('./Settings');
|
||||
const SettingsDialog = lazy(() => loadSettings().then((m) => ({ default: m.Settings })));
|
||||
if (typeof window !== 'undefined') {
|
||||
const warm = () => {
|
||||
loadSettings().catch(() => undefined);
|
||||
};
|
||||
if ('requestIdleCallback' in window) window.requestIdleCallback(warm, { timeout: 10_000 });
|
||||
else setTimeout(warm, 5_000);
|
||||
}
|
||||
|
||||
type SettingsProps = {
|
||||
initialPage?: SettingsPages;
|
||||
requestClose: () => void;
|
||||
};
|
||||
|
||||
export function Settings(props: SettingsProps) {
|
||||
return (
|
||||
<Suspense
|
||||
fallback={
|
||||
// Settings opens inside a FocusTrap, which needs a tabbable node.
|
||||
<Box
|
||||
tabIndex={0}
|
||||
role="status"
|
||||
aria-label="Loading settings"
|
||||
alignItems="Center"
|
||||
justifyContent="Center"
|
||||
style={{ padding: config.space.S700, outline: 'none' }}
|
||||
>
|
||||
<Spinner variant="Secondary" size="400" />
|
||||
</Box>
|
||||
}
|
||||
>
|
||||
<SettingsDialog {...props} />
|
||||
</Suspense>
|
||||
);
|
||||
}
|
||||
@@ -71,6 +71,7 @@ import {
|
||||
makePresetId,
|
||||
normalizeLabel,
|
||||
} from '../../../utils/statusPresets';
|
||||
import { STATUS_EXPIRY_KEY, STATUS_MSG_KEY } from '../../../utils/statusKeys';
|
||||
import { writeStatusExpiry } from '../../../utils/statusExpiry';
|
||||
|
||||
type ProfileProps = {
|
||||
@@ -370,8 +371,7 @@ function ProfileDisplayName({ profile, userId }: ProfileProps) {
|
||||
);
|
||||
}
|
||||
|
||||
export const STATUS_EXPIRY_KEY = (id: string) => `lotus-status-expiry-${id}`;
|
||||
export const STATUS_MSG_KEY = (id: string) => `lotus-status-msg-${id}`;
|
||||
export { STATUS_EXPIRY_KEY, STATUS_MSG_KEY };
|
||||
|
||||
const CLEAR_AFTER_OPTIONS = [
|
||||
{ label: 'Never', value: '0' },
|
||||
|
||||
@@ -1 +1,2 @@
|
||||
export * from './Settings';
|
||||
export { SettingsPages } from './pages';
|
||||
export { Settings } from './SettingsLazy';
|
||||
|
||||
@@ -0,0 +1,11 @@
|
||||
/** Settings dialog pages. Kept apart from Settings.tsx so callers can name a
|
||||
* page without pulling the dialog into the entry chunk. */
|
||||
export enum SettingsPages {
|
||||
GeneralPage,
|
||||
AccountPage,
|
||||
NotificationPage,
|
||||
DevicesPage,
|
||||
EmojisStickersPage,
|
||||
DeveloperToolsPage,
|
||||
AboutPage,
|
||||
}
|
||||
@@ -63,7 +63,7 @@ import {
|
||||
migrateLocalMuteTimers,
|
||||
unmuteRoom,
|
||||
} from '../../features/room-nav/muteTimers';
|
||||
import { STATUS_EXPIRY_KEY, STATUS_MSG_KEY } from '../../features/settings/account/Profile';
|
||||
import { STATUS_EXPIRY_KEY, STATUS_MSG_KEY } from '../../utils/statusKeys';
|
||||
import { noteLocalStatusWrite } from '../../utils/ownStatusSync';
|
||||
import { setPresenceWithRetry } from '../../utils/presenceWrite';
|
||||
import { useDeepLinkNavigate } from '../../hooks/useDeepLinkNavigate';
|
||||
|
||||
@@ -0,0 +1,3 @@
|
||||
/** localStorage keys for this device's copy of the status message and its expiry. */
|
||||
export const STATUS_EXPIRY_KEY = (id: string) => `lotus-status-expiry-${id}`;
|
||||
export const STATUS_MSG_KEY = (id: string) => `lotus-status-msg-${id}`;
|
||||
@@ -251,6 +251,25 @@ const vendorChunks = (id) => {
|
||||
if (id.includes('node_modules/immer')) return 'immer';
|
||||
if (id.includes('node_modules/folds')) return 'folds';
|
||||
if (id.includes('node_modules/emojibase')) return 'emojibase';
|
||||
// HTML sanitising (sanitize-html pulls in postcss + htmlparser2) and colour
|
||||
// maths are needed at startup but are big, stable libraries: keep them in
|
||||
// their own cacheable chunks instead of wherever the chunk graph drops them
|
||||
// (once Settings became lazy they landed in the entry chunk).
|
||||
if (
|
||||
id.includes('node_modules/sanitize-html') ||
|
||||
id.includes('node_modules/postcss') ||
|
||||
id.includes('node_modules/htmlparser2') ||
|
||||
id.includes('node_modules/domhandler') ||
|
||||
id.includes('node_modules/domutils') ||
|
||||
id.includes('node_modules/dom-serializer') ||
|
||||
id.includes('node_modules/entities') ||
|
||||
id.includes('node_modules/parse-srcset') ||
|
||||
id.includes('node_modules/nanoid') ||
|
||||
id.includes('node_modules/picocolors') ||
|
||||
id.includes('node_modules/source-map-js')
|
||||
)
|
||||
return 'sanitize-html';
|
||||
if (id.includes('node_modules/chroma-js')) return 'chroma';
|
||||
};
|
||||
|
||||
export default defineConfig({
|
||||
|
||||
Reference in New Issue
Block a user