본문 바로가기
개발/etc

웹 페이지 레이턴시 최적화

by 가시죠 2025. 1. 18.
반응형

웹 레이턴시 최적화

 

웹페이지의 로딩 속도를 개선하는 건 사용자 경험과 검색 엔진 최적화를 위해 정말 중요합니다.

여기에 웹페이지 레이턴시를 줄이는 다양한 방법을 정리 해 보겠습니다.

 

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">
반응형

댓글