원챌 8월 3일차 + 4일차 (230807, 230811)

Sheryl Yun·2023년 8월 10일
0
post-thumbnail

Recap

  • 프론트엔드 테스트는 비즈니스 로직을 테스트하는 것

성능 측정 툴

Lighthouse, Web Vitals, Performance(개발자 도구), Profiler 알아보기

1. Lighthouse

웹 성능을 분석하는 오픈 소스

성능 분석 (Performance)

  • 개발자 도구의 Network 탭의 와이파이 모양 클릭
  • No throttling 등 선택 가능
  • 성능을 일부러 약간 떨어뜨려서 약간 안 좋은 환경에 있는 상황에서 테스트를 진행
  • 모든 유저가 빠른 네트워크에서 사용하는 게 아니기 때문

접근성 검사 (Accessible)

  • 웹 접근성 (for 장애인, 노령자 등)

SEO 검사

PWA

  • 앱인데 웹처럼 쓸 수 있는지 (프로그레시브 웹앱)
  • 성능과는 크게 관련 X
    Lighthouse는 측정할 때마다 약간씩 다를 수 있음
  • 참고할 만한 지표 정도
  • 수치에 집착하지 말고 직접 웹사이트 테스트하면서 사용자가 ‘거슬릴 만한 것’에 대해서 측정

Lighthouse 검사 시점

production 빌드 레벨에서 검사

  • production하면서 어느 정도 최적화가 되기 때문
    • minification
      • 빈칸, 줄바꿈 제거
      • js 내용을 모두 한 줄로 합쳐줌 (용량이 줄면서 번들 사이즈 감소)
    • Tree shaking
      • 안 쓰는 코드 버리기
      • unused javascript
        • 예: react-query dev-tool
          • 어차피 dev 툴이라 production 후 사라짐
          • develop에서 확인하면 이걸 포함해서 확인
    • yarn run build → yarn run preview 이렇게 터미널에 찍으면 production 빌드 레벨에서 확인 가능

2. Web Vitals

  • 구글에서 제공
  • 사용자 경험 측정

LCP

  • 화면에서 제일 큰 이미지가 뜨는 데 걸리는 시간
    • 2.5초 이하 초록불
    • 2.5초~4초 노란불
    • 4초 넘어가면 빨간불

FID (First Input Delay)

  • 인풋이 지연되는 시간
  • TTI와 비슷

CLS

  • 레이아웃이 움직여서 사용자 경험을 방해함

3. Performance

  • 개발자 도구
    탭에 들어가서 맨 왼쪽에 있는 '녹음' 버튼 클릭
    브라우저 화면을 다시 띄우면서 성능 측정
    * 화면이 그려지는 순간들을 보여줌
  • Scripting
    • 자바스크립트를 불러오는 시간
  • Rendering
    • HTML로 화면을 그려내는 시간
  • Painting
    • CSS를 입히는 시간
  • 현업에서 최적화할 때는 Performance 대신 주로 Lighthouse나 Profiler 사용
    • Performance는 육안으로 잘 안 느껴짐
    • Lighthouse에서 빨간 불 정도 되어야 사용자들 인지

4. Profiler

  • 리액트 내장 기능 (리액트로 만들어진 사이트의 경우 개발자 도구에 Component와 함께 해당 탭 생성)
  • 용도: '컴포넌트별' 렌더링 시간 측정
    • 병목 생기는 컴포넌트를 최적화할 수 있음
  • 사용 방법: 리액트 코드에서 Profiler 컴포넌트로 감싸고 prop으로 onRender={onRender} 추가
    • 더 편한 방법으로 Profiler로 안 감싸고 하는 방법도 있음
  • 유의: 배포한 곳(production 레벨)에서는 안 됨 (development 레벨에서만 동작)
    • 관련 에러 메시지
      Profiling not supported.
      Profiling support requires either a development or profiling build of React v16.5+.

5. Code Splitting

  • 번들 사이즈를 잘개 쪼개는 것
    * 100KB를 10KB로 잘게 쪼개서
    • 처음부터 100KB를 다 불러오지 않고
      • 필요한 10KB, 20KB부터 먼저 불러오는 것
  • 장점
    * 초기 로딩 시간 감소
  • 방법
    * React.lazy와 Suspense를 함께 사용 (동적 import)
    • lazy로 감싼 컴포넌트를 완전히 불러올 때까지
    • Suspense fallback(로딩중 UI)을 보여줌
    • 렌더링 컴포넌트가 완전히 불러와지면 그때 로딩 UI 대신 해당 컴포넌트를 보여줌

회사의 레거시 코드를 개선하는 것도 개발자의 중요한 업무 - 좋은 경험

  • `npm dedupe (de-deplicate: 중복을 없앰)
  • package.json의 ^10.0.2 버전의 의미
    • '10.0점 대에서는 아무 거나 설치해도 괜찮아'
    • 만약 ^가 없으면? - '무조건 10.0.2만 사용해야 해'
  • font 용량 줄이기
  • font를 HTML에 script 태그로 추가하면 용량 문제 발생 가능
  • build 파일 중 '~chunk'를 포함한 파일
    • 예: build/static/js/123124.aejes.chunk.js
      • 해당 파일을 브라우저가 기억해두었다가 캐시해두고
      • 다른 페이지에서 같은 파일을 요청할 경우 캐시 사용
  • 코드 스플리팅은 그냥 되는 게 아니다.
    • CRA인 경우 웹팩 설정이 스플리팅을 지원해서 가능
    • Vite도 지원해서 가능
    • 만약 CRA나 Vite가 아니고 웹팩을 커스텀할 경우 스플리팅이 되도록 설정 필요

질문 타임

  • dynamic import로 파일을 나중에 불러오면 화면이 늦게 떠서 사용자 입장에서 안 좋을 것 같다
    • 그래서 로딩 UI를 보여주는 것
    • 번들 용량이 적기 때문에 빨리 불러오고 그 잠깐 사이에 로딩중 보여주는 것
    • 용량적 측면에서의 장점이 더 커서 코드 스플리팅은 단점이 거의 없다고 보면 됨
    • 오히려 통째로 가져오면 최초 로딩이 더 길어짐
  • 조금씩 불러오는 과정에서 layout shift가 생길 수 있지 않나?
    • next.js를 쓰면 shift가 발생하지 않음
    • 또 fallback 컴포넌트로 자리를 미리 잡아놓으면 안 생기는데
      • 이 경우 fallback과 불러올 컴포넌트의 크기가 동일해야 함

Layout Shift 관련 공식 문서 내용
'각 요소의 개별 레이아웃 이동 점수는 예상치 못한 움직임이 발생하는 경우에만 CLS로 계산됩니다. 새 요소가 DOM에 추가되거나 기존 요소의 크기가 변경되는 경우 로드된 요소가 위치를 유지하면 레이아웃 이동에 포함되지 않습니다.'

=> 로드된 요소가 위치를 유지하게 하는 법

  • width, height 설정
  • 부모 요소의 명확한 크기 설정

=> 이걸로 해결할 수 있는 현상

  • auto가 먹지 않을 때
  • next/image에서 fill 옵션을 넣을 때 발생하는 에러

intersectionObserver와 무한 스크롤

  • 코드 스플리팅의 목적
    • 최소한의 assets을 불러오게 하는 것
  • intersectionObserver도 유사한 개념
    • 보여줄 부분만 불러오는 것 (바닥에 닿았을 때) - ref와 함께 사용
    • 1000개를 다 그리느냐 vs. 화면에 보이는 10개만 그리느냐
    • 적용 시 실제 걸리는 시간이 1/10 정도로 감소

무한 스크롤과의 차이
무한 스크롤은 서버에서 뭔가를 해줘야 함
예: 10개씩 계속 서버에서 불러오는 것
애초에 전체를 다 가져오는 건 최적화할 수 없음
무한 스크롤로 서버와 협동해서 가져오는 게 훨씬 성능에 좋음
결국 백엔드에서 적은 양의 데이터를 불러오는게 하도록 하는 게 베스트

react-intersection-observer🔗
이 라이브러리를 쓰면 intersection observer를 매우 쉽게 사용 가능

bandWidth와 latency의 차이

  • bandWidth: 대역폭
    • 예: 생수의 입구 - 나올 수 있는 구멍, 여기가 막히면 병목 현상 발생
  • latency: 지연 시간
    • 원래 올 때 1초 걸려야 하는데 3초 걸리면 2초가 latency

원챌 4일차 (230811)

출근 첫 주의 여파로 졸아서 필기가 적음

Cache

  • 운영체제 안에 있음
  • 자주 사용하는 데이터를 저장해두는 것 (= 가방)
  • 관련 에러
    • serve static assets with an effecient cache policy
    • 캐시 정책을 잘못 했다 (캐시를 하면 더 빨리 불러올 수 있는데)
  • cache-control 설정해줘야 함
  • Network 탭에 Cache-Control이 있으면 캐시를 한 것
    • 첫 로딩에는 디스크 캐시로 들어가고
    • 이후 새로고침 하면 (자주 쓰는 것으로 인식해서) 메모리 캐시로 바뀜

종류 (2가지)

메모리 캐시 (가방)

  • 비교적 자주 쓰는 것

디스크 캐시 (창고)

  • 용량이 큰 경우 (가방에 안 들어감)

Font 최적화

  • font source 쓰면 asset 파일을 관리할 필요가 없음
    • woff2 포맷으로 자동 적용된 폰트 -> 용량이 매우 작)
    • Noto Sans와 비교하면 많이 차이남
  • @font-face를 쓰면 css로 인식됨
    • 자바스크립트에서 할 수 있는 게 없음
  • woff2가 제일 용량이 적음
  • 개발자 도구 Sources 들어가서 per function 옆의 녹음 버튼 누르면
    • 파일이 얼마만큼 안 쓰이고 있는지 확인 가능

purgeCSS

  • 안 쓰이는 CSS 삭제해줌
    • tailwind 쓸 때 많이 쓰임

그외 팁

  • rm -rf build : 빌드 폴더 지우기
    • 이후 다시 yarn run build
  • code .
    • 클론 받은 레포를 바로 열 때

Lock Files

  • 패키지 매니저인 npm과 yarn은 같이 쓰면 안 된다.
    • npm과 yarn을 같이 쓰면 같은 패키지인데도 다른 lock 파일을 쓰게 됨
      • 한 마디로 다른 패키지 버전으로 개발하는 것
        => 이러한 이유로 패키지 매니저는 꼭 하나만 사용한다.
  • 또한 Node 버전이 다르면 lock 파일이 달라질 수 있어서
    • 팀원끼리 node 버전 통일하는 것을 추천
  • lock 파일은 건드리지 않는다.
    • lock에 문제 생기면 지우고 새로 npm install하기
    • lock을 직접 수정하면 꼬일 수 있음

dependency와 devDependency 차이

  • dependency
    • 실제 프로젝트가 구동할 때 필요한 패키지
  • devdependency
    • 개발할 때만 필요한 패키지
    • 예: typescript, @testing-library, @types/~, babel 관련 패키지 등

Typescript

  • enum은 타입스크립트 시스템상 추천하지 않는 문법
    • 런타임 비용 얘기 있음
    • enum은 객체여서
      • 불필요한 런타임 오버헤드 초래 (규모 커지면 문제 초래)
    • 런타임 줄이려면 불변성 필요한데
      • 객체는 기본적으로 가변적
        => enum 쓰면 런타임에서 변경 가능성이 있어서 좋지 않다.
profile
데이터 분석가 준비 중입니다 (티스토리에 기록: https://cherylog.tistory.com/)

1개의 댓글

comment-user-thumbnail
2023년 8월 10일

잘 읽었습니다. 좋은 정보 감사드립니다.

답글 달기