TypeScript, React, Sass, Naver Cloud Platform (NCP)
프론트엔드
6주
일반적인 SNS와 반대로 사용자의 피드에 다른사람들이 사진과 글을 작성해줄 수 있는 사진중심 SNS입니다.
사용자는 피드의 공개일을 설정할 수 있습니다.
그 전까지는 게시물을 볼 수 없고, 썸네일을 픽셀화 시켜 사용자에게 공개일을 기다리는 재미 선사합니다.
프로젝트의 지향점은 대용량 트래픽을 경험하는것이었고,
이를 위해 FE 담당으로서 프론트엔드 성능개선, 이미지 최적화에 관심을 가졌습니다.
관련문서 :
Image Optimizer를 통한 반응형 최적화를 진행해보자!
초기 로드속도 향상을 위해 LQIP(Low Quality Image Placeholder) 기법을 사용했습니다.
원본 이미지에 비해 용량이 작은 이미지로 먼저 화면을 구성한 후, 원본 이미지로 교체하는 기법을 사용했습니다.
원본 이미지에 비해 확연하게 빠른 속도로 화면을 구성하기 때문에 UX를 개선할 수 있었습니다.
자체적으로 고안한 lazy loading 알고리즘을 사용했습니다.
사용자가 캐러셀의 페이지를 넘겨 n번째 이미지를 볼 때, n+2번째 이미지가 저화질인지 체크하고, 만약 저화질이라면 src를 원본화질로 전환합니다.
[useEffect를 활용한 lazy loading 코드]
useEffect(() => {
if (page + 2 < imageStatus.length && imageStatus[page + 2].isLq === true) {
setImageStatus((imageStatus) => {
const newImageStatus = [...imageStatus]
const target = newImageStatus[page + 2]
target.isLq = false
target.src = getPostingThumbUrl(target.url!)
newImageStatus[page + 2] = target
return newImageStatus
})
}
}, [page])
원본 이미지를 개선하기 위해 화면의 크기를 감지하고, 그에 맞는 이미지를 호출합니다.
NCP의 ImageOptimizer를 활용해 환경에 맞는 사이즈의 이미지를 로드하도록 개선했습니다.
하나의 이미지로만 대응하던 기존대비 1/100 의 이미지 로드 속도 개선, 서버 비용 감소를 이뤄냈습니다.
[화면크기를 감지하고 그에 맞는 이미지 URL을 생성하는 코드]
export const getthumbUrl = (url: string) => {
return `${url}${getQueryString(true)}`
}
export const getoriginalUrl = (url: string) => {
return `${url}${getQueryString(false)}`
}
const getQueryString = (isLq: boolean) => {
const windowWidth = window.innerWidth
const size = isLq ? getThumbSize(windowWidth) : getOriginalSize(windowWidth)
return `?type=m&w=${size}&h=${size}`
}
const getOriginalSize = (widdowWidth: number) => {
const level = Math.floor(widdowWidth / 100)
if (level >= 5) return 500
if (level >= 4) return 400
return 300
}
const getThumbSize = (widdowWidth: number) => {
const level = Math.floor(widdowWidth / 100)
if (level >= 5) return 50
if (level >= 4) return 40
return 30
}