NextJS Image组件在iOS16初始不可见时无法渲染的原因排查
解决方案
1. 强制图片立即加载
显式设置loading="eager",跳过Next.js的懒加载逻辑:
<Image className={styles.productImg} src={props.data.imgSmall} width={160} height={160} alt={props.data.name} loading="eager" unoptimized={true} />
2. 滚动事件触发组件重绘
监听滚动容器的滚动事件,通过更新组件key触发重绘,强制Safari渲染图片:
import { useEffect, useState } from 'react'; import styles from "../styles/ProductItem.module.css"; import priceFormat from "../Helpers/priceFormat"; import Image from "next/image"; import Percentage from "./icons/Percentage"; import { useRouter } from "next/router"; function ProductItem(props) { const router = useRouter(); const [scrollKey, setScrollKey] = useState(0); useEffect(() => { const scrollContainer = document.querySelector('.你的水平滚动容器类名'); if (!scrollContainer) return; const handleScroll = () => setScrollKey(prev => prev + 1); scrollContainer.addEventListener('scroll', handleScroll); return () => scrollContainer.removeEventListener('scroll', handleScroll); }, []); let marginStyle = {}; if (props.noLeftMargin) marginStyle.marginLeft = 0; if (props.noRightMargin) marginStyle.marginRight = 0; return ( <div className={`${styles.itemContainer} ${props.className}`} style={marginStyle} onClick={() => router.push("/product/" + props.data.id)} key={`product-${props.data.id}-${scrollKey}`} > <div className={styles.imageContainer}> <Image className={styles.productImg} src={props.data.imgSmall} width={160} height={160} alt={props.data.name} unoptimized={true} /> {props.data.salePercentage > 0 && ( <div className={styles.percentageContainer}> <Percentage className={styles.percentageSvg} /> <div className={styles.percentageOffText}> {`%${props.data.salePercentage}`} <br /> OFF </div> </div> )} </div> <div className={styles.priceLabel}> {props.data.salePercentage ? `$${priceFormat( props.data.price * ((100 - props.data.salePercentage) / 100) )}` : `$${priceFormat(props.data.price)}`} </div> {props.data.salePercentage > 0 && ( <div className={styles.oldPrice}>{`$${priceFormat( props.data.price )}`}</div> )} <div className={styles.productName}> {props.data.brand} {props.data.name} </div> </div> ); } export default ProductItem;
3. 临时替换为原生img标签
如果Next.js Image组件的优化逻辑与Safari冲突,可暂时用原生img标签验证:
<img className={styles.productImg} src={props.data.imgSmall} width={160} height={160} alt={props.data.name} loading="eager" />
4. 调整滚动容器CSS属性
添加CSS属性触发Safari硬件加速,避免渲染优化限制:
.你的水平滚动容器类名 { -webkit-transform: translateZ(0); transform: translateZ(0); backface-visibility: hidden; }
内容的提问来源于stack exchange,提问作者Etohimself
相关产品推荐
相关产品推荐

