본문 바로가기

FrontEnd

프론트엔드 성능 최적화 가이드 3장 스터디

반응형

해당 도서의 3장을 기반으로 진행한 스터디 입니다.

 

프론트엔드 성능 최적화 가이드

웹이 가벼워지면 사용자의 만족도는 올라간다 웹사이트를 방문했는데 페이지가 늦게 로드되면 금세 ‘뒤로 가기’ 버튼에 손이 갑니다. 구글의 연구에 따르면 페이지 표시 시간이 1초에서 3초

blog.insightbook.co.kr

홈페이지 최적화

이전 시리즈 보기
2022.11.15 - [분류 전체보기] - 프론트엔드 성능 최적화 가이드 1장 스터디

 

프론트엔드 성능 최적화 가이드 1장 스터디

해당 도서의 1장을 기반으로 진행한 스터디 입니다. 프론트엔드 성능 최적화 가이드 웹이 가벼워지면 사용자의 만족도는 올라간다 웹사이트를 방문했는데 페이지가 늦게 로드되면 금세 ‘뒤로

itchallenger.tistory.com


2022.11.15 - [웹성능최적화] - 프론트엔드 성능 최적화 가이드 2장 스터디

 

프론트엔드 성능 최적화 가이드 2장 스터디

해당 도서의 2장을 기반으로 진행한 스터디 입니다. 프론트엔드 성능 최적화 가이드 웹이 가벼워지면 사용자의 만족도는 올라간다 웹사이트를 방문했는데 페이지가 늦게 로드되면 금세 ‘뒤로

itchallenger.tistory.com


이 장에서 학습할 최적화 기법

  • 이미지 지연 로딩
  • 이미지 사이즈 최적화
  • 폰트 최적화
  • 캐시 최적화
  • 불필요한 CSS 제거

이미지 지연 로딩

  • 첫 화면에 당장 필요하지 않은 이미지가 먼저 로드되지 않도록 로드 지연
    • 우선순위 조절
  • 이전 장에서는 CDN에서 이미지 가저올 시에 고정 크기로 이미지 최적화
    • url 쿼리 수정만 하면 되서 간단했음
  • 내 서버의 정적 이미지 파일을 최적화해보자

폰트 최적화

  • 기본 폰트가 아닌 커스텀 폰트 사용시 발생할 수 있는 문제 알아보기
  • 문제 식별하고 최적화하기

캐시 최적화

  • 자주 사용되는 리소스를 브라우저에 저장해두고, 다음번에 사용하려고 할 때 저장되어 있는 것을 사용
  • 캐시를 어떻게 적용하고 활용하면 좋을 지 살펴보기

불필요한 CSS 제거

  • 사용하지 않는 CSS를 제거하여 파일 사이즈 줄이기

분석 툴 소개

크롬 개발자 도구의 Coverage 패널

  • 웹 페이지 렌더링 과정에서 어떤 코드가 실행되었는지 보여줌
  • 각 파일의 코드가 얼마나 실행되었는지 비율로 나타냄
    • 특정 파일의 실행 퍼센티지가 낮다면 불필요한 코드가 많이 포함된 것임

Sqoosh

https://squoosh.app/

 

Squoosh

Simple Open your image, inspect the differences, then save instantly. Feeling adventurous? Adjust the settings for even smaller files.

squoosh.app

  • 이미지 압축 웹서비스
  • 웹에서 간편하게 이미지의 포맷과 사이즈 변경 가능

PurgeCSS

https://purgecss.com/

 

PurgeCSS - Remove unused CSS | PurgeCSS

 

purgecss.com

  • 미사용 CSS 제거 도구
  • CLI, webpack 플러그인 형태로 사용 가능

이미지 지연 로딩

네트워크 분석

  • 네트워크 성능은 Fast 3G 혹은 Slow 3G 설정으로 분석
    • Fast 3G
      • 업로드 750kb/s
      • 다운로드 1500kb/s
    • Slow 3G
      • 업로드 330kb/s
      • 다운로드 780kb/s 
    • 커스텀 설정도 가능
      • throtlling option

custom throttling 옵션 추가

아래 그림을 보면 가장 큰 영역을 차지하는 비디오의 다운로드가 pending(하얀 막대)되는 것을 볼 수 있음

  • 다른 리소스가 먼저 로드되기 때문
    • 대역폭
  • 사용자 경험 -
  • 우선순위를 조절해 줄 필요가 있음

홈페이지의 네트워크 리소스

페이지가 로드될 때가 아닌, 화면에 보이는 순간 혹은 직전에 이미지를 로드함

  • 뷰포트에 이미지가 표시될 위치까지 스크롤 되었을 때 이미지를 로드

이미지 지연 로딩의 원리

Intersection Observer

스크롤 이벤트에 이 로직을 넣으면 해당 로직이 너무 많이 실행됨.
조금이라도 무거운 로직이 들어가면 브라우저의 메인 스레드에 무리가 감

무수히 많이 실행되는 스크롤 이벤트

  • Intersection Observer를 사용해 특정 요소를 관찰할 수 있음
    • 특정 요소가 화면에 들어왔을 때만 함수를 호출할 수 있음
      • 처음 페이지가 로드될 때애도 호출함
        • 대상 요소가 처음 관찰되는 순간에도 콜백을 실행
        • 최초에는 대상 요소가 뷰포트 안에 있는지 없는지 알 수 없기 때문
    • 성능 면에서 효율적임

https://developer.mozilla.org/en-US/docs/Web/API/Intersection_Observer_API

 

Intersection Observer API - Web APIs | MDN

The Intersection Observer API provides a way to asynchronously observe changes in the intersection of a target element with an ancestor element or with a top-level document's viewport.

developer.mozilla.org

  • 주로 가장 중요한 값은 isIntersecting 플래그임
    • 뷰포트 내에 들어왔는지 여부를 말해줌

실습 코드 : https://github.com/i0boy/frontend-performance-optimization-3/commit/18f998bcdd68d54e97636bb5ea06f72526e33809

  • 이미지 로드 후 unobserve하기
  • useEffect에서 disconnect하는것 잊지 말기
  • data-src 속성 이용하는 것 주의하기

이미지 사이즈 최적화

느린 이미지 로딩 분석

  • 지연 로딩을 적용했으나 이미지 용량 자체가 커서 다운로드 및 처리가 오래걸림
    • 느리다는 이미지를 줄 수 있음
  • 이미지 자체를 최적화 해야 함
    • 크기(사이즈, 용량)
    • 포맷(압축, 인코딩방식)

파일 크기가 큰 이미지

이미지 포맷 종류

이미지 최적화는 간단히 말하면 이미지의 가로, 세로 사이즈를 줄여 이미지 용량을 줄이고 그만큼 더 빠르게 다운로드 하는 것

사이즈 줄이기 + 압축

  • 이미지 포맷 : 비트맵
    • PNG
      • 무손실 압축 방식
      • 알파 채널(투명도) 지원
    • JPG
      • 손실 압축
      • 투명도 지원 X
      • 고화질일 필요 없거나 투명도 정보가 필요 없으면 JPG 사용
    • WebP
      • 무손실 / 손실 둘 다 지원
      • JPG, PNG에 비해 매우 효율적
      • 브라우저 호환성 고려 필요
  • 사이즈
    • PNG > JPG > WebP
  • 화질 
    • PNG = WebP > JPG
  • 호환성
    • PNG = JPG > WebP

WebP 포맷의 호환성 표

Sqoosh를 사용하여 이미지 변환

https://squoosh.app/

 

Squoosh

Simple Open your image, inspect the differences, then save instantly. Feeling adventurous? Adjust the settings for even smaller files.

squoosh.app

  • 최대 표시 사이즈를 기준으로 가로, 세로 2배로 변환
    • ex) 300 x 300px이면 600 x 600px

  • 압축 방식과 압축률(Quality)를 각각 Webp, 75로 설정
    • 압축률이 너무 크면 화질이 떨어짐
    • 압축률이 너무 작으면 용량이 커짐
    • 70~80정도가 적절
  • Effort는 CPU의 리소스를 얼마나 사용할 지
    • 기본값 4로 설정

webp로 변경 실습 : https://github.com/i0boy/frontend-performance-optimization-3/commit/bf2a303ad5073f3ada99c12b8d6537f3c036e289

  • 호환성을 고려하여 picture 태그와 src 태그 사용 가능
    • previousSibiling 속성 사용

picture 태그 실습 : https://github.com/i0boy/frontend-performance-optimization-3/commit/74ffc518cdc19f2b6f6a3b5eba0be1e32a78a33a

  • 원본 JPG 자체도 최적화 할 수 있음

JPG 압축을 위한 옵션

이미지 최적화를 통해 로딩 속도를 향상시킨 결과


동영상 최적화

동영상 컨텐츠 분석

Network 패널에서 본 동영상 다운로드

  • 동영상 파일은 이미지처럼 하나의 요청으로 모든 영상을 다운로드하지 않음
    • 재생이 필요한 앞부분을 먼저 다운로드 한 뒤 순차적으로 나머지 내용을 다운로드
    • 요청이 여러개로 나누어져 있음
  • 문제점 : 애초에 영상이 크다보니 재생하기까지 꽤 오래걸림

Performance 패널을 통해 확인해보면 일정 시간 동안 콘텐츠가 다운되고 그 이후에야 재생되는 모습을 볼 수 있음

  • 또한 assets 폴더의 동영상 파일 크기를 보면 무려 54MB임
    • 웹에서 사용하기는 너무 큼
    • 동영상 컨텐츠를 최적화하여 더욱 빠르게 재생되도록 만들 수 있음

동영상 압축

동영상 최적화는 이미지 최적화와 비슷함 : 용량을 줄임

  • 동영상의 가로와 세로 사이즈를 줄임
  • 압축방식을 변경

동영상에는 프레임 레이트(frame rate)라는 복잡한 설정이 추가로 존재

  • 동영상 특화 서비스 아니면 알 필요 없음

동영상 최적화는 화질을 낮추는 작업임

  • 동영상이 메인 컨텐츠라면 조심해야 함

웹 기반 동영상 압축 서비스 : https://www.media.io/app

 

Online Free Video Editor with Simplicity - Media.io

 

www.media.io

사용할 동영상 포맷 : WebM

  • 구글에서 개발한 웹에 최적화된 동영상 포맷
  • 호환성을 위해 mp4도 압축해서 제공할 수 있음

비트레이트를 제일 낮은 512kbps로 변경
오디오 끄기(메인 배경일 뿐임)

동영상 압축 옵션

실습 : https://github.com/i0boy/frontend-performance-optimization-3/commit/2b4e3f31e6e04336842de643228483160c5cd0f2

최적화 전 비디오 실행까지 6초가 걸렸으나 최적화 후 1초면 충분함

압축 후 동영상 로딩 과정

동영상 압축 후 전보다 빠르게 로딩되고 있으나, 화질이 많이 저하됨.
동영상 압축 시 이 점을 유의해야 함.
하지만 그럼에도 압축해야 한다면 저하된 화질을 보완할 수 있는 트릭이 있음

  • 패턴과 필터 사용
    • 동영상이 패턴과 필터에 가려져 사용자가 동영상 화질이 좋지 않음을 쉽게 인지할 수 없음
    • 사살 이 영상에는 이미 점박이 패턴이 적용됨

배너에 적용된 패턴 배경

패턴만으로 충분하지 않은 경우 filter: blur(10px) 적용

  • tailwind 사용 시 filter blur-md 정도가 적절함

패턴만으로 충분하지 않은 경우 filter: blur(10px) 적용

필터 적용 예제 보기 : https://github.com/i0boy/frontend-performance-optimization-3/commit/2b4e3f31e6e04336842de643228483160c5cd0f2#diff-6cf9f8dfd46767c5a7b0d6adcf67806fdc337a83dcc815b2a8ebef3cfb5ac4d8


폰트 최적화

크롬 개발자 도구의 Network 패널에서 throttle 설정을 Fast 3G로 설정해보자
그 후 새로고침 하면 배너의 텍스트 폰트가 변하는 것을 확인할 수 있음
이는 텍스트가 보이는 시점에 폰트 다운로드가 완료되지 않아 생기는 현상임

폰트의 변화

파일 크기가 750kb고 다운로드 하는 데 4.82초가 소요됨
즉, 폰트가 페이지 로드 후 5초 후에나 제대로 적용됨

Network 패널에서 본 폰트 다운로드 정보

이 현상은 당연히 사용성에 영향을 줌

  • 페이지의 깜빡임은 페이지가 느리다는 느낌을 줄 수 있음
  • 폰트에 의해 레이아웃 시프트 발생
    • 성능 문제
    • 사용성 문제

FOUT, FOIT

FOUT(Flash Of Unstyled Text)

  • 엣지 브라우저에서 폰트를 로드하는 방식
  • 폰트 다운로드 여부와 상관없이 먼저 텍스트를 보여준 후, 폰트가 다운로드 되면 그때 폰트를 적용함
  • 중요한 텍스트

FOIT(Flash Of Invisible Text)

  • 크롬, 사파리, 파이어폭스에서 폰트를 로드하는 방식
  • 폰트가 완전히 다운로드되기 전까지 텍스트 자체를 보여주지 않음
  • 폰트가 다운로드 완료되면 폰트가 적용된 텍스트를 보여줌
  • 3초만 기다리는 FOIT : 3초 이후에도 폰트가 다운되지 않으면 일단 기본 폰트를 보여준 뒤 다운돠면 바꿈
  • 덜 중요한 텍스트

즉 크롬 브라우저는 3초 동안은 폰트 다운로드를 기다리며 폰트를 보여주지 않다가, 3초가 지나면 기본 폰트로 보여준다.
그 다음 폰트가 다운로드되면 해당 폰트를 적용한다

FOUT vs FOIT

상황에 따라 더 적절한 방법이 있음

  • 중요한 것은 깜빡임 최소화

폰트 최적화 방법

  • 폰트 적용 시점 제어하기
  • 폰트 사이즈 줄이기

폰트 적용 시점 제어하기

  • 중요한 텍스트(뉴스 제목)은 FOUT 사용
  • 덜 중요한 텍스트(부가 설명)는 FOIT 사용
    • 시선 분산 방지

CSS의 font-display 속성 사용

  • @font-face에서 설정 가능
    • auto : 브라우저 기본 동작(default)
    • block: FOIT (timeout=3s)
    • swap : FOUT
    • fallback : FOIT (timeout=0.1s)
      • 3초 이후에도 못불러오면 기본 폰트로 유지
      • 폰트는 캐시해두어 새로고침하면 볼 수 있음
    • optional : FOIT (timeout=0.1s)
      • timeout 이후 사용자 네트워크 상태에 따라 기본 폰트로 유지하거나 변경
      • 폰트는 캐시해두어 새로고침하면 볼 수 있음

해당 실습에서는 block을 사용함

  • 화면 문구가 중요한 내용은 아니기 때문

하지만 block을 적용하면 안보이던 폰트가 갑자기 나타나 어색할 수 있음

  • fade-in 애니메이션 적용
  • 폰트 페이드 인은 js가 필요함
  • fontfaceobserver 라이브러리 사용

실습 내용 : https://github.com/i0boy/frontend-performance-optimization-3/commit/30d1d434df7c013eee41423bb696ca391967efab

폰트 파일 크기 줄이기

폰트 파일 크기를 줄이는 방법은 두 가지가 있음

  • 압축률이 좋은 폰트 포맷(확장자) 사용
    • 영상, 이미지와 동일함
  • 필요한 문자의 폰트만 로드하기
    • 서브셋

폰트 포맷 변경하기

  • TTF 및 OTF 포맷
    • 운영체제에서 사용
    • 파일 크기가 매우 큼
    • 매번 리소스를 다운로드해야 하는 웹 환경에선 적합하지 않음
  • WOFF(Web Open Font Format)
    • TTF 폰트를 압축하여 웹에서 더 빠르게 로드할 수 있도록 해줌
    • WOFF2라는 더 향상된 압축 방식을 적용한 포맷도 있음

폰트 포맷별 파일 크기 비교

WOFF와 WOFF2에도 브라우저 호환성 문제가 있기 때문에, 우선 순위 지정 필요

폰트 포맷 별 브라우저 호환성

폰트 포맷을 변경해주는 웹 서비스 : Transfonter
https://transfonter.org/

 

Online @font-face generator

The @font-face CSS rule allows web developers to specify online fonts to display text on their web pages. By allowing authors to provide their own fonts, @font-face eliminates the need to depend on the limited number of fonts users have installed on their

transfonter.org

아래와 같이 ttf 파일을 업로드하고 WOFF, WOFF2 선택
변환 후 WOFF,WOFF2 파일을 asset 폴더로 이동

  • 변환 파일에 포함된 demo.html과 stylesheet.css는 폰트 적용 예시 페이지임. 삭제해도 무방

Transfonter 서비스의 폰트 변환 옵션

  • 폰트 우선순위 적용하기
    • 적용 우선순위가 높은것부터 차례로 나열

실습 예제 : https://github.com/i0boy/frontend-performance-optimization-3/commit/d63f423abb0acf6b79aba1ba8373c99e50a2bbe0

코드 작성 후 새로고침 해보면 WOFF2 포맷의 폰트를 로드하는 것을 볼 수 있음
만약 브라우저가 지원하지 않는다면 WOFF를 로드할 것임

WOFF2 포맷의 폰트 로딩

서브셋 폰트 사용

폰트 포맷을 변경하여 파일 크기를 줄였으나 447kb는 여전히 큼

  • 사용할 문자의 폰트 정보만 추출하면 용량을 크게 줄일 수 있음
  • 일부 문자의 폰트 정보만 갖고 있는 것을 서브셋(subset) 폰트라고 함
  • fallback을 위해 ttf도 적용

서브셋 폰트 설정

파일 크기가 굉장히 줄어든 것을 볼 수 있음.

변환된 서브셋 폰트

적용 실습 코드 : https://github.com/i0boy/frontend-performance-optimization-3/commit/4277a58fcad2f59079771838cf09bf182ff6f777

쓰로틀링을 적용해도 빠르게 로딩됨을 볼 수 있음

변환된 서브셋 폰트의 로딩

한발 더 나아가 폰트를 파일 형태가 아닌 Data-URI 형태로 CSS 파일에 포함할 수 있음

  • Data-URL
    • data 스킴이 접두어로 붙은 문자열 형태의 데이터
    • 파일을 문자열 형태로 변환하여 문서(HTML, CSS, JS)에 인라인으로 삽입
  • Data-URL 형태로 CSS 파일에 넣어두면 별도의 네트워크 로드 없이 폰트 사용 가능
    • 네트워크 대역폭을 줄이기 위함임

폰트 파일을 Data-URI 형태로 App.css에 포함하려면 먼저 폰트를 문자열 데이터로 변환해야 함.
이 역시 Transfonter를 사용하면 됨
WOFF2를 업로드하고 아래와 같이 선택
(나머지 포맷들도 동일하게 해줌)

폰트의 Data-URI 변환 옵션

실습 코드 : https://github.com/i0boy/frontend-performance-optimization-3/commit/3f26b861a9d21c39ab7b0a514b371bbc1c136350

메인 페이지를 새로고침하면 Network 패널에서 폰트 파일이 기존과 달리 Data-URI 형태로 로드됨

  • 43ms로 매우 빠름
  • 브라우저는 별도의 트래픽으로 기록하지만 실제로는 다른 파일 내부에 임베드되어 있어 별도의 다운로드 시간 불필요

Data-URI 폰트의 로딩
Data-URI 폰트의 로딩 상세 정보

대신 App.css의 다운로드 속도 및 처리 속도가 증가하기 때문에 트레이드오프가 있음
또한 캐시를 활용하지 못함
대역폭 문제가 있는 네트워크 에서 혹은 폰트 용량이 매우 작을 경우 효과적인 것 같음
관련 리서치는 아래 문서 참조
https://www.zachleat.com/web/web-font-data-uris/

 

Web Font Anti-pattern: Data URIs—zachleat.com

A post by Zach Leatherman (zachleat)

www.zachleat.com


캐시 최적화

Diagnostics 섹션의 Serve static assets with an efficient cache policy를 보자
네트워크를 통해 다운로드하는 리소스에 캐시 정책을 적용하라는 뜻임.
리소스를 보내주는 서버에서 Cache-Control 헤더를 설정해 줘야 함

Lighthouse 검사결과 다시보기

캐시란?

  • 간단히 말하면 자주 사용하는 데이터나 값을 미리 복사해 둔 임시 저장공간
  • 혹은 해당 공간에 데이터나 값을 저장하는 동작

웹에서는 서비스에서 사용하는 이미지나 js같은 파일 등을 매번 네트워크를 통해 불러오지 않고 최초에만 다운로드 한 뒤, 그 뒤 요청 시 기존에 다운받은 파일을 재사용함

Lighthouse에서 캐시 관련 파일 정보를 찾을 수 있음

Lighthouse 캐시 관련 항목

번들 파일의 응답 헤더에 Cache-Control이 없음

번들 파일의 응답 헤더

캐시 종류

웹에서 사용하는 두 가지 종류의 캐시

  • 메모리 캐시
    • 메모리(RAM)에 저장하는 방식
  • 디스크 캐시
    • 파일 형태로 디스크에 저장하는 방식

어떤 캐시를 사용할지는 직접 제어할 수 없음.
브라우저가 사용 빈도나 파일 크기에 따라 특정 알고리즘을 사용하여 처리함

아래와 같이 캐시가 적용된 리소스의 응답 헤더를 보면 Cache-Control 헤더를 확인할 수 있음

  • 이 헤더는 서버에서 설정함
  • 이를 통해 브라우저는 해당 리소스를 얼마나 캐시할 지 판단함

 

메모리 캐시에서 가져온 이미지

캐시를 확인할 때는 Network 패널의 Disable cache 설정을 꺼야 함

구글에서 단순 새로고침을 한 후 확인하면 메모리 캐시가 많음
브라우저를 완전히 종료한 후 구글에 다시 접속한 뒤 네트워크 리소스를 확인하면 디스크 캐시가 많음
브라우저가 완전히 종료되면 메모리에 있는 내용은 제거하고 다음 접속 때는 파일 형태로 남아있는 캐시를 활용하기 때문

Network 패널의 캐시 정보
네트워크 리소스에서 볼 수 있는 Cache-Control 지시문

브라우저가 캐시를 하기 위해선 서버 응답 해더에 Cache-Control이 필요함을 알았음
Cache-Control은 어떤 값이 어떻게 설정되는 헤더인지 알아보자

Cache-Control

Cache-Control은 리소스의 응답 헤더에 설정되는 헤더임
브라우저는 서버에서 이 헤더를 통해 캐시를 어떻게, 얼마나 적용해야 하는 지 판단함.
Cache-Control에는 대표적으로 아래 5가지 값이 조합되어 들어감

  • no-cache
    • 캐시 사용 전에 서버 검사
    • 캐시를 사용하지 않는게 아님
      • 캐시 사용 전에 서버에서 캐시된 리소스를 사용해도 되는지 검사함
  • no-store
    • 캐시 사용 안함
    • 진짜 캐시 안쓰는 옵션
  • public
    • 모든 환경에서 캐시 사용 가능
  • private
    • 브라우저 환경에서만 캐시 사용, 외부 캐시 서버에서는 사용 불가
  • max-age
    • 캐시의 유효 시간
    • 초 단위로 얼마나 오래 캐시를 사용할 지 설정
      • max-age=60이면 60초

public과 private의 차이는 캐시 환경
웹 리소스는 브라우저뿐 아니라 웹 서버와 브라우저 사이를 연결하는 중간 서버에서도 캐시될 수 있음
중간 서버 캐시를 사용하지 않고 싶다면 private 옵션을 사용함

  • Cache-Control: max-age=60
    • 60초 동안 캐시 사용
    • 디폴트 퍼블릭, 모든 환경 캐시
  • Cache-Control: private, max-age=60
    • 브라우저 환경에서만 60초 동안 캐시 사용
  • Cache-Control: public, max-age=0
    • 모든 환경에서 0초 동안 캐시 사용
    • no-cache와 유사(매번서버검사)

캐시 적용

리액트를 빌드하고, 서빙하는 express 서버를 따로 사용함
html,css,js 별 다른 캐시 정책 실습

  • HTML
    • 일반적으로 no-cache 정책
    • 항상 최신 버전의 웹 서비스를 제공하기 위함
  • JS
    • 파일명에 해시를 함께 가지고 있음
    • 코드가 변경되면 해시도 변경되어 항상 다른 파일
    • 파일 변경되면 완전히 다른 파일이기에 아무리 오래 캐시해도 상관없음
  • CSS
    • js와 동일
  • Image
    • 보통 이미지도 JS, CSS와 동일

리소스 종류 별 캐시 설정

실습 내용 : https://github.com/i0boy/frontend-performance-optimization-3/commit/7263ab191559180374bff80449623a39eb054f2e

맨 처음에 요청하면 리소스들이 캐시되는 것을 볼 수 있음

브라우저 캐시 적용 모습
추가된 Cache-Control 헤더

만료 시간을 10초로 주었으므로, 10초 후 다시 새로고침해 보자

유효 시간이 지난 후 네트워크 상태

캐시 유효 시간이 만료되면서 브라우저는 기존에 캐시된 리소스를 재사용해도 될지, 리소스를 새로 다운로드 해야 할 지 서버에 확인함.
리소스가 변경되지 않았으면 서버에서는 304 상태 코드를 응답으로 보냄
이 경우 브라우저는 기존 리소스를 그대로 사용할 수 있음
304 코드를 받아도 서버에서 응답을 그대로 준 것처럼 취급하는것 같음

MDN 문서에 따르면 서버에서는 굳이 리스폰스를 주지 않아도 된다 함.

유효시간이 지난 후 리소스의 상태코드

  • 캐시된 리소스와 서버의 최신리소스가 같은지 다른지 어떻게 체크할까?
    • 서버에서는 캐시된 리소스의 응답 헤더에 있는 Etag 값과 서버에 있는 최신 리소스의 Etag 값을 비교함
    • 브라우저는 If-None-Match 헤더를 이용해 Etag 정보를 서버로 보냄

상세 자료 : https://withbundo.blogspot.com/2017/07/http-13-http-iii-if-match-if-modified.html

 

[HTTP 프로토콜 강좌]#13 HTTP 요청 헤더 III - If-Match, If-Modified-Since, If-None-Match

오늘은 HTTP 요청헤더 중 다음 3가지에 대해 이야기 해보려한다. If-Match If-Modified-Since If-None-Match 원래 한번에 헤더 5개씩 정리를 하려 했는데, 이번주 외근과 출장이 좀 있다보...

withbundo.blogspot.com

dcinside는 배너 이미지를 5분 간 캐싱함. 직접 테스트해보기
https://www.dcinside.com/

 

CONNECTING HEARTS! 커뮤니티 포털 디시인사이드입니다.

국내 최대 인터넷 커뮤니티 포털이자 인터넷 트렌드의 중심, 디시인사이드입니다. 힛갤, 실시간 베스트 등의 갤러리 커뮤니티 서비스를 제공합니다.

www.dcinside.com


불필요한 CSS 제거

Lighthouse 패널의 Opportunities 섹션의 Reduce unused CSS 확인

Lighthouse 검사 중 불필요한 CSS에 관한 항목

620Kib중에 616Kib를 사용하지 않고 있음.

조금 더 자세하게 살펴보기 위해 Coverage 패널 사용
Coverage 패널은 페이지에서 사용하는 자바스크립트 및 CSS 리소스에서 실제로 실행하는 코드가 얼마나 되는지 알려줌

Coverage 패널 표시 방법
Coverage 패널

상단의 새로고침 버튼을 클릭하면 페이지가 새로고침 되면서, 그 과정에서 실행한 코드를 리소스 별로 표시해 줌

Coverage 패널의 검사 결과

  • js파일은 38.9퍼센트가 사용되지 않았으나, 패널 기록 중에 앱을 사용하면 점차 비율이 올라감
    • 분기 코드 때문
    • 웹팩이 트리셰이킹 해주기도 함
  • CSS는 별다른 분기가 없어 미사용 비율을 줄여줄 필요가 있음
    • 물론 페이지 별로 사용비율이 다를 수 있으므로 진행하다 보면 사용률은 올라감

Coverage 패널을 통해 연 Sources 패널

꽤 많은 Tailwind CSS의 유틸 클래스가 사용되지 않고 있음

PurgeCSS

https://purgecss.com/

 

PurgeCSS - Remove unused CSS | PurgeCSS

 

purgecss.com

PurgeCSS는 파일에 들어있는 모든 키워드를 추출하여 해당 키워드를 이름으로 갖는 CSS 클래스만 보존하고
나머지 매칭되지 않는 클래스는 모두 지우는 방식으로 CSS 파일을 최적화함

PurgeCSS에서 키워드를 추출하는 기준

디폴트 추출기준이 tailwind 네이밍 규칙을 반영하도록 config를 수정해 주어야 함.
:를 키워드로 인식하지 않고 잘라버리기 때문임.

module.exports = {
  defaultExtractor: (content) => content.match(/[\w-/:]+/g) || [],
};
  • content로 대상 파일의 전체 코드를 넘겨받고 문자열 배열을 반환함
    • 이 문자열 배열이 추출할 css 클래스명 배열임

최적화 실습 내용 : https://github.com/i0boy/frontend-performance-optimization-3/commit/922067b78a2f86518383124f2707da03ba8f2269

PurgeCSS를 실행한 뒤 용량이 많이 줄은 것을 본 적 있음.
만약 실습할 때 용량이 그대로면 개발자 도구를 열고 새로고침 버튼을 꾸욱 클릭한 뒤, Empty Cache and Hard Reload 해보기

PurgeCSS 실행 후 Coverage 패널의 검사 결과

 

반응형