Lighthouse를 통한 프로덕션 웹 앱 최적화
실제로 공들여 만든 웹 앱을 배포했을 때, 개발자들은 최적화가 잘 되었는지 고민하게 됩니다.
저 역시 웹 앱을 배포하고 이제 실제 서비스 운영을 하려하는데 최적화가 고민이 되었습니다.
React의 useCallback, useMemo, memo 같은 최적화 외에도 많은 최적화 이슈들이 있습니다.
크롬 브라우저에서는 Lighthouse 기능을 지원하는데요, 이 기능을 이용하면 배포한 웹 페이지를 분석하고 최적화를 해야 할 문제가 무엇인지 분석해줍니다.
주의하셔야할 점이 있는데요, localhost:3000 같은 개발 서버는 성능 퍼포먼스가 낮은 점수를 받을 수 밖에 없기 때문에 정확한 수치를 알고 싶으시다면 프로덕션으로 배포를 하고 시크릿 탭으로 확인한 후에 최적화하시는 방법을 추천드립니다.
먼저 제가 배포한 웹 앱의 점수를 보여드리려합니다.
그리 나쁘진 않다 볼 수 있는 점수지만, 어떤 부분에서 이슈가 생겼는지 확인해보면 점수가 낮지 않더라도 고쳐야할 문제가 많습니다. 어떤 이슈가 발생했는지 확인하고 차근차근 고쳐보도록 하겠습니다.
(*성능은 시크릿 탭으로 캡쳐를 안해서 확장 프로그램이 반영되었기 때문에 실제 수치는 약 95점입니다.)
성능
1. 콘텐츠가 포함된 최대 페인트 이미지 미리 로드
이 부분은 렌더링 과정에서 이미지를 먼저 불러올 수 없기 때문에 발생합니다.
Lighthouse에서는 이미지 역시 페이지 렌더링 과정에서 불러올 수 있으면 좋겠다고 하는데요,
제 Next.js 프로젝트에서는 Next Image 컴포넌트로 쉽게 해결 할 수 있었습니다.
Next Image가 알아서 저희가 입력한 도메인의 이미지를 렌더링 할 때 우선순위를 높여서 로딩 속도를 개선해줍니다.
(Priority={true})
AWS CloudFront 같은 외부 서비스 사용할 때는 next.config.js에서 설정이 필요합니다. (참고 자료)
Next Image를 사용할 때는 이미지의 width,height가 고정되어야 한다는 제약 사항이 있습니다.
때문에 유저가 업로드 하는 크기가 전부 다른 이미지의 경우에 쓰는 것은 추천드리지 않습니다.
제 프로젝트에는 썸네일 같은 고정된 크기를 가지는 이미지에 한해서 적용하였습니다.
2. 사용하지 않는 자바스크립트 줄이기
이 부분은 프로젝트 내에서 사용되지 않는 export하는 Styled-components 코드들과 더 이상 필요하지 않은 자바스크립트 컴포넌트를 제거한 후 개선되었습니다. 특히 외부 스크립트를 잘못된 곳에 선언해서 사용하는 경우 로딩에 지장이 생길 수 있기 때문에 주의가 필요합니다.
3. 효율적인 캐시 정책을 사용하여 정적인 애셋 제공하기
Next.js에서는 제 이미지의 캐시 TTL을 1분으로 잡고 있습니다.
next.config.js에서 minimumCacheTTL을 일주일로 설정해주어도 바뀌지 않는 현상이 일어나는데요, CDN인 AWS CloudFront의 TTL 설정을 바꿔줘도 마찬가지였습니다. 이 부분은 해결하면 해당 내용을 수정하도록 하겠습니다.
접근성
위 이미지의 문제점은 브라우저나 검색엔진이 어떤 요소인지 파악하기 위해 정보를 제공하지 않아서 발생합니다.
저 코드에서는 검색창에서 정보가 미비한 케이스였습니다.
밑의 예제를 보시면 input에 arial-label과 button에 title을 추가하였습니다.
<SearchInput
name="search"
type="text"
aria-label="Search" // 브라우저와 검색엔진에게 어떤 요소인지 알려줍니다.
value={formik.values.search}
onChange={formik.handleChange}
/>
<SearchButton title="Search" type="submit"> // 브라우저와 검색엔진에게 어떤 요소인지 알려줍니다.
<AiOutlineSearch />
</SearchButton>
권장사항
제 사이트에선 위의 이미지처럼 2가지 이슈가 발생하였습니다.
index 페이지의 글 목록에서 썸네일을 불러올 때, width와 height를 둘다 지정해주지 않아서 발생하는 이슈였습니다.
제 경우에는 AWS Lambda@Edge로 S3의 이미지를 쿼리스트링으로 리사이징해서 배포하였는데, 이 쿼리스트링으로 width만 지정해주고 height를 지정해주지 않아서 발생하는 이슈였습니다.
height가 멋대로 이미지 원본 크기에 기반하여 조정이 되었기 때문에 종횡비(Aspect ratio)가 어긋나게 되어 Lighthouse에서 이를 감지하고 알려주게 된 것입니다.
쿼리스트링으로 height까지 종횡비에 맞게 지정해주고 테스트 해본 결과 이슈가 전부 해결되어 100점이 되었습니다.