@@ -107,11 +107,32 @@ function useFitText( { fitText, name, clientId } ) {
107107 return ;
108108 }
109109
110- // Apply initially
111- applyFitText ( ) ;
112-
113110 // Store current element value for cleanup
114111 const currentElement = blockElement ;
112+ const previousVisibility = currentElement . style . visibility ;
113+
114+ // Store IDs for cleanup
115+ let hideFrameId = null ;
116+ let calculateFrameId = null ;
117+ let showTimeoutId = null ;
118+
119+ // We are hiding the element doing the calculation of fit text
120+ // and then showing it again to avoid the user noticing a flash of potentially
121+ // big fitText while the binary search is happening.
122+ hideFrameId = window . requestAnimationFrame ( ( ) => {
123+ currentElement . style . visibility = 'hidden' ;
124+ // Wait for browser to render the hidden state
125+ calculateFrameId = window . requestAnimationFrame ( ( ) => {
126+ applyFitText ( ) ;
127+
128+ // Using a timeout instead of requestAnimationFrame, because
129+ // with requestAnimationFrame a flash of very high size
130+ // can still occur although rare.
131+ showTimeoutId = setTimeout ( ( ) => {
132+ currentElement . style . visibility = previousVisibility ;
133+ } , 10 ) ;
134+ } ) ;
135+ } ) ;
115136
116137 // Watch for size changes
117138 let resizeObserver ;
@@ -122,6 +143,17 @@ function useFitText( { fitText, name, clientId } ) {
122143
123144 // Cleanup function
124145 return ( ) => {
146+ // Cancel pending async operations
147+ if ( hideFrameId !== null ) {
148+ window . cancelAnimationFrame ( hideFrameId ) ;
149+ }
150+ if ( calculateFrameId !== null ) {
151+ window . cancelAnimationFrame ( calculateFrameId ) ;
152+ }
153+ if ( showTimeoutId !== null ) {
154+ clearTimeout ( showTimeoutId ) ;
155+ }
156+
125157 if ( resizeObserver ) {
126158 resizeObserver . disconnect ( ) ;
127159 }
0 commit comments