remotion-dev / remotion

🎥 Make videos programmatically with React
https://remotion.dev
Other
19.58k stars 952 forks source link

React.lazy not suppoting to import remotion compositions into remotion player #4019

Closed ursnj closed 1 week ago

ursnj commented 1 week ago

React.lazy not suppoting to import remotion compositions into remotion player

Bug Report 🐛

Uncaught Error: Element type is invalid. Received a promise that resolves to: [object Object]. Lazy element type must resolve to a class or function. Did you wrap a component in React.lazy() more than once? at mountLazyComponent (

Reason for importing compositions lazy is because when im building composition resources are bundling and downloading all at once so causing performance issues. if i load them lazily only one composistion resources downloaded once.

JonnyBurger commented 1 week ago

Indeed we already wrap the component in React.lazy for you.

Does that help?

ursnj commented 1 week ago

when i create a bundle with compositions in my application its bundling all the code and assets in single file thats keep on increasing when a add more compositions.

is there any way that i can add my own react.lazy logic ???

JonnyBurger commented 1 week ago

I see you are looking for lazyComponent:

<Composition
                    id="looped"
                    lazyComponent={() => import('./LoopedVideo')}
                    durationInFrames={200}
                    fps={60}
                    height={1080}
                    width={1080}
                />

LoopedVideo must export a component as default export

ursnj commented 1 week ago

i think this is at remotion studio root code, im trying to import compositions into my website and render them in my website with remotion player like :

import {lazy, Suspense, useMemo} from 'react';
import {NLoading} from 'nayan';
import { Player } from '@remotion/player';
import { useVideoStore } from '../../shared/stores/VideoStore';

const Composition = lazy(() => import('../../../remotion/compositions/sample/SampleComposition'));

interface Props {
  template: any;
}

const VideosPlayer = (props: Props) => {
  const { template } = props;
  const videoState = useVideoStore(state => state.video);

  return (
    <Suspense fallback={<NLoading />}>
      <Player
        fps={30}
        loop
        controls
        autoPlay={false}
        alwaysShowControls
        component={Composition}
        inputProps={videoState.data}
        className="max-w-full max-h-[300px] md:max-h-[calc(100vh_-_115px)]"
        durationInFrames={template.compositionDuration}
        compositionWidth={template.compositionWidth}
        compositionHeight={template.compositionHeight}
      />
    </Suspense>
  );
};

export default VideosPlayer;

Hope this helps!

JonnyBurger commented 1 week ago

You can also use lazyComponent in the player! Just remove the wrapping in lazy and use lazyComponent instead of component

ursnj commented 1 week ago

WOW Great, its working as expected, Thank you soo much for the quick help ^^