웹 개발을 하다 보면 성능 최적화는 필수적인 주제이다.
특히 브라우저가 웹 페이지를 렌더링할 때 어떻게 리소스를 효율적으로 관리하고 성능을 최적화하는지에 대한 이해는 프론트엔드 개발자로서 매우 중요하다.
이번 포스팅에서는 브라우저가 리소스를 로드하는 과정에서 성능을 최적화하기 위해 사용하는 다양한 기법들을 정리해보고자 한다.
1. HTTP/2 프로토콜 사용
기본적으로 브라우저는 네트워크 연결을 통해 서버에서 HTML, CSS, JavaScript 등 다양한 리소스를 다운로드한다.
이때 최신 HTTP/2 프로토콜은 성능을 크게 향상시킨다. 이전의 HTTP/1.1에서는 하나의 연결당 하나의 리소스만 순차적으로 요청할 수 있었다. 하지만 HTTP/2에서는 하나의 TCP 연결에서 여러 리소스를 동시에 병렬로 요청할 수 있어 병목 현상이 줄어들고 페이지 로드 시간이 단축된다.
추가 팁: HTTP/2는 기본적으로 멀티플렉싱(multiplexing)을 지원하므로, CSS, JS, 이미지 등 여러 리소스를 병렬로 처리할 수 있다. 최신 웹 서버에서 HTTP/2를 활성화하고 클라이언트 브라우저가 이를 지원하도록 하는 것이 중요하다.
2. 캐싱(Caching)
브라우저는 자주 사용하는 리소스를 캐시에 저장하여, 동일한 리소스를 다시 요청할 때 서버에서 받아오는 대신 캐시에서 가져온다. 이를 통해 네트워크 요청 시간을 절약하고, 페이지 로드 속도를 크게 개선할 수 있다. 특히 이미지, CSS, JavaScript와 같은 정적인 파일에 캐싱을 적용하면 성능 향상에 큰 도움이 된다.
- 브라우저 캐시: 브라우저는 로컬에 리소스를 저장해두고, 다음 요청 시 캐시된 버전을 사용한다.
- HTTP 캐싱: 서버에서 Cache-Control, ETag 같은 헤더를 통해 리소스의 캐싱 정책을 제어할 수 있다.
추가 팁: 정적 리소스의 캐시 만료일을 설정하여 변경된 경우에만 다시 로드되도록 할 수 있다. 이를 통해 불필요한 네트워크 요청을 줄일 수 있다.
3. 리소스 우선순위 지정
브라우저는 리소스를 로드할 때 우선순위를 부여해, 중요한 리소스는 먼저 로드하고 덜 중요한 리소스는 나중에 로드한다.
예를 들어, 화면에 먼저 표시되어야 할 크리티컬 렌더링 패스에 포함된 CSS와 JavaScript는 우선적으로 로드된다. 반면에 스크롤을 해야 볼 수 있는 이미지나 추가적인 데이터를 로드하는 비동기 요청은 나중으로 미뤄진다.
- 크리티컬 렌더링 패스(Critical Rendering Path) : 브라우저가 HTML, CSS, JavaScript를 스크린에 픽셀로 나타내는 과정
추가 팁: 필수적인 CSS 파일은 HTML `<head>` 부분에 배치하고, 중요도가 낮은 스크립트는 `<body>` 태그의 끝부분에 배치하여 먼저 콘텐츠가 렌더링될 수 있도록 유도하는 것이 좋다.
4. Lazy Loading (지연 로딩)
이미지나 동영상과 같은 무거운 리소스는 페이지가 처음 로드될 때 모두 로딩하지 않고, 사용자가 해당 콘텐츠를 필요로 할 때 로드하는 Lazy Loading 기법을 사용할 수 있다. 예를 들어, 사용자가 페이지를 스크롤하여 이미지가 화면에 보여질 때만 해당 이미지를 로드하게 하면 페이지의 초기 로딩 속도를 크게 개선할 수 있다.
HTML5에서는 `<img>` 태그에 `loading="lazy"` 속성을 추가하는 것만으로도 간편하게 지연 로딩을 구현할 수 있다.
<img src="image.jpg" loading="lazy" alt="Lazy Loaded Image" />
추가 팁: Lazy Loading은 이미지뿐만 아니라, iframe 콘텐츠에도 적용할 수 있다. 다만, 주의할 점은 너무 많은 지연 로딩을 남발하면 렌더링 지연이 발생할 수 있으니 중요한 리소스는 로딩을 지연시키지 않는 것이 좋다.
5. 압축(Compression)
브라우저는 서버로부터 리소스를 받을 때, Gzip이나 Brotli와 같은 압축 기술을 사용해 파일 크기를 줄일 수 있다.
서버에서 압축된 데이터를 보내고, 브라우저는 이를 해제해 로드하는 방식이다.
이를 통해 데이터 전송량을 줄일 수 있어 네트워크 대역폭을 절약하고, 특히 대용량 리소스의 경우 성능 향상이 크게 나타난다.
추가 팁: 웹 서버 설정에서 Gzip이나 Brotli 압축을 활성화하고, JS 및 CSS 파일은 minify하여 용량을 줄이면 훨씬 더 빠르게 리소스를 전송할 수 있다.
6. Preload, Prefetch, Preconnect
브라우저는 리소스 로딩을 더 빠르게 하기 위해 다양한 리소스 힌트를 사용한다.
이러한 힌트를 통해 브라우저는 필요한 리소스를 미리 로드하거나, 서버와의 네트워크 연결을 미리 준비할 수 있다.
- Preload: 페이지 렌더링에 꼭 필요한 리소스를 미리 로드한다.
<link rel="preload" href="style.css" as="style">
- Prefetch: 앞으로 필요할 리소스를 미리 로드하여 사용자가 다음 페이지로 이동할 때 빠르게 로딩할 수 있도록 준비한다.
<link rel="prefetch" href="next-page.js">
- Preconnect: 서버와의 연결을 미리 설정하여, 네트워크 요청 시 연결 시간을 줄인다.
<link rel="preconnect" href="https://example.com">
추가 팁: 웹폰트 파일 로딩 시 preconnect와 preload를 잘 활용하면, 초기 로드 시간을 단축할 수 있다.
7. JavaScript 비동기 로딩
JavaScript 파일은 기본적으로 파싱 차단 요소이다.
즉, JavaScript가 로드될 때 다른 리소스의 로딩이 멈추고 JavaScript가 모두 로드되고 실행된 후에야 다른 리소스를 처리할 수 있다. 이를 해결하기 위해 `async`와 `defer` 속성을 사용하여 JavaScript를 비동기적으로 로드할 수 있다.
- `async`: JavaScript 파일을 병렬로 로드하고, 로드가 완료되면 바로 실행한다.
<script src="script.js" async></script>
- `defer`: HTML 파싱이 완료된 후 JavaScript 파일을 실행한다.
<script src="script.js" defer></script>
추가 팁: `async`는 독립적인 스크립트에 사용하고, `defer`는 DOM 조작을 필요로 하는 스크립트에 적용하면 효율적이다.
이를 통해 페이지 로딩 성능을 최적화할 수 있다.
정리
브라우저가 리소스를 로드하는 과정에서 성능을 최적화하기 위해 사용하는 다양한 기법들을 이해하고 적절하게 적용하는 것은 페이지 로딩 속도를 크게 향상시킬 수 있으므로, 웹 프론트 엔드 개발자가 알고 있으면 좋은 상식들이다.
'개발 > 프론트엔드' 카테고리의 다른 글
| 왜 Redux 대신 Redux Toolkit을 사용하는가? (4) | 2024.12.23 |
|---|---|
| CSR 환경에서 OG 태그 사용의 해결 방안은 무엇일까? (5) | 2024.10.27 |
| 프론트엔드 개발자가 알아야 할 백엔드 JWT 인증 및 권한 관리 (1) | 2024.09.29 |
| Flux 패턴 (2) | 2024.09.17 |
| 프론트엔드 개발자가 많이 사용하는 그 프레임워크(또는 라이브러리)들을 비교해보쟈 (3) | 2024.09.08 |