개발 공부 기록

프론트엔드 웹 성능 최적화 - 2 본문

개발

프론트엔드 웹 성능 최적화 - 2

_김도연 2025. 1. 20. 08:48

이미지 레이지(lazy) 로딩

Intersection Observer

웹 애플리케이션에서 특정 요소가 뷰포트(Viewport)나 지정된 부모 컨테이너의 가시 영역과 교차할 때 이를 비동기적으로 관찰할 수 있게 해주는 API

 

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

useEffect(() => {
    const options = {};
    
    const callback = (entries, observer) => {
    	entries.forEach(entry => {
        	if(entry.isIntersecting) {
            	entry.target.src = entry.target.dataset.src;
                observer.unobserve(entry.target);
            }
        	
        });
    }
}, []);

<img data-src={props.imgae} ref={imgRef} />

 

 

react-lazyload

https://www.npmjs.com/package/react-lazyload

 

react-lazyload

Lazyload your components, images or anything where performance matters.. Latest version: 3.2.1, last published: 10 months ago. Start using react-lazyload in your project by running `npm i react-lazyload`. There are 459 other projects in the npm registry us

www.npmjs.com

 


이미지 사이즈 최적화

PNG - 무손실 압축. 상대적으로 용량 큰편

JPG - 압축. 약간의 화질 저하

WEBP - 구글에서 만든 최근의 이미지 포맷. 지원하지 않는 브라우저도 있음.

              JPG에 비해 용량, 화질면에서 성능이 좋음

 

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

ㄴ이미지파일을 압축, webp 파일로 변환할 수 있는 사이트

 

<picture> 태그

https://developer.mozilla.org/en-US/docs/Web/HTML/Element/picture

 

<picture>: The Picture element - HTML: HyperText Markup Language | MDN

The <picture> HTML element contains zero or more <source> elements and one <img> element to offer alternative versions of an image for different display/device scenarios.

developer.mozilla.org

ㄴ 조건을 설정하여 사이즈나 확장자에 따라 다른 이미지를 로드할 수 있음


동영상 최적화

동영상 압축기 이용

 

<video> 태그에도 동일하게 여러개의 소스 지정가능(가능한 우선순위로 실행)

https://developer.mozilla.org/en-US/docs/Web/HTML/Element/video

 

<video>: The Video Embed element - HTML: HyperText Markup Language | MDN

The <video> HTML element embeds a media player which supports video playback into the document. You can use <video> for audio content as well, but the <audio> element may provide a more appropriate user experience.

developer.mozilla.org

 


폰트 최적화

FOUT - 폰트 불러오기 전에 기본텍스트 보여주고 나중에 폰트 적용

FOIT - 폰트가 안불러와졌다면 텍스트를 안보여주고 한번에 적용된 글로 보여줌

 

웹폰트의 최적화 방법

1. 폰트 적용 시점 컨트롤하기

2. 폰트 사이즈 줄이기

 

폰트 적용 시점 컨트롤하기

https://developer.mozilla.org/ko/docs/Web/CSS/@font-face/font-display

 

font-display - CSS: Cascading Style Sheets | MDN

font-display 설명자(descriptor)는 font face가 표시되는 방법을 결정합니다. 이는 다운로드 여부와 사용 시기에 따라 다릅니다.

developer.mozilla.org

https://www.npmjs.com/package/fontfaceobserver

 

fontfaceobserver

Detect if web fonts are available. Latest version: 2.3.0, last published: 3 years ago. Start using fontfaceobserver in your project by running `npm i fontfaceobserver`. There are 548 other projects in the npm registry using fontfaceobserver.

www.npmjs.com

 

 

폰트 사이즈 줄이기

웹폰트 포멧 사용

TFF/OTF -> 웹에서 더 사용하기 좋게, 더 효율적으로 -> WOFF/WOFF2

 

파일크기

TTF/OTF > WOFF > WOFF2

 

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

local 폰트 사용

@font-face {
	font-family: FONTNAME;
	src: loca("FONTNAME"), // 사용자 컴퓨터에 설치되어 있는 경우
    	 url(".../FONTNAME.woff2") format("woff2"),
         url(".../FONTNAME.woff") format("woff"),
    	 url(".../FONTNAME.ttf") format("truetype"),
}

 

 

Subset 사용

내가 사용하는 글자만 포함시켜서 폰트 파일 압축

 

Unicode Range 적용

font-face의 CSS 속성

내가 지정한 범위의 유니코드만 불러올 수 있음

 

data-uri로 변환

네트워크 리소스 절약 가능

 

preload

<link rel="preload" href="FONTNAME" as="font" type="font/woff2" crossorigin>

preload 지정하여 가장 먼저 로딩할 수 있음

https://www.npmjs.com/package/preload-webpack-plugin

 

preload-webpack-plugin

Enhances html-webpack-plugin with link rel=preload wiring capabilities for scripts. Latest version: 2.3.0, last published: 7 years ago. Start using preload-webpack-plugin in your project by running `npm i preload-webpack-plugin`. There are 87 other project

www.npmjs.com

webpack 사용중이라면 설정추가해주기

plugins: [
  new PreloadWebpackPlugin({
    rel: 'preload',
    as: 'font',
    include: 'allAssets',
    fileWhitelist: [/(.woff2?)/i]
  })
]

캐시 최적화

캐시 - 데이터나 값을 미리 복사해 놓는 임시 장소나 그런 동작

 

캐시 방식 (사용자가 결정X. 브라우저 동작 방식을 따라감)

1. 메모리 캐시 

2. 디스크 캐시

 

캐시 지정

Response Headers에 Cache-Control 를 설정해서 보내줘야 함

 

설정 값

  • no-cache: 캐시를 사용하기 전에 서버에 검사 후, 사용 결정
  • no-store: 캐시 사용 안 함
  • public: 모든 환경에서 캐시 사용 가능
  • private: 브라우저 환경에서만 캐시 사용, 외부 캐시 서버에서는 사용 불가 (ex. 로그인 정보 등)
  •  max-age: 캐시의 유효시간

html 파일은 no-cache

js, css, img 파일은 hash 값이 파일명에 붙으니 긴 기간으로 max-age 지정 (ex. public, max-age=31536000)

 

const header = {
	setHeaders: (res, path) => {
    	if(path.endsWith(".html")) {
        	res.setHeader("Cache-Control", "no-cache")
        } else if(path.endsWith(".js") || path.endsWith(".css") || path.endsWith(".webp2")) {
        	res.setHeader("Cache-Control", "public, max-age=31536000")
        } else {
        	res.setHeader("Cache-Control", "no-cache")
        }
    },
}

app.use(express.static(path.join(__dirname, "../build"), header))

불필요한 CSS 제거

Coverage 탭에서 코드 사용량을 검사할 수 있음

빨간색 - 사용하지 않은 코드

검은색 - 사용한 코드

 

https://purgecss.com/

 

PurgeCSS - Remove unused CSS | PurgeCSS

 

purgecss.com

ㄴ Class 네임에 포함되지 않은 클래스들을 다 제거하고 필요한 코드만 남김


Layout Shift 피하기

원인

- 사이즈가 정해져 있지 않은 이미지

- 사이즈가 정해져 있지 않은 광고

- 동적으로 삽입된 콘텐츠

- Web font (FOIT, FOUT)

 

 

'개발' 카테고리의 다른 글

프론트엔드 웹 성능 최적화  (0) 2025.01.14
Comments