Programming/Client

웹 사이트 성능 측정 및 최적화 (with LightHouse)

Jiwoo 2023. 4. 6. 22:51

LightHouse 성능 측정

웹 사이트를 만들고 배포까지 마쳤다.

그런데 SSR임에도 불구하고 초기 렌더링이 느려서 성능 측정이 필요했다.

크롬 확장 프로그램인 LightHouse을 사용해서 사용자 입장의 성능을 측정했다.


다른 것들은 준수했으나 가장 중요한 퍼포먼스 점수가 처참했기에 최적화를 진행했다,

💡 이미지 최적화

성능 하락의 주된 원인은 이미지였기에 두 가지 과정을 거쳤다.

Next.js에서 제공하는 Image 태그 커스텀

해당 Image 태그는 width, height를 필수적으로 적어야 했는데,
나는 이미지의 크기가 부모의 맞춰서 유동적으로 변화하는 것을 원했다.
그래서 기본 속성을 이용하여 커스텀했다.
Image의 width나 height는 px단위의 숫자만 넣을 수 있기에 0을 넣고
sizes="100vw"를 넣어서 전체 화면 사이즈보다는 작음을 알려준다.
그 다음에 스타일을 따로 지정해줬다.

import Image from "next/image";

// tailwind 미사용
<Image
   src={img1}
   width="0"
   height="0"
   sizes="100vw"
   style={{ width: '100%', height: 'auto' }}
/>

// tailwind 사용
<Image
   src={img1}
   width="0"
   height="0"
   sizes="100vw"
   className="w-full h-auto"
/>

// typescript + tailwind-styled-components
import tw from "tailwind-styled-components";

interface CustomImgProps {
 src: string;
 alt: string;
}

const CustomImg = ({ src, alt }: CustomImgProps) => {
 return (
   <Wrapper>
     <Img src={src} alt={alt} width="0" height="0" sizes="100vw" />
   </Wrapper>
 );
};

const Wrapper = tw.div`
   w-full h-full relative
`;
const Img = tw(Image)`
   w-full h-[auto]
`;

export default CustomImg;

이미지 확장자 변경 및 용량 축소

태그만 바꾸는 것으로는 부족해서 이미지의 용량 자체를 줄였다.
jpeg는 png로 바꿨고, 그래도 너무 크다면 webp으로 변경했다.
이미지 자체의 크기를 줄이고 불필요한 고화질은 화질을 낮췄다.
네이버는 이미지 하나를 좌표 단위로 잘라 쓸 정도로 극도의 이미지 최적화를
한다고 들은 적이 있기에, 매우 중요하다고 생각한다.
역시 이미지 최적화 후, 초기 렌더링의 버벅임이 줄었다.

💡 웹 접근성 향상

웹 접근성 향상은 UX를 위한 모든 웹사이트의 의무사항이다.
WAI-ARIA를 사용하여 어렵지 않게 향상시킬 수 있다.

WAI-ARIA 란?

(Web Accessibility Initiative’s Accessible Rich Internet Applications)
스크린 리더가 브라우저를 읽을 때 각 요소의 역할과 의미를 인식할 수 있도록 HTML 태그에 필요한 정보를 제공해주는 보조 기술
(스크린 리더: 시각장애가 있는 사용자를 위해 컴퓨터 화면을 낭독해주는 소프트웨어)


  • 현재 지원되는 브라우저
  1. 시맨틱태그 사용
    자체적으로 의미를 지낸 시맨틱 태그 사용을 지향한다.
    ex) <header>, <footer>, <main>, <nav> ...
  2. role
    시맨틱태그가 아니라면 role 속성으로 해당 태그의 역할을 알려줄 수 있다.
    마음대로 쓰는 것이 아니라 정해진 값이 있다. mdn에서 확인하기
  3. aria-label
    태그가 가지고 있는 의미를 적는데, role과 달리 정해진 값이 없다.
    • 시맨틱 태그이거나 role 속성 값이 상호작용(interactive)를 하는 값일 때 사용 가능
    • 의미 없는 태그(div, p 등)에는 role이 안 붙어있다면 사용 불가

💡 불필요한 js 코드 삭제

초기에 기본 설정을 위해 깔았지만 사용하지 않은 패키지가 있었다.
나 같은 경우에는 페이지 이동이 없었기에 react-dom이 사용되지 않았다.
그래서 모두 삭제하고 정리해줬다.

결과

  • 퍼포먼스 점수: 49 -> 92
  • 접근성 점수: 79 -> 86

나머지까지 거의 100에 가깝도록 계속 리팩토링 할 예정이다.
사용자 입장에서 초기 렌더링 시간을 측정하기 때문에 매번 점수가 달라지지만
크게 레벨은 달라지지 않기 때문에 참고해서 리팩토링하기 좋은 것 같다.



참고
스택오버플로우