Today
-
Total
-
  • 내 사이트 이미지 로딩속도는 왜 느릴까?
    Dev 2020. 12. 22. 20:40

    SPA가 대세로 자리매김한 요즘 사이트 최초 로딩 속도는 사이트의 품질 뿐만 아니라 프론트엔드 개발자의 실력까지 볼 수 있는 지표가 되었습니다. SPA에서는 페이지가 로드되었을 때 바로 VIews의 Interaction이 가능하도록 페이지 로드에 필요한 모든 것들을 맨 처음에 한번에 로딩하기 때문이죠. 구글은 최초 페이지 로딩이 3초 이상 걸릴 경우 50%의 사용자가 이탈한다는 분석값을 내놓았으며, 페이지 로딩 시간이 긴 경우 검색 순위를 낮추겠다는 말까지 나왔습니다.

     

    nownews.seoul.co.kr/news/newsView.php?id=20180123601013

     

    https://nownews.seoul.co.kr/news/newsView.php?id=20180123601013&rftime=20150630

     

    nownews.seoul.co.kr

     

    같은 내용을 보여주더라도 컴포넌트가 얼마나 최적화되고, 잘 포맷된 정적 파일을 사용하며, 어떤 생명주기를 거쳐 페이지가 로드되는지가 아주 중요해졌다는 말이죠. 그래서 저도 제 사이트의 로딩 속도가 얼마나 걸리는지 궁금해졌습니다.

    developers.google.com/speed/pagespeed/insights/

    Google PageSpeed insight에서 사이트 속도 측정 및 분석 기능을 제공하네요. 제 사이트 점수를 확인해보았습니다.
    (단순히 최초 페이지 로딩 속도만 궁금하다면 tools.pingdom.com/ 이 사이트를 추천합니다!)

     


    😢 처참한 결과가... (입틀막)

    네, 구글에게 신나게 혼났습니다..

    최초 로딩 속도는 3초 이내로 세이프였지만, 안좋은 지표가 참 다양하게도 보이네요. 결국 페이지 로딩 속도가 빠른 편은 아니었기에 최적화가 필요하다고 마음먹었습니다. 이중에서도 가장 중요해 보면서 간단하게 처리가 가능해 보이는 것은 이미지 포맷이 제대로 되어있지 않은 부분이네요. 그래서 한번 파헤쳐보았습니다.

     

     

    1) 이미지 크기 적절하게 설정하기

    이미지의 용량 역시 로드 속도에 많은 영향을 끼치지만 단순히 이미지의 크기, 즉 이미지의 면적도 중요한 영향을 미칩니다. 특히 전문 카메라로 찍은 고화질, 고해상도 이미지의 경우 이미지의 면적이 굉장히 높게 잡혀있는 경우가 많습니다. 이를 최적화하지 않고 올리게 되면 다른 이미지에 비해 유독 로딩 속도가 느려지게 되는 것이죠. 

     

    저는 Storage로 S3을 사용하고 있기 때문에, 정적 파일로 배포된 이미지부터 쭉 확인해보아야 했습니다. 이전에 콘텐츠 디자이너님으로부터 전달받은, 전문 카메라로 촬영한 이미지의 크기를 먼저 확인해보았습니다. 

    ngnix 기준으로 1MB 이상의 Entity는 차단하는 것이 기본값이라는 것을 생각해보면 그래도 용량이 꽤나 나가는 편입니다. 무엇보다 규격이 6048 x 4024입니다. 어차피 기기의 해상도에 맞춰 반응형으로 이미지가 보여지게 되면.. 광화문 광장 스크린에 내 페이지의 이미지를 깔끔하게 띄우고 싶은 꿈이 있는 게 아니라면 과하게 커 보입니다. 이 이미지의 크기부터 어떻게 해봅시다. 이미지 크기를 조정할 수 있는 툴은 다양하지만 저는 맥의 미리보기의 크기 조정을 통해서 수정하는 편입니다.

    미리보기에서 제공하는 기본 기능

    비율에 맞추어 크기를 줄여주기 때문에, 가로 길이를 972px로 줄이면 알아서 비율에 맞게 수정됩니다. 결과를 확인해보니 크기는 990 KB -> 55KB로 말도안되는 수치가 줄었네요. 이렇게 이미지의 크기를 줄이는 것 만으로도 용량을 줄일 수 있습니다.

     

     

    2) 차세대 형식을 이용하여 이미지 제공하기

     

    (1) 적절한 이미지 포맷

     

    현재 이 이미지 파일은 .png 파일입니다. 보통 웹 사이트에서 사용하는 포맷은 jpg, png, svg 등이 있겠으나 svg는 벡터 이미지를 표현하기 위하여 압축 효율은 좋지 않은 편입니다. jpg와 png를 비교해봅시다.

     

    JPG

    - 용량이 큰 이미지 파일을 작게 만들어 이미지 파일을 쉽게 공유할 수 있도록 한 포맷입니다. 이미지의 용량이 적을 수록 로딩이 빠르게 되기 때문에 웹 이미지로 자주 사용되는 포맷입니다. 이미지의 용량을 줄이기 위해 압축 손실(불필요한 정보는 삭제)을 거칩니다.

     

    PNG

    - JPG 파일과 달리 투명성을 지원하며, 압축 손실이 없습니다. JPG와 달리 모든 정보를 포함하기 때문에, 복잡한 이미지에 주로 활용됩니다.

     

    제가 사용하는 이미지는 작은 목업 이미지이기 때문에 JPG로 이미지 포맷을 변경해보겠습니다. 

     

     

    (2) 적절한 압축률 선택하기

     

    이미지를 압축할 수록 파일 크기는 작아지지만 이미지의 품질은 저하됩니다.

    이미지를 압축하지 않을 수록 품질은 향상되지만 파일 크기는 커집니다. 그럼 어쩌라구욧

     

    결국 이미지에 맞는 적절한 압축 방식을 사용하여 확인해보아야 합니다. 저는 이미지 압축을 할 때 구글에서 제공하는 squash라는 사이트를 애용합니다.

    squoosh.app/

     

    Squoosh

     

    squoosh.app

     

     

    중앙 수직선을 기준으로 좌측이 변환 전, 우측이 변환 후입니다. MozJPEG 형식으로 압축해도 이미지의 정보 손실이 거의 없네요. 우측 하단을 살펴보면 압축을 통해 용량이 얼마나 최적화되었는지 나옵니다. 압축해도 이미지가 잘 보이니 이대로 압축해도 문제없겠습니다.

     

    다음 이미지는 JPG로 포맷을 하다보니 투명성 보장이 되지 않아 배경이 검정색이 되었고, 용량은 성공적으로 압축되었으나 이미지의 정보 손실이 과하게 일어나 깨진 모습입니다. 이미지에 따라 적합한 압축 포맷을 선택해야 하는 이유입니다.

     

    자, 이제 이미지 크기/포맷 변경과 압축을 통하여 995KB -> 35.6KB로 용량 압축에 성공했습니다.

    한번 변환 전과 변환 후를 비교해보겠습니다.

     


    🧐 직접 성능을 비교해보자

    구글 개발자콘솔의 Network 탭에서는 모든 XHR, Image, JS, CSS 등의 리소스 로딩이 어떻게 이루어지고 있으며, 몇 ms나 걸리는 지 측정해 줍니다(Network 탭을 연 이후부터 측정을 시작합니다). Network 탭에서 Image만 선택하여 정렬해보겠습니다.

    다양한 이미지 파일을 불러오고 있으며, 15ms ~ 30ms 정도까지 찍히네요. 이제 아까 변환한 이미지와 변환 전 이미지를 동시에 배포하여, 속도 차이가 얼마나 일어나는지 확인해보겠습니다.

     

    로딩 속도가 각각 변경 전 266ms, 변경 후 60ms로 4배 차이 이상이 나네요. 물론 변환 후에도 가로길이 972px로 작은 이미지가 아니었기에 변환 후에도 꽤 걸리는 편이지만, 변환 전에는 굉장히 심각합니다. 이런 이미지 포맷과 압축만 잘 해주어도 이정도의 절감 효과를 볼 수 있다니, 대단하네요!

     


    📖 결론

    Google PageSpeed Insight로부터 안좋은 지표를 많이 발견하였으나, 차근차근 수정해 나가야겠다는 생각이 들었습니다. 현재 사이트 점수가 32점인데, 80점 이상으로 끌어올려보자는 개인적인 목표 역시 생겼습니다. 평소에 이미지 1MB라고 하면 굉장히 낮아보였는데, 이렇게 압축 후 용량을 확인해보니 최고의 사용자 경험을 제공해야하는 프론트엔드 개발자로써 많은 깨달음을 얻을 수 있었습니다. 단순히 개발을 잘할 뿐만 아니라 사이트 및 SEO 최적화도 가능한 개발자가 되기 위해 노력해야겠습니다!

     

     

    📚 출처 

    - JPG / PNG 비교하기

    lifelog-story.tistory.com/93

    - SEO를 위한 이미지 최적화
    www.openads.co.kr/content/contentDetail?contsId=2581

     

    댓글