📌 문제상황
// 실제 코드는 부가적인 기능으로 코드가 복잡하여 최대한 간소화한 코드를 예시로 사용했다
<div className="grid grid-cols-3">
{[1, 2, 3].map((_) => (
<div>
<img className="w-full aspect-square object-cover" />
<p>이름</p>
<p>가격</p>
</div>
))}
</div>;
- Grid 배치로 크기를 자동으로 설정한 grid 아이템 이미지의 로딩 전후로 리플로우 발생 이슈 발견
- w-full 과 aspect-square로 높이와 너비 비율을 설정했다고 생각했기 때문에 리플로우 없이 로딩 될 것이라 생각했지만, 예상과는 다른 동작 결과를 보임
📌 원인 분석
=> aspect ratio을 1:1로 세팅해둔 것이 높이를 설정한 것이라 생각한 게 문제
- 높이가 명시적으로 정해진 것이 아니기 때문에 브라우저는 이미지를 로드하기 전까지 높이를 정확하게 알 수 없음. 즉, 이미지 로드 후에만 높이를 조정할 수 있음
- 그래서 비율을 1:1로 잡아놨다고 하더라도 비율 계산을 할 수가 없게 됨
📌 해결 방법 고민
방법1 ) 명시적 이미지 크기 설정
- grid minmax를 활용하여 min-width를 설정
- 이미지 크기를 명시적으로 나타내는 효과를 냄
= > 한계 : 리플로우가 적어지긴 했지만 여전히 발생하고, 이미지의 비율도 무너지게 됨
방법 2) 이미지 로드 전까지 스켈레톤 UI 사용
- 초기값이 true인 로딩 state를 만들고 로딩 완료된 후 값이 false로 되도록 이미지 onLoad 핸들러에 등록
- 로딩값이 true인 동안 스켈레톤 UI 대체
=> 한계 : grid 아이템마다 state를 생성해야 하므로 렌더링 성능 저하 고려
방법 3) 별도의 이미지 컨테이너로 레이아웃 미리 설정
과정 : 이미지를 div태그로 감싸 이미지가 로드 되기 전 먼저 레이아웃 고정
=> ✅ 선택
📌 문제 해결
이미지가 로딩 되기 전까지 컨테이너가 미리 공간을 차지하고 있어서 리플로우가 더이상 발생하지 않는 것을 확인하였다.
<div className="grid grid-cols-3">
{[1, 2, 3].map((_) => (
<div>
<div className="w-full aspect-square">
<img className="w-full h-full object-cover" />
</div>
<p>이름</p>
<p>가격</p>
</div>
))}
</div>;
'Tech > ReactJS' 카테고리의 다른 글
상세 상품 prefetch로 인한 불필요한 네트워크 요청 해결 (0) | 2024.05.20 |
---|---|
컴파운드 컴포넌트로 재사용성과 가독성 높이기 (0) | 2024.05.09 |
결제 후 장바구니 속 아이템이 삭제되었다가 재생성되는 이슈 (0) | 2024.04.29 |
비동기적으로 동작하지만 비동기 함수는 아닌 setState (0) | 2024.04.13 |
외부 클릭 시 연관 검색어 창 닫기 : addEventListener 사용 (0) | 2024.03.29 |