I opted to implement NextJS for enhanced routing capabilities and image optimization. However, I encountered an issue with certain images failing to load properly on iOS devices. The problem arises within a scrollable horizontal container featuring Product Images.
Some of the images extend beyond the visible area, requiring scrolling to view them.
While everything functions smoothly on web browsers, testing it on Safari on my iPhone (iOS 16) revealed that images outside the visible area remain unrendered. Let me illustrate this further.
Expected result in Chrome Device Tool:
Actual outcome experienced on iOS 16:
An interesting observation is that rotating the phone triggers the rendering of the images.
My implementation involves using the Image/Next component with priority and unoptimized props set to true. I have experimented with both configurations but saw no improvement.
The frontend utilizes the latest version of NextJS exclusively, without additional libraries. The backend consists of an express server solely responsible for providing image pathways. This server operates with Nginx and reverse proxy settings.
This is the provided React code snippet:
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();
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)}
>
<div className={styles.imageContainer}>
<Image
className={styles.productImg}
src={props.data.imgSmall}
width={160}
height={160}
alt={props.data.name}
priority={true}
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;
Below is the {data}
data structure provided via props:
{
id: "ca629a01-7c58-49f1-949e-fad574c28b3e",
imgLarge: "/images/products/electronics_smartphone_1.jpg",
imgSmall: "/images/products/electronics_smartphone_1_small.jpg",
brand: "Chip",
options: [
{
name: "Storage",
values: ["64GB", "128GB", "256GB"],
affectsPrice: 1,
},
{
name: "Color",
values: ["black", "white", "gray", "red", "gold", "silver"],
affectsPrice: 0,
},
],
name: "Smartphone",
price: 684,
salePercentage: 0,
saleReason: "",
viewCount: 10438,
soldCount: 4706,
maincategory: "electronics",
rating: "3.60",
warranty: 2,
availableColors: ["silver", "gold", "red", "white"],
subcategory: "electronics_smartphone",
sellers: [....]
}
To test the application, visit: Ertuway.com