기능이 잘 되는 것으로 만족했었지만.. 3초 법칙(페이지가 3초 이상 로딩되면, 사용자가 떠나는 확률이 높아진다.)을 알고 내가 만든 웹페이지의 성능이 좋아야 만든 기능을 써먹을 수 있구나. 생각하여 성능 최적화에 대하여 알아보고 실행해보았다. 처음 해본 성능 측정의 결과에 꽤나 큰 충격을 먹었다 ..^^
더 빠르고, 성능이 좋은 서비스에 대한 욕심이 생겨서 100점은 아니더라도, 90점은 근접하자는 생각으로 최적화를 열심히 했고, 새롭게 알게된 것도 많다. 이에 대한 이야기를 써보겠다 !!!
1. Chrome 개발자 도구의 Performance
2. Chrome 확장 도구 Lighthouse
Performance을 사용하면 내가 원하는 범위를 녹화하여 성능을 측정해준다. 처음 해보는 성능 측정인지라, 얼마정도의 ms가 성능이 좋은 것인지 잘 몰랐지만 내가 구현한 게시글 페이지
에서는 사진이 많아서 로딩이 꽤 걸리는 것은 알 수 있었다.
게시글 페이지에 맨 상단에는 대표 이미지를 넣었다. 원래는 png
였으나, webp
는 이미지 압축 효과가 높으며 웹사이트의 로딩 속도 단축을 겨냥한 확장자이기 때문에 png => webp
으로 변경했다.
또한, 게시글 목록에 있는 이미지의 확장자는 .png , .jpeg, .jpg
만 올릴 수 있는 api를 사용하여 이렇게 세 개의 이미지로 분포 되어있었다. 여기사 .jpg
가 가장 무거웠으며 .png와 .jpeg
가 상대적으로 가벼웠다. 그래서 확장자가 jpg인 사진을 jpeg로 변경했다.
확장자만 변경했지만 아주 조금이라도, 그림에서 0.160ms를 개선시켰다.
Lighthouse는 성능 개선에 초보인 나도 한 눈에 보기 쉽게 분석 결과가 항목으로 나타난다.
⭐ Lighthouse 성능 분석 항목
Performance: 웹 성능을 측정하며, 화면에 콘텐츠가 표시되는데 걸리는 시간, 표시된 후 사용자와 상호작용 하는데까지 걸리는 시간을 확인한다.
Accessibility: 웹 페이지가 웹 접근성을 잘 갖추고 있는지 확인한다.
Best Practices: 웹 페이지가 웹 표준 모범 사례를 잘 따르고 있는지 확인한다.
SEO: 웹 페이지가 검색 엔진 최적화가 잘 되어있는지 확인한다.
먼저 접근성에 대한 최적화부터 했다. 68점으로 높은 점수가 아니였고 이에 대한 문제점을 찾아보았다.
How to Fix: "Buttons Do Not Have Accessible Names"
가 첫 문제점이었다. 이는 버튼에 액세스 가능한 이름이 없다는 경고문으로 버튼 요소에 aria-label=""
을 추가해주면 간단히 해결될 문제이지만 주의해야할 점이 있다.
⭕-1
<button onClick={goPostUpload} aria-label=" 게시글 작성"></button>
⭕-2
<button onClick={goPostUpload} aria-label="작성하기"> 작성하기 </button>
❌-3
<button onClick={goPostUpload} aria-label="작성 버튼"> 작성하기 </button>
1번은 태그 사이에 아무런 텍스트가 없을 경우에 aria-label
에 버튼을 설명할 수 있는 말을 작성해주면 된다. 2번은 태그 사이에 텍스트가 있을 경우 aria-label
과 맞춰줘야 한다. 그렇다면 3번은 무엇이 문제일까? 우선 태그 사이에 있는 텍스트와 aria-label
이 맞지 않는다는 점과, 버튼을 설명하는 글에 굳이 "~버튼"
이라는 말은 지양하는 편이 좋다.
(+) 버튼에 aria-label
를 넣은 방식과 마찬가지로 link에도 넣어주면 Accessibility뿐만 아니라 SEO에도 도움이 된다 !!
Lists do not contain only <li> elements and script supporting elements .
라는 경고문도 나타났다. 이것에 대한 해결방법은 li만 단독으로 쓰인 것에 ul태그를 추가하는 것이었다.
❌
<li>
<PostItemLi
key={item.id}
{...item}
/>
</li>
⭕
<ul>
<li>
<PostItemLi
key={item.id}
{...item}
/>
</li>
</ul>
이렇게 수정해준 결과 Accessibility 항목에서 35점이 오른 개선효과를 보았다.
다음으로 최적화한 것은 Best Practices이다. 여기서 겪은 문제는 이미지의 실제 크기는 897 x 505
인데 웹 페이지에서는 1440 x 788
로 쓰여서 저해상도의 문제가 나타난 것이다.
이 문제에서는 src 속성으로 구현할 수 없는 브라우저의 뷰포트 너비나 디스플레이 해상도에 대한 반응형 이미지 소스 지정을 위해 도입된 srcSet 속성을 사용하여 해결했다.
우선 src에는 크기가 897 x 505
인 이미지를 그대로 넣었고, srcSet에는 원래 이미지를 1440 x 788
크기로 변환하여 넣어주었다.
<img src={post} srcSet={postResize} alt="포스트 페이지 대표 이미지" />
(+ 참고)📝 이미지의 크기를 변환하는 사이트의 링크
srcSet을 넣어준결과 Best Practices 항목에서 31점이 올랐다 !!
SEO 항목은 처음 성능을 측정 했을 때부터 90점이 나왔고, button과 link에도 aria-label을 달아주니까 점수가 100점이 되었다. 전에 SEO에 대하여 포스팅하여 SEO 최적화 방법이 있으니까 참고하길 바란다 !!
정말.. 정말 성능을 최적화 하기 어려웠던 항목이다. 제일 점수도 낮고, 문제점도 많아서 차근차근 할 수 있는 것부터 개선해보았다. 첫 번째로 기능을 안하는 코드, 주석 등 불필요한 코드를 삭제했다. 두 번째는 라우터 기반으로 Code Splitting을 했다.
const Home= lazy(()=> import('../pages/home/Home'));
<Router>
<Suspense fallback={<div>Loading...</div>}>
<Routes>
<Route path="/home" element={<Home />} />
</Routes>
</Suspense>
</Router>
이렇게 코드를 바꿔주었더니 39점이 향상했다.
도장깨기 하듯이 성능을 개선하다 보니까 뭔가 재밌었다.. 아직 Performance 항목에 대해서 90점 이상을 못 만든것이 아쉬움이 남지만 더 공부하면서 개선해야겠다 !!! 🌞