add more dynamic imports to optimize bundle

This commit is contained in:
jeffvli
2026-01-17 07:32:16 -08:00
parent 6cb5c95c1f
commit ef5daad1dd
20 changed files with 529 additions and 163 deletions
@@ -8,7 +8,7 @@ import { usePlayerEvents } from '/@/renderer/features/player/audio-player/hooks/
import { getSongUrl } from '/@/renderer/features/player/audio-player/hooks/use-stream-url';
import { AudioPlayer, PlayerOnProgressProps } from '/@/renderer/features/player/audio-player/types';
import { useRadioStore } from '/@/renderer/features/radio/hooks/use-radio-player';
import { getMpvProperties } from '/@/renderer/features/settings/components/playback/mpv-settings';
import { getMpvProperties } from '/@/renderer/features/settings/components/playback/mpv-properties';
import {
usePlaybackSettings,
usePlayerActions,
@@ -1,7 +1,7 @@
import type { RefObject } from 'react';
import type ReactPlayer from 'react-player';
import { useCallback, useEffect, useImperativeHandle, useRef, useState } from 'react';
import ReactPlayer from 'react-player';
import { AudioPlayer, PlayerOnProgressProps } from '/@/renderer/features/player/audio-player/types';
import { convertToLogVolume } from '/@/renderer/features/player/audio-player/utils/player-utils';
@@ -69,6 +69,31 @@ export const WebPlayerEngine = (props: WebPlayerEngineProps) => {
const player1Ref = useRef<null | ReactPlayer>(null);
const player2Ref = useRef<null | ReactPlayer>(null);
const [ReactPlayerComponent, setReactPlayerComponent] = useState<any>(null);
const [isLoading, setIsLoading] = useState(true);
useEffect(() => {
let isMounted = true;
const loadReactPlayer = async () => {
try {
const module = await import('react-player');
if (isMounted) {
setReactPlayerComponent(() => module.default);
setIsLoading(false);
}
} catch (error) {
console.error('Failed to load react-player:', error);
setIsLoading(false);
}
};
loadReactPlayer();
return () => {
isMounted = false;
};
}, []);
const [internalVolume1, setInternalVolume1] = useState(volume / 100 || 0);
const [internalVolume2, setInternalVolume2] = useState(volume / 100 || 0);
@@ -184,9 +209,13 @@ export const WebPlayerEngine = (props: WebPlayerEngineProps) => {
[onStartedPlayer2, preservesPitch],
);
if (isLoading || !ReactPlayerComponent) {
return <div id="web-player-engine" style={{ display: 'none' }} />;
}
return (
<div id="web-player-engine" style={{ display: 'none' }}>
<ReactPlayer
<ReactPlayerComponent
config={{
file: { attributes: { crossOrigin: 'anonymous' }, forceAudio: true },
}}
@@ -206,7 +235,7 @@ export const WebPlayerEngine = (props: WebPlayerEngineProps) => {
volume={volume1}
width={0}
/>
<ReactPlayer
<ReactPlayerComponent
config={{
file: { attributes: { crossOrigin: 'anonymous' }, forceAudio: true },
}}
@@ -1,16 +1,22 @@
import formatDuration from 'format-duration';
import { memo } from 'react';
import { lazy, memo, Suspense } from 'react';
import styles from './mobile-fullscreen-player.module.css';
import { PlayerbarSeekSlider } from '/@/renderer/features/player/components/playerbar-seek-slider';
import { PlayerbarWaveform } from '/@/renderer/features/player/components/playerbar-waveform';
import { usePlayerTimestamp } from '/@/renderer/store';
import { PlayerbarSliderType, usePlayerbarSlider } from '/@/renderer/store/settings.store';
import { Spinner } from '/@/shared/components/spinner/spinner';
import { Text } from '/@/shared/components/text/text';
import { PlaybackSelectors } from '/@/shared/constants/playback-selectors';
import { QueueSong } from '/@/shared/types/domain-types';
const PlayerbarWaveform = lazy(() =>
import('/@/renderer/features/player/components/playerbar-waveform').then((module) => ({
default: module.PlayerbarWaveform,
})),
);
interface MobileFullscreenPlayerProgressProps {
currentSong?: QueueSong;
}
@@ -38,7 +44,9 @@ export const MobileFullscreenPlayerProgress = memo(
</div>
<div className={styles.sliderWrapper}>
{isWaveform ? (
<PlayerbarWaveform />
<Suspense fallback={<Spinner />}>
<PlayerbarWaveform />
</Suspense>
) : (
<PlayerbarSeekSlider max={songDuration} min={0} />
)}
@@ -1,8 +1,8 @@
import formatDuration from 'format-duration';
import { lazy, Suspense } from 'react';
import { PlayerbarSeekSlider } from './playerbar-seek-slider';
import styles from './playerbar-slider.module.css';
import { PlayerbarWaveform } from './playerbar-waveform';
import { useRemote } from '/@/renderer/features/remote/hooks/use-remote';
import {
@@ -13,9 +13,16 @@ import {
} from '/@/renderer/store';
import { PlayerbarSliderType, usePlayerbarSlider } from '/@/renderer/store/settings.store';
import { Slider, SliderProps } from '/@/shared/components/slider/slider';
import { Spinner } from '/@/shared/components/spinner/spinner';
import { Text } from '/@/shared/components/text/text';
import { PlaybackSelectors } from '/@/shared/constants/playback-selectors';
const PlayerbarWaveform = lazy(() =>
import('./playerbar-waveform').then((module) => ({
default: module.PlayerbarWaveform,
})),
);
export const PlayerbarSlider = () => {
const currentSong = usePlayerSong();
const playerbarSlider = usePlayerbarSlider();
@@ -51,7 +58,9 @@ export const PlayerbarSlider = () => {
</div>
<div className={styles.sliderWrapper}>
{isWaveform ? (
<PlayerbarWaveform />
<Suspense fallback={<Spinner />}>
<PlayerbarWaveform />
</Suspense>
) : (
<PlayerbarSeekSlider max={songDuration} min={0} />
)}
@@ -1,13 +1,19 @@
import clsx from 'clsx';
import { MouseEvent } from 'react';
import { lazy, MouseEvent, Suspense } from 'react';
import styles from './playerbar.module.css';
import { CenterControls } from '/@/renderer/features/player/components/center-controls';
import { LeftControls } from '/@/renderer/features/player/components/left-controls';
import { MobilePlayerbar } from '/@/renderer/features/player/components/mobile-playerbar';
import { RightControls } from '/@/renderer/features/player/components/right-controls';
import { useIsMobile } from '/@/renderer/hooks/use-is-mobile';
import { Spinner } from '/@/shared/components/spinner/spinner';
const MobilePlayerbar = lazy(() =>
import('./mobile-playerbar').then((module) => ({
default: module.MobilePlayerbar,
})),
);
import { useFullScreenPlayerStore, useSetFullScreenPlayerStore } from '/@/renderer/store';
import { usePlayerbarOpenDrawer } from '/@/renderer/store';
import { PlaybackSelectors } from '/@/shared/constants/playback-selectors';
@@ -24,7 +30,11 @@ export const Playerbar = () => {
};
if (isMobile) {
return <MobilePlayerbar />;
return (
<Suspense fallback={<Spinner />}>
<MobilePlayerbar />
</Suspense>
);
}
return (