1
1
'use client'
2
2
3
- import { forwardRef , memo , useCallback , useMemo , useRef , useState } from 'react'
3
+ import {
4
+ cloneElement ,
5
+ forwardRef ,
6
+ memo ,
7
+ useCallback ,
8
+ useImperativeHandle ,
9
+ useMemo ,
10
+ useRef ,
11
+ useState ,
12
+ } from 'react'
4
13
import clsx from 'clsx'
5
14
import { useIsomorphicLayoutEffect } from 'foxact/use-isomorphic-layout-effect'
6
15
import mediumZoom from 'medium-zoom'
@@ -296,14 +305,31 @@ const OptimizedImage = memo(
296
305
const { height, width } = useMarkdownImageRecord ( src ! ) || rest
297
306
const hasDim = ! ! ( height && width )
298
307
308
+ const placeholderImageRef = useRef < HTMLImageElement > ( null )
299
309
const ImageEl = (
300
- < img data-zoom-src = { src } alt = { alt } src = { src } ref = { ref } { ...rest } />
310
+ < img
311
+ data-zoom-src = { src }
312
+ alt = { alt }
313
+ src = { src }
314
+ ref = { placeholderImageRef }
315
+ { ...rest }
316
+ />
301
317
)
318
+
319
+ useImperativeHandle ( ref , ( ) => placeholderImageRef . current ! )
320
+
321
+ const optimizedImageRef = useRef < HTMLImageElement > ( null )
322
+
323
+ useIsomorphicLayoutEffect ( ( ) => {
324
+ const $renderImage = optimizedImageRef . current
325
+ if ( ! $renderImage ) return
326
+ if ( ! placeholderImageRef . current ) return
327
+ placeholderImageRef . current . src = $renderImage . src
328
+ } , [ src ] )
302
329
return (
303
330
< >
304
331
{ hasDim ? (
305
332
< >
306
- { /* @ts -expect-error */ }
307
333
< Image
308
334
alt = { alt || '' }
309
335
fetchPriority = "high"
@@ -312,9 +338,12 @@ const OptimizedImage = memo(
312
338
{ ...rest }
313
339
height = { + height }
314
340
width = { + width }
341
+ ref = { optimizedImageRef }
315
342
/>
316
343
< div className = "absolute inset-0 flex justify-center opacity-0" >
317
- { ImageEl }
344
+ { cloneElement ( ImageEl , {
345
+ src : 'data:image/gif;base64,R0lGODlhAQABAIAAAAAAAP///yH5BAEAAAAALAAAAAABAAEAAAIBRAA7' , // blank src
346
+ } ) }
318
347
</ div >
319
348
</ >
320
349
) : (
0 commit comments