Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[Refactor] 소개페이지 상단 배너 로딩 속도 개선 #428

Merged
merged 3 commits into from
Sep 16, 2024

Conversation

lydiacho
Copy link
Member

@lydiacho lydiacho commented Sep 10, 2024

Summary

소개페이지의 상단 배너 로딩 속도가 너무 느렸어요
소개페이지의 가장 상단 콘텐츠이고 나름 메인 콘텐츠이기 때문에 개선이 시급한 친구라고 생각했습니다 !
(관련해서 아주 불편하다고 제보도 받았구요)
해결책 고민하는 시간은 길었지만 결론적으로 작업한 코드는 정말 별거 없습니다

  • s3에 업로드되어있는 이미지 사이즈 수정 및 webp로 변환
  • SSG 형식으로 불러오던 소개페이지 데이터를 ISR 형식으로 수정 (revalidate 간격 120초)
  • 상단 배너 element를 div 태그 -> next/image 컴포넌트로 수정

Screenshot

🪫 개선 전

image

image

🔋 개선 후

image image

LCP 3.5초 줄임으로써 Performance 지수를 약 20점 올릴 수 있었습니다 🤙🏻

Comment

🐽 s3에 업로드되어있는 이미지 사이즈 수정 및 webp로 변환

우선 아시다시피 소개페이지의 상단 배너는 저희가 로컬 이미지를 넣어주는 형태가 아니라 s3에 저장되어있는 이미지를 서버에서 받아와서 remote url을 src로 넣어주는 형태입니다
그런데 이 이미지 상태가 심각했어요

image

렌더되는 너비는 100vw여서 가장 커봤자 2000px보다 작을텐데
저 불러오는 원본 이미지 너비는 무려 16400px........파일 사이즈는 3.8MB.... 거의 100배에 달하게 큰 이미지를 받고 있더라구요
백엔드 개발자분이 피그마에서 이미지를 추출해갈때 화질 저하를 막기 위해 4배로 뽑아가신게 원인이었어요

이게 가장 치명적인 문제였기에
이미지 다시 리사이징하고 또 최적화를 위해 형식도 webp로 변환해서 백엔드분께 파일 변경을 부탁드렸습니다

이미지 리사이징은 너비 4000px로 했어요. 2000px로 하니까 기존 배너보다 확실히 화질 저하가 발생하더라구요
그래서 기존보다 최대한 화질 차이 안나는 선에서 최소한으로 줄인 크기가 4000px 였습니당

무튼 그렇게 리사이징 + webp 변환해서 3.8MB -> 288KB로 줄일 수 있었습니다

image

여기서 로딩 속도 개선 끝났다~ 싶었는데 별안간 이슈가 발생했어요

🐽 SSG 형식으로 불러오던 소개페이지 데이터를 ISR 형식으로 수정 (revalidate 간격 120초)

그 이슈는 ... 이미지 파일 갈아끼고 나서 데브 모드에서 빠르게 로딩되는거 확인하고 배포서버에도 반영해달라고 요청을 드렸는데
분명 서버에서는 이미지를 교체했는데 그게 저희 배포본에는 반영이 안되는거예요
브라우저 캐시 문제라고 생각해서 온갖 캐시 다 지우고 이 브라우저 저 브라우저에서 다 시도해보았는데 이미지는 절대 업데이트 되지 않았어요

image

그래서 네트워크 탭으로 SSG로 불러오고 잇는 about.json을 찾아보니
vercel cache에 HIT를 치고있더라고요?

즉, 제가 삽질하고 있던 브라우저 캐시가 아닌, SSG 사용으로 인한 vercel 캐시에 저장되어있던 친구였어요.

장황한 설명 생략하고 결론만 말씀드리면,
Vercel에 배포된 Next 배포본에서 SSG로 불러오는 데이터는 Vercel의 _next 캐시에 영구적으로 저장이 되어서,
이후 해당 캐시를 항상 사용한다고 하더라고요.
즉 재배포가 되기 전까지는 영구적으로 동일한 캐시데이터를 사용하게 되는거죠. (SSG의 효과가 바로 이 친구 덕분이겠죠?)

그런데 SSG의 강점을 위해 제공하는 이 기능은 딱봐도 한계점이 보이죠.
바로 제가 이번에 겪은 상황처럼 서버 데이터가 변경될 경우 이게 반영이 안된다는 점인데요,
그 한계를 개선하기 위해 next13버전에서 등장한게 ISR (Incremental Static Regeneration) 이라고 합니다

나랑 같은 니즈를 가진 사람의 호소문
Lee Robinson 씨의 ISR 소개

SSG의 장점은 최대한 가져가되, revalidate 주기를 지정해줘서 주기적으로 해당 데이터를 update 시켜줄 수 있는 방식입니다

따라서 이 revalidate 옵션을 2분으로 설정해줌으로써 SSG -> ISR 방식으로 수정해서
배포본(pnpm build -> ppm start)에서 갱신된 서버 데이터 잘 반영되는 것까지 확인했습니다!

궁금하실만한 부분 몇까지 더 첨언하자면

  • ❓왜하필 2분인가요?

    • 사실 소개페이지는 기존에 SSG를 썼던 만큼 잦은 업데이트가 전혀 불필요한 페이지예요. 다만 서버 데이터상의 변경이 생겼을 경우 이게 반영은 되어야 하니까 너무 긴 주기를 주고 싶진 않았고, 하지만 또 사용자가 접속하는 시간동안 서버 데이터가 바뀌는 일이 매우 드문건 사실이잖아요? 따라서 대부분의 경우에 사용자가 참여하는 한 세션 동안 새로이 revalidate 하면서 불필요한 서버 요청을 일으키는 것도 피하고 싶었어요. 그래서 GA로 사용자 체류시간을 봤는데 소개페이지는 평균 체류시간 약 50초, 전체 페이지 평균 체류 시간 약 1분 20초, 한달 내 최대 체류 시간 약 1분 50초 이길래 이보다 긴 2분으로 설정했습니다.
  • ❓근데 그럼 2분마다 데이터가 stale하게 된다면, 사용자가 새로 접속할 때마다 새로이 데이터를 불러오는건데 그럼 SSG의 효과가 떨어지는 것 아닌가?

    • 아니에요. SSG가 사용자 경험에 이득을 주는 부분은 미리 빌드해놓고 캐시에 저장되어있는 데이터를 해당 페이지 접속했을 때 딱 띄우기 때문에 빠르게 로드할 수 있다는 점인데요, ISR을 통해 stale한 데이터를 revalidate 해서 만약 데이터가 갱신되었을 경우, 사용자가 cache에서 MISS를 찍고 새로이 서버에서 데이터를 가져오게 되면 SSG의 장점이 훼손되겠죠? 그런데 그게 아니라! 갱신된 데이터는 백그라운드 상에서 _next 캐시 저장소에 반영되는 방식입니다. 즉 클라이언트 입장에서 사전에 빌드된 데이터를 _next 캐시에서 가져오는 것은 그대로고, revalidate은 백그라운드 상에서 진행되면서 캐시가 갱신되게 돼요.(즉 클라가 캐시를 MISS하는 케이스는 없는 것임) 따라서 사용자 경험 측면에서는 SSG나 ISR이나 모두 동일한 효과를 유지해요.

내용이 다소 두서없을 수 있을 것 같아요 🥵🥵🥵...
그리고 ISR에 대해 공유드리고 싶은 부분들이 더더 많이 남아있어서 아티클 완성되면 여기에 추가해놓겠습니다!!

🐽 상단 배너 element를 div 태그 -> next/image 컴포넌트로 수정

마지막 최적화 단계인데요,
이미지 리사이징을 했지만 화질저하 때문에 여전히 큰 이미지를 가져오고 있기 때문에
next/image 컴포넌트를 사용해서 한번 더 리사이징 및 최적화를 해주었어요.

기존에는 그냥 div 태그에 background-image로 삽입하는 형식으로 구현되어있더라구요?
그런데 상단배너는 이미지 위에 별도의 콘텐츠가 있는 것도 아니라서 기존의 background 방식을 유지할 필요가 없었어요

따라서 next/image 컴포넌트로 바꿔줌으로써 화면에 fit한 사이즈로 리사이징해주며 한단계 더 최적화해주었습니다

이렇게 해서 최종적으로 3.8MB로 들어오던 file size를 5.2kB까지 줄일 수 있게 되었어요 !


+) 노드 버전으로 인한 CI 에러 때문에 yml파일 수정해줬습니다

@lydiacho lydiacho self-assigned this Sep 10, 2024
Copy link

height bot commented Sep 10, 2024

Link Height tasks by mentioning a task ID in the pull request title or commit messages, or description and comments with the keyword link (e.g. "Link T-123").

💡Tip: You can also use "Close T-X" to automatically close a task when the pull request is merged.

@wuzoo
Copy link
Contributor

wuzoo commented Sep 10, 2024

먼저 궁금한 점은, 제가 아는 바에 의하면 SSG에서 revalidate와 같은 속성의 ISR을 사용하는 이유는, 결국에는 정적으로 페이지를 생성하였지만 빌드 프로세스에서 데이터를 가져오기 때문에, 받아오는 데이터의 최신화를 위해 특정 주기마다 revalidate하여 데이터를 새로 갈아끼기 위해 사용하는 것으로 알고 있어요.

그런데 사실 현재 상단 배너로 가져오는 이미지 url은 적어도 솝트의 한 기수동안은 변하지 않는 데이터이고, 아마도 ? 갈아껴주어야 하는 상황에서는 서버에서 s3 이미지 주소를 갈아끼워주는 방식인건데, revalidate가 현재 SSG로 렌더링하고 있는 소개페이지의 상단 배너에 그리 큰 영향이 있는지 궁금합니다 !

승희님이 Vercel에서 자동적으로 cache하는 것 때문에 결국 revalidate를 하셨다면, 찾아보니 vercel의 캐시 전략에서, 특정 데이터를 패칭하는 경우에만 cache를 비활성화하는 옵션도 있더라구요 !

결국 SSG를 통해 데이터 패칭을 하였고, 받아오는 데이터에서 가끔씩 최신화가 되지 않는 경우에 ISR을 사용하는 것으로 알고 있는데, 버셀의 캐시 전략에 의해서 revalidate 옵션을 사용하는 것보다 더 좋은 방향이 있지 않을까 ! 하는 생각으로 리뷰 남깁니다.

@wuzoo
Copy link
Contributor

wuzoo commented Sep 10, 2024

추가적으로 webp 이미지 포맷을 사용하게 된다면, 분명 오래된 버전의 브라우저에서는 호환 문제가 발생할 수 있을 것 같다는 생각이 들어요 !

제가 아는 바에 의하면 picture 그리고 source html 태그 등으로, 브라우저가 webp 포맷을 지원할 경우에는 해당 포맷의 이미지를 렌더링하고, 아니라면 대체 포맷의 이미지인 png 혹은 jpg 이미지를 렌더링하는 전략도 았는 것으로 알고 있습니다 !

한 번 확인해주시면 감사하겠습니당

@wuzoo
Copy link
Contributor

wuzoo commented Sep 10, 2024

아 ! 그리고 혹시 궁금한 건데, 제가 소개 페이지 업데이트 작업할 때, 저도 이 부분 최적화를 고려하면서 next/image 컴포넌트로 변경하는 시도를 해봤었는데요. 서버에서 받아오는 데이터이다 보니까 fill 옵션을 사용해야하고, 따라서 width, height가 지정되어있지 않다보니까, 기존에 divbackground image로 설정했을때보다 화질이 좀 저하된 상태로 렌더링되는 이슈가 있더라구요 !

혹시 이 부분도 고려하시고 수정하신건지 궁금합니당 !

@lydiacho
Copy link
Member Author

하아 열심히 쓴 답장이 날라가서 ㅠㅠㅠ 늦어진 점 죄송합니다 @wuzoo

먼저 궁금한 점은, 제가 아는 바에 의하면 SSG에서 revalidate와 같은 속성의 ISR을 사용하는 이유는, 결국에는 정적으로 페이지를 생성하였지만 빌드 프로세스에서 데이터를 가져오기 때문에, 받아오는 데이터의 최신화를 위해 특정 주기마다 revalidate하여 데이터를 새로 갈아끼기 위해 사용하는 것으로 알고 있어요.

맞습니다!

그런데 사실 현재 상단 배너로 가져오는 이미지 url은 적어도 솝트의 한 기수동안은 변하지 않는 데이터이고, 아마도 ? 갈아껴주어야 하는 상황에서는 서버에서 s3 이미지 주소를 갈아끼워주는 방식인건데, revalidate가 현재 SSG로 렌더링하고 있는 소개페이지의 상단 배너에 그리 큰 영향이 있는지 궁금합니다 !

직접적으로 영향이 있죠! 서버에서 s3 이미지 주소를 갈아끼워준다고 할지라도 SSG로 불러오는 데이터는 서버에서 데이터를 가져오는게 아니라 저장되어있는 캐시에서 데이터를 가져오기 때문에 반영이 안되는게 앞서 PR에서 언급한 주요 문제였어요! 클라는 계속 캐시에서 데이터를 가져오니까 서버에 변경사항이 생겼을 때 그 변경사항을 캐시에 업데이트해주는 과정이 필요한 상황인거고, 이를 위해 ISR을 도입한 겁니다!
말씀하신 것처럼 솝트의 한 기수 동안 변하지 않는 데이터인건 맞아요 그렇기에 소개페이지에서는 SSG를 쓰고있던거구요. 근데 이번과 같은 일반적이지 않지만 서버의 데이터를 수정해야 하는 케이스가 생길 때마다 다시 Vercel에서 캐시를 지우고 재 배포를 하는것보다 자동화 할 수 있는 방법이 있다면 이를 택하는게 더 적절한 방법이라고 생각합니다! (더군다나 불필요한 요청이 많이발생하거나 사용자 경험상에 악영향을 끼치는게 아니니까요)

승희님이 Vercel에서 자동적으로 cache하는 것 때문에 결국 revalidate를 하셨다면, 찾아보니 vercel의 캐시 전략에서, 특정 데이터를 패칭하는 경우에만 cache를 비활성화하는 옵션도 있더라구요 !

캐시가 되는건 Vercel에서 배포되었기 때문인 것보다 SSG방식으로 데이터패칭을 하기 때문인게 더 주 요인이에요! 그리고 알려주신 cache 비활성화 전략 알아보았는데, 이는 말그대로 특정 데이터 패칭에 캐시 비활성화 기능을 걸어놓는거고, 그럼 저희는 소개 페이지 페칭에 저 옵션을 추가해야 하는건데, SSG는 빌드된 데이터를 캐시에서 가져오는 원리라 강점인 친구인데 SSG 페칭에 캐시 비활성화 옵션을 넣어버리는건 모순이라고 생각해요. 그럴거면 SSG를 안쓰는것과 매한가지가 되는게 아닐까유?!
그리고 cache를 이렇게 비활성화하면 Cache MISS가 매번 나서 서버에서 데이터를 가져오게 되는건데, ISR이 이 Cache MISS가 나지 않으면서도 서버 데이터를 업데이트시킬 수 있는 전략인거라 ISR보다 적절한 대안으로 보이지는 않숩니다 . . !!


추가적으로 webp 이미지 포맷을 사용하게 된다면, 분명 오래된 버전의 브라우저에서는 호환 문제가 발생할 수 있을 것 같다는 생각이 들어요 !
제가 아는 바에 의하면 picture 그리고 source html 태그 등으로, 브라우저가 webp 포맷을 지원할 경우에는 해당 포맷의 이미지를 렌더링하고, 아니라면 대체 포맷의 이미지인 png 혹은 jpg 이미지를 렌더링하는 전략도 았는 것으로 알고 있습니다 !

맞아요! 말씀하신 부분을 next/image 컴포넌트는 자동으로 제공해줍니다! webp, avif로 최적화를 해주고, 만약 이를 지원하지 않는 환경인 경우엔 원본 파일 제공해요. (fallback처리가 된다는 뜻)
근데 이부분에서는 제가 실수한게, 원본 데이터를 png로 넣어놓고, 이를 next/image로 렌더링하면 자동으로 webp로 최적화 & webp지원안될 경우 png로 유지 -> 이렇게 되는건데, 제가 서버에 webp로 변환한 데이터를 넘겨드려서 fallback 기능 소용 없어지게 만들었네요 ㅠㅠ 다시 png 파일로 서버 데이터 수정 요청 드린 상태입니다!! 짚어주셔서 감사해용

아 ! 그리고 혹시 궁금한 건데, 제가 소개 페이지 업데이트 작업할 때, 저도 이 부분 최적화를 고려하면서 next/image 컴포넌트로 변경하는 시도를 해봤었는데요. 서버에서 받아오는 데이터이다 보니까 fill 옵션을 사용해야하고, 따라서 width, height가 지정되어있지 않다보니까, 기존에 div의 background image로 설정했을때보다 화질이 좀 저하된 상태로 렌더링되는 이슈가 있더라구요 !

헉 이부분은 완전 몰랐어요. 덕분에 알았네요! 감사합니다 요 부분은 어떻게 개선할지 좀더 이것저것 시도해보고 다시 멘션드릴게용

Copy link
Member

@eonseok-jeon eonseok-jeon left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

늦어서 죄송해요 너무 고생하셨습니다!!

❓왜하필 2분인가요?

사실 소개페이지는 기존에 SSG를 썼던 만큼 잦은 업데이트가 전혀 불필요한 페이지예요. 다만 서버 데이터상의 변경이 생겼을 경우 이게 반영은 되어야 하니까 너무 긴 주기를 주고 싶진 않았고, 하지만 또 사용자가 접속하는 시간동안 서버 데이터가 바뀌는 일이 매우 드문건 사실이잖아요? 따라서 대부분의 경우에 사용자가 참여하는 한 세션 동안 새로이 revalidate 하면서 불필요한 서버 요청을 일으키는 것도 피하고 싶었어요. 그래서 GA로 사용자 체류시간을 봤는데 소개페이지는 평균 체류시간 약 50초, 전체 페이지 평균 체류 시간 약 1분 20초, 한달 내 최대 체류 시간 약 1분 50초 이길래 이보다 긴 2분으로 설정했습니다.

한달 내 최대 체류 시간 약 1분 50초인데 2분으로 설정하는 건 사실상 revalidate를 하지 않는 거 같아요!
이게 매 2분 마다 계속해서 revalidate를 하는 것이 아니라 아무나 페이지 진입 후 2분이 지나게 되면 한 번만 revalidate를 해서 caching을 새로 바꿔준다는 거라서요
따라서 새 이미지를 보기 위해선 누군가는 2분 이상 머물러야 합니다
하지만 저희의 최대 시간은 1분 50초라 다소 어려울 거 같아요~

서버에서 데이터가 변했다 하더라도 아무도 2분 이상 들어가있지 않았기에 기존 cache된 데이터가 보이게 될 거예요!
(참고자료로 넣어주신 youtube 영상도 보면 1s로 설정했지만 빠르게 새로고침하면 1s가 지나지 않아 업데이트가 되지 않고 있는 걸 볼 수 있어요!)

따라서 그냥 1초로 변경하는게 더 나을 거 같단 생각입니다
만약 예를 들어 1분으로 설정한다 했을 때 페이지에 1분 이상 머무르는 유저가 발생되기 전까진 모든 유저들이 이전 데이터값을 보게 될 거예요
1분이 지난 후에 들어온 유저들 부터 새로 업데이트된 데이터를 보게 되는 거죠

그런데 1초로 설정한다면 처음으로 1초 이상 접속할 유저가 페이지 진입 하고 1초 후엔 모두가 새 데이터를 보게 될 테니 바로 갈아끼우는 게 낫지 않나 싶어요! (1분의 공백 제거)

서버 비용 때문에 그런 거라면 on demand를 이용하면 될 거 같아요
물론 이건 서버에서 수정이 필요한 거라 쉽진 않을 수 있지만요ㅜ
아니면 그냥 30초 정도로 늘려도 될 거 같습니다

주절주절 사실 이걸 왜 서버에서 받아와야 하는 걸까 고민이 좀 되는 거 같아요

어드민에 들어갈 내용 정리하면서도 느낀 건데
6개월 마다 변경되는 거라 변경 빈도가 높은 편도 아닌데
사실 어드민에서 변경하는 거나 코드 딴에서 변경하는 거나 리소스는 동일하게 발생하거든요

문구 이런 거는 그렇다 쳐도 사진은 규격만 동일하게 한다면 바꾸는 거 1초도 안 걸리니까 그냥 하드코딩으로 박는 게 더 낫지 않나 싶은 생각이 들긴 합니다

현재 서버 비용도 많이 들고 한데 비용도 줄일 수 있고
추가로 서버로 부터 이미지 받아오는 것 보다 미리 빌드된 이미지 갔다 넣는 게 속도 면에서도 더 빠를 거 같아서요,,,,

일단 제 개인적인 의견이었고요 이 부분은 좀 더 의논 해보면 좋을 거 같아요

@lydiacho
Copy link
Member Author

lydiacho commented Sep 16, 2024

@eonseok-jeon

서버 비용 때문에 그런 거라면 on demand를 이용하면 될 거 같아요

일단 on demand를 제일 먼저 고려했지만 말씀하신 것처럼 서버측에서 코드 작업을 해줘야 하고 현재 서버에서는 말그대로 s3 이미지 올려서 갖다 박는 느낌이라 서버 코드 단에서 변경사항을 감지하는 코드를 추가하는 것보다 클라에서 작업하는게 더 적합한 환경이라고 생각해서 on demand는 선택지에서 제외했습니다!

한달 내 최대 체류 시간 약 1분 50초인데 2분으로 설정하는 건 사실상 revalidate를 하지 않는 거 같아요!
이게 매 2분 마다 계속해서 revalidate를 하는 것이 아니라 아무나 페이지 진입 후 2분이 지나게 되면 한 번만 revalidate를 해서 caching을 새로 바꿔준다는 거라서요
따라서 새 이미지를 보기 위해선 누군가는 2분 이상 머물러야 합니다
하지만 저희의 최대 시간은 1분 50초라 다소 어려울 거 같아요~

혹시 이 내용이 출처를 알 수 있을까요??
제가 했을 때는 제가 이해한 바대로 잘 작동해서요!
제가 이해한 바 : 사용자의 체류 시간 기준으로 revalidate 시간을 재는게 아니라, next 서버에서 마지막 데이터 요청 시간 이후로 revalidate 시간이 지났는가?를 체크.

revalidate 20초로 하고 build start 해서 통으로 실행시킨 영상이에요

default.mov

vscode 터미널 보시면 언제 캐시 업데이트하는지 볼 수 있도록 콘솔 찍어놨는데
최초 pnpm build 했을 때 콘솔, 빌드 후 20초 됐을 때 콘솔,
그 이후 20초동안 아무리 재실행해도 업데이트안되다가
20초 지나니까 또 콘솔.

즉 사용자 접속 타이밍과 revalidate 시간은 무관하다는 의미입니다.

(참고자료로 넣어주신 youtube 영상도 보면 1s로 설정했지만 빠르게 새로고침하면 1s가 지나지 않아 업데이트가 되지 않고 있는 걸 볼 수 있어요!)

말씀하신 영상도 혹시 1:49 얘기하시는거면, 1초 미만으로 연속해서 계속 리프레시를 하는데 1초를 체류했을 때마다 업데이트 되는게 아니라 계속 1초 미만으로 리프레시 시키는데 마지막 요청 후로 1초 지나고 그 이후 최초로 리프레시했을 때 데이터가 업데이트되는 방식으로, 즉 제가 이해한 방식으로 작동되고 있는 것으로 보여요

혹시 제가 뭔가 잘못 짚고 있는게 있다면 말씀해주세요 !

@eonseok-jeon
Copy link
Member

아ㅏㅏㅏㅏㅏ 고렇네요 제가 잘못 알고 있었네요 😓 죄송합니다ㅜ
올려주신 유튜브 자료에서 새로고침할 때 값이 변경되지 않은 걸로 잘못 봤었었네요 (실제로 값이 변경되고 있었음)
2분 좋은 거 같습니다!!
소중한 시간 뺏은 점 다시 한 번 사과드릴게여 😢

@lydiacho
Copy link
Member Author

아우 아닙니다 !! 이런건 시간 뺏는게 아니지요 !~~

주용님이 언급해주신 next/image로 인한 화질 저하 개선은 따로 이슈 / 브랜치 파서 별도로 진행할 예정이라
이 친구는 우선 머지하겠습니다 ~~ 🙇🏻‍♀️🙇🏻‍♀️🙇🏻‍♀️🙇🏻‍♀️

@lydiacho lydiacho merged commit 00882b6 into develop Sep 16, 2024
1 check passed
@lydiacho lydiacho deleted the fix/#411_image-speed branch September 16, 2024 09:10
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

Successfully merging this pull request may close these issues.

[Refactor] 이미지 로딩 속도 개선
3 participants