Skip to content

Commit

Permalink
perf: optimize image rendering
Browse files Browse the repository at this point in the history
  • Loading branch information
WX-DongXing committed Nov 28, 2024
1 parent c39bdd2 commit 228558d
Showing 1 changed file with 74 additions and 25 deletions.
99 changes: 74 additions & 25 deletions packages/webpack-plugin/lib/runtime/components/react/mpx-image.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ import {
DimensionValue,
ImageLoadEventData
} from 'react-native'
import { noop } from '@mpxjs/utils'
import { SvgCssUri } from 'react-native-svg/css'
import useInnerProps, { getCustomEvent } from './getInnerListeners'
import useNodesRef, { HandlerRef } from './useNodesRef'
Expand Down Expand Up @@ -58,6 +59,14 @@ export interface ImageProps {
binderror?: (evt: NativeSyntheticEvent<ImageErrorEventData> | unknown) => void
}

interface ImageState {
viewWidth?: number
viewHeight?: number
imageWidth?: number
imageHeight?: number
ratio?: number
}

const DEFAULT_IMAGE_WIDTH = 320
const DEFAULT_IMAGE_HEIGHT = 240

Expand Down Expand Up @@ -118,34 +127,54 @@ const Image = forwardRef<HandlerRef<RNImage, ImageProps>, ImageProps>((props, re
overflow: 'hidden'
}

const state = useRef<ImageState>({})

const nodeRef = useRef(null)
useNodesRef(props, ref, nodeRef, {
defaultStyle
})

const isSvg = SVG_REGEXP.test(src)
const isWidthFixMode = mode === 'widthFix'
const isHeightFixMode = mode === 'heightFix'
const isCropMode = cropMode.includes(mode)
const isLayoutMode = isWidthFixMode || isHeightFixMode || isCropMode
const resizeMode: ImageResizeMode = ModeMap.get(mode) || 'stretch'

const onLayout = ({ nativeEvent: { layout: { width, height } } }: LayoutChangeEvent) => {
setViewWidth(width)
setViewHeight(height)
state.current.viewWidth = width
state.current.viewHeight = height

if (state.current.imageWidth && state.current.imageHeight && state.current.ratio) {
setViewWidth(width)
setViewHeight(height)
setRatio(state.current.ratio)
setImageWidth(state.current.imageWidth)
setImageHeight(state.current.imageHeight)
state.current = {}
setLoaded(true)
}
}

const { normalStyle, hasSelfPercent, setWidth, setHeight } = useTransformStyle(styleObj, { enableVar, externalVarContext, parentFontSize, parentWidth, parentHeight })

const { layoutRef, layoutStyle, layoutProps } = useLayout({ props, hasSelfPercent, setWidth, setHeight, nodeRef, onLayout })
const { layoutRef, layoutStyle, layoutProps } = useLayout({
props,
hasSelfPercent,
setWidth,
setHeight,
nodeRef,
onLayout: isLayoutMode ? onLayout : noop
})

const { width, height } = normalStyle

const isSvg = SVG_REGEXP.test(src)
const isWidthFixMode = mode === 'widthFix'
const isHeightFixMode = mode === 'heightFix'
const isCropMode = cropMode.includes(mode)
const isLayoutMode = isWidthFixMode || isHeightFixMode || isCropMode
const resizeMode: ImageResizeMode = ModeMap.get(mode) || 'stretch'

const [viewWidth, setViewWidth] = useState(isNumber(width) ? width : 0)
const [viewHeight, setViewHeight] = useState(isNumber(height) ? height : 0)
const [imageWidth, setImageWidth] = useState(0)
const [imageHeight, setImageHeight] = useState(0)
const [ratio, setRatio] = useState(0)
const [loaded, setLoaded] = useState(!isLayoutMode)

const fixedHeight = useMemo(() => {
const fixed = viewWidth * ratio
Expand Down Expand Up @@ -325,9 +354,19 @@ const Image = forwardRef<HandlerRef<RNImage, ImageProps>, ImageProps>((props, re
useEffect(() => {
if (!isSvg && isLayoutMode) {
RNImage.getSize(src, (width: number, height: number) => {
setRatio(!width ? 0 : height / width)
setImageWidth(width)
setImageHeight(height)
state.current.imageWidth = width
state.current.imageHeight = height
state.current.ratio = !width ? 0 : height / width

if (state.current.viewWidth && state.current.viewHeight) {
setViewWidth(state.current.viewWidth)
setViewHeight(state.current.viewHeight)
setRatio(!width ? 0 : height / width)
setImageWidth(width)
setImageHeight(height)
state.current = {}
setLoaded(true)
}
})
}
}, [src, isSvg, isLayoutMode])
Expand All @@ -350,6 +389,16 @@ const Image = forwardRef<HandlerRef<RNImage, ImageProps>, ImageProps>((props, re
}
)

function renderImage (
imageProps: any,
enableFastImage = false
) {
const Component: React.ComponentType<any> = enableFastImage ? RNImage : RNImage
return <Component {...imageProps} />
}

console.log('render: ')

return (
<View {...innerProps}>
{
Expand All @@ -363,18 +412,18 @@ const Image = forwardRef<HandlerRef<RNImage, ImageProps>, ImageProps>((props, re
...modeStyle
}}
/>
: <RNImage
source={{ uri: src }}
resizeMode={resizeMode}
onLoad={bindload && onImageLoad}
onError={binderror && onImageError}
style={{
transformOrigin: 'top left',
width: isCropMode ? imageWidth : '100%',
height: isCropMode ? imageHeight : '100%',
...(isCropMode && modeStyle)
}}
/>
: loaded && renderImage({
source: { uri: src },
resizeMode: resizeMode,
onLoad: bindload && onImageLoad,
onError: binderror && onImageError,
style: {
transformOrigin: 'top left',
width: isCropMode ? imageWidth : '100%',
height: isCropMode ? imageHeight : '100%',
...(isCropMode && modeStyle)
}
})
}
</View>
)
Expand Down

0 comments on commit 228558d

Please sign in to comment.