웹페이지의 로딩 속도를 개선하는 건 사용자 경험과 검색 엔진 최적화를 위해 정말 중요합니다.
여기에 웹페이지 레이턴시를 줄이는 다양한 방법을 정리 해 보겠습니다.
1. HTTP 요청 최소화
1.1 파일 병합 및 최소화
CSS와 JavaScript 파일을 병합하고, 불필요한 공백과 주석을 제거하여 HTTP 요청을 줄입니다.
병합 후에는 최소화된(minified) 파일을 생성해 사용하세요.
CSS 병합 전:
/* style1.css */
body {
margin: 0;
padding: 0;
}
/* style2.css */
h1 {
color: blue;
font-size: 24px;
}
CSS 병합 및 최소화 후:
/* merged.min.css */
body{margin:0;padding:0}h1{color:blue;font-size:24px}
JavaScript 병합 전:
// script1.js
function greet() {
console.log('Hello, world!');
}
// script2.js
function farewell() {
console.log('Goodbye, world!');
}
JavaScript 병합 및 최소화 후:
// merged.min.js
function greet(){console.log("Hello, world!")}function farewell(){console.log("Goodbye, world!")}
1.2 이미지 스프라이트 사용
여러 개의 작은 이미지를 하나의 큰 이미지로 결합한 후 CSS로 필요한 부분만 표시합니다.
이미지 스프라이트 CSS 예제:
.sprite {
background-image: url('sprite.png');
background-repeat: no-repeat;
}
.icon-home {
background-position: 0 0;
width: 32px;
height: 32px;
}
.icon-settings {
background-position: -32px 0;
width: 32px;
height: 32px;
}
2. 브라우저 캐싱
정적 리소스를 캐싱하면 브라우저가 동일한 리소스를 다시 요청하지 않아도 됩니다.
Apache 서버 설정 예제:
<IfModule mod_expires.c>
ExpiresActive On
ExpiresByType text/css "access plus 1 week"
ExpiresByType application/javascript "access plus 1 week"
ExpiresByType image/jpeg "access plus 1 month"
ExpiresByType image/png "access plus 1 month"
</IfModule>
Nginx 서버 설정 예제:
location ~* \.(jpg|jpeg|png|gif|ico|css|js)$ {
expires 30d;
log_not_found off;
}
3. 데이터베이스 쿼리 최적화
3.1 인덱스 사용
데이터베이스 쿼리의 속도를 높이기 위해 자주 검색하는 컬럼에 인덱스를 생성합니다.
SQL 예제:
CREATE INDEX idx_user_email ON users (email);
3.2 필요한 데이터만 SELECT
SELECT * 대신 필요한 컬럼만 명시합니다.
비효율적인 쿼리:
SELECT * FROM users WHERE email = 'user@example.com';
효율적인 쿼리:
SELECT id, name FROM users WHERE email = 'user@example.com';
3.3 조인 최적화
테이블 조인의 순서를 최적화하거나 서브쿼리를 대체합니다.
비효율적인 쿼리:
SELECT * FROM orders WHERE user_id IN (SELECT id FROM users WHERE email = 'user@example.com');
효율적인 쿼리:
SELECT o.* FROM orders o
JOIN users u ON o.user_id = u.id
WHERE u.email = 'user@example.com';
3.4 쿼리 캐싱
자주 실행되는 쿼리의 결과를 캐싱하면 성능을 크게 개선할 수 있습니다.
쿼리 캐싱(Query Caching)은 데이터베이스에서 자주 사용되는 쿼리의 결과를 캐시하여 동일한 쿼리가 실행될 때 데이터베이스를 직접 조회하지 않고 캐시된 결과를 반환하도록 하는 방식입니다. 이를 통해 데이터베이스 부하를 줄이고 응답 속도를 개선할 수 있습니다.
주의사항) 쿼리 캐싱의 한계
1. 캐시된 데이터는 데이터베이스가 변경되었을 때 최신 상태를 보장하지 못할 수 있습니다.
→ 이를 해결하려면 캐시 무효화(Invalidate) 로직을 구현해야 합니다.
2. 읽기와 쓰기가 빈번히 발생하는 시스템에서는 캐싱이 성능을 저하할 가능성이 있습니다.
4. 데이터베이스 비정규화
정규화가 원칙이지만 성능을 우선시 한다면 때로는 비정규화를 해야 할 수 있습니다.
비정규화를 통해 테이블 간 조인을 줄이고 조회 성능을 높일 수 있습니다.
정규화된 테이블 예제:
-- 사용자 테이블
CREATE TABLE users (
id SERIAL PRIMARY KEY,
name VARCHAR(50),
email VARCHAR(100)
);
-- 주문 테이블
CREATE TABLE orders (
id SERIAL PRIMARY KEY,
user_id INT REFERENCES users(id),
product_name VARCHAR(50)
);
비정규화된 테이블 예제:
-- 비정규화된 주문 테이블
CREATE TABLE orders (
id SERIAL PRIMARY KEY,
user_name VARCHAR(50),
user_email VARCHAR(100),
product_name VARCHAR(50)
);
5. CDN(Content Delivery Network) 사용
CDN을 활용하면 콘텐츠를 사용자와 가까운 서버에서 제공해 네트워크 레이턴시를 줄일 수 있습니다.
CDN 예제:
<script src="https://cdn.jsdelivr.net/npm/jquery@3.6.0/dist/jquery.min.js"></script>
6. 이미지 최적화
6.1 WebP 형식 사용
이미지를 WebP 형식으로 변환하여 파일 크기를 줄입니다.
명령어 예제:
cwebp input.jpg -o output.webp
6.2 지연 로딩(Lazy Loading)
사용자가 화면을 스크롤할 때 필요한 이미지만 로드합니다.
HTML 및 JavaScript 예제:
<img src="placeholder.jpg" data-src="image.jpg" class="lazyload" />
<script>
document.addEventListener("DOMContentLoaded", function() {
const lazyImages = document.querySelectorAll('.lazyload');
lazyImages.forEach(img => {
img.src = img.dataset.src;
});
});
</script>
7. 비동기 및 지연 로딩
JavaScript 비동기 로딩
<script async src="script.js"></script>
CSS 비동기 로딩
<link rel="stylesheet" href="styles.css" media="print" onload="this.media='all';">
8. 압축 사용
Gzip이나 Brotli 압축을 사용하여 전송 데이터를 줄입니다.
Nginx 설정 예제:
gzip on;
gzip_types text/plain text/css application/json application/javascript;
9. Critical Rendering Path 최적화
최소한의 CSS와 JavaScript만 초기 렌더링에 포함시켜 페이지 로딩 속도를 개선합니다.
Critical Rendering Path(CRP)란 브라우저가 HTML, CSS, JavaScript를 처리해 화면에 내용을 렌더링하는 과정을 말합니다.
최적화는 이 과정을 단축하여 페이지가 사용자에게 더 빨리 표시되도록 하는 것입니다.
CRP 3가지 단계
1. DOM(Document Object Model) 생성 : 브라우저가 HTML을 파싱해 DOM 트리를 생성.
2. CSSOM(CSS Object Model) 생성 : CSS 파일을 파싱해 CSSOM 트리를 생성.
3. 렌더 트리(Render Tree) 생성 및 렌더링 : DOM과 CSSOM을 결합해 렌더 트리를 생성하고 화면에 그림.
최적화 전 코드
<!DOCTYPE html>
<html lang="en">
<head>
<title>Slow Page</title>
<script src="script.js"></script>
<link rel="stylesheet" href="styles.css">
</head>
<body>
<h1>Hello World</h1>
</body>
</html>
최적화 후 코드
<!DOCTYPE html>
<html lang="en">
<head>
<title>Fast Page</title>
<!-- 필수 스타일 인라인 -->
<style>
body { margin: 0; font-family: Arial, sans-serif; }
h1 { color: blue; }
</style>
<!-- 비필수 스타일 지연 로드 -->
<link rel="stylesheet" href="styles.css" media="print" onload="this.media='all';">
<!-- JavaScript 비동기 로딩 -->
<script async src="script.js"></script>
</head>
<body>
<h1>Hello Optimized World</h1>
</body>
</html>
10. DNS 프리패칭 및 사전 로딩
DNS 프리패칭
<link rel="dns-prefetch" href="//example.com">
리소스 사전 로딩
<link rel="preload" href="main.css" as="style">
'개발 > etc' 카테고리의 다른 글
윈도우에서 사용 가능한 오픈소스 및 무료 웹 취약점 분석 도구 (0) | 2025.01.19 |
---|---|
오즈리포트 바코드 출력 예제 (0) | 2021.03.18 |
열두가지 애자일 원칙 (0) | 2021.02.14 |
댓글