@@ -9,15 +9,25 @@ import { useAPI } from "../../../providers/ApiProvider";
9
9
10
10
const configClass = cn ( "configure" ) ;
11
11
12
- const loadDependencies = async ( ) => import ( "@humansignal/editor" ) ;
12
+ // Lazy load Label Studio with a single promise to avoid multiple loads
13
+ // and enable as early as possible to load the dependencies once this component is mounted for the first time
14
+ let dependencies ;
15
+ const loadDependencies = async ( ) => {
16
+ if ( ! dependencies ) {
17
+ dependencies = import ( "@humansignal/editor" ) ;
18
+ }
19
+ return dependencies ;
20
+ } ;
13
21
14
22
export const Preview = ( { config, data, error, loading, project } ) => {
23
+ // @see comment about dependencies above
24
+ loadDependencies ( ) ;
25
+
26
+ const [ storeReady , setStoreReady ] = useState ( false ) ;
15
27
const lsf = useRef ( null ) ;
16
- const resolvingEditor = useMemo ( loadDependencies ) ;
17
28
const rootRef = useRef ( ) ;
18
- const projectRef = useRef ( project ) ;
19
29
const api = useAPI ( ) ;
20
-
30
+ const projectRef = useRef ( project ) ;
21
31
projectRef . current = project ;
22
32
23
33
const currentTask = useMemo ( ( ) => {
@@ -53,12 +63,14 @@ export const Preview = ({ config, data, error, loading, project }) => {
53
63
} , [ config ] ) ;
54
64
55
65
const initLabelStudio = useCallback ( async ( config , task ) => {
56
- if ( ! task . data ) return ;
66
+ // wait for dependencies to load, the promise is resolved only once
67
+ // and is started when the component is mounted for the first time
68
+ await loadDependencies ( ) ;
57
69
58
- await resolvingEditor ;
70
+ if ( lsf . current || ! task . data ) return ;
59
71
60
72
try {
61
- const lsf = new window . LabelStudio ( rootRef . current , {
73
+ lsf . current = new window . LabelStudio ( rootRef . current , {
62
74
config,
63
75
task,
64
76
interfaces : [ "side-column" ] ,
@@ -71,6 +83,7 @@ export const Preview = ({ config, data, error, loading, project }) => {
71
83
const c = as . createAnnotation ( ) ;
72
84
73
85
as . selectAnnotation ( c . id ) ;
86
+ setStoreReady ( true ) ;
74
87
} ;
75
88
76
89
if ( isFF ( FF_DEV_3617 ) ) {
@@ -82,12 +95,9 @@ export const Preview = ({ config, data, error, loading, project }) => {
82
95
} ,
83
96
} ) ;
84
97
85
- lsf . on ( "presignUrlForProject" , onPresignUrlForProject ) ;
86
-
87
- return lsf ;
98
+ lsf . current . on ( "presignUrlForProject" , onPresignUrlForProject ) ;
88
99
} catch ( err ) {
89
100
console . error ( err ) ;
90
- return null ;
91
101
}
92
102
} , [ ] ) ;
93
103
@@ -99,45 +109,30 @@ export const Preview = ({ config, data, error, loading, project }) => {
99
109
} , [ loading , error ] ) ;
100
110
101
111
useEffect ( ( ) => {
102
- if ( ! lsf . current ) {
103
- initLabelStudio ( currentConfig , currentTask ) . then ( ( ls ) => {
104
- lsf . current = ls ;
105
- } ) ;
106
- }
107
- } , [ currentConfig , currentTask ] ) ;
108
-
109
- useEffect ( ( ) => {
110
- if ( lsf . current ?. store ) {
111
- lsf . current . store . assignConfig ( currentConfig ) ;
112
- console . log ( "LSF config updated" ) ;
113
- }
114
- } , [ currentConfig ] ) ;
115
-
116
- useEffect ( ( ) => {
117
- if ( lsf . current ?. store ) {
118
- const store = lsf . current . store ;
112
+ initLabelStudio ( currentConfig , currentTask ) . then ( ( ) => {
113
+ if ( storeReady && lsf . current ?. store ) {
114
+ const store = lsf . current . store ;
119
115
120
- store . resetState ( ) ;
121
- store . assignTask ( currentTask ) ;
122
- store . initializeStore ( currentTask ) ;
116
+ store . resetState ( ) ;
117
+ store . assignTask ( currentTask ) ;
118
+ store . assignConfig ( currentConfig ) ;
119
+ store . initializeStore ( currentTask ) ;
123
120
124
- const c = store . annotationStore . addAnnotation ( {
125
- userGenerate : true ,
126
- } ) ;
121
+ const c = store . annotationStore . addAnnotation ( {
122
+ userGenerate : true ,
123
+ } ) ;
127
124
128
- store . annotationStore . selectAnnotation ( c . id ) ;
129
- console . log ( "LSF task updated" ) ;
130
- }
131
- } , [ currentTask ] ) ;
125
+ store . annotationStore . selectAnnotation ( c . id ) ;
126
+ console . log ( "LSF updated" ) ;
127
+ }
128
+ } ) ;
129
+ } , [ currentConfig , currentTask , storeReady ] ) ;
132
130
133
131
useEffect ( ( ) => {
134
132
return ( ) => {
135
133
if ( lsf . current ) {
136
134
console . info ( "Destroying LSF" ) ;
137
- // there can be weird error from LSF, but we can just skip it for now
138
- try {
139
- lsf . current . destroy ( ) ;
140
- } catch ( e ) { }
135
+ lsf . current . destroy ( ) ;
141
136
lsf . current = null ;
142
137
}
143
138
} ;
0 commit comments