프론트엔드가 할 수 있는 성능 최적화에 대해 알아보자!
코드 번들링 및 압축
웹팩(Webpack) 같은 도구를 사용하여 자바스크립트 및 스타일 시트 코드를 번들링하고 압축
-> 파일 크기가 줄어들어 로딩 시간이 단축
코드 번들링과 압축은 웹 애플리케이션의 자바스크립트와 스타일시트 코드를 하나의 파일로 묶어주고, 필요한 경우 코드를 최소화하여 파일 크기를 줄이는 작업
->초기 로딩 속도를 개선하고 대역폭을 절약
주로 웹팩(Webpack)이나 Parcel 같은 도구를 사용하여 코드 번들링 및 압축을 수행
코드 번들링
여러 개의 파일을 하나의 번들로 묶는 과정을 의미
이때, 여러 파일 간의 의존성 관계를 파악하고, 필요한 모듈만 포함하여 최종 번들 파일 생성
번들링을 통해 여러 파일의 로딩 시간을 줄이고 네트워크 요청을 최소화
웹팩
- 더 복잡한 설정과 다양한 기능을 제공
필요에 따라 로더, 플러그인, 코드 스플리팅, 동적 임포트 등을 활용하여 더 세밀하게 코드 번들링 및 압축을 조정 - 코드 번들링과 최적화 작업을 수행하는 도구
개발자가 작성한 여러 개의 자바스크립트 파일과 스타일시트 파일을 하나로 묶어주고, 필요한 최적화 작업을 자동으로 처리하여 애플리케이션의 성능 향상 - 코드를 최적화하여 파일 크기를 줄여주는 기능도 제공
자바스크립트 코드를 압축하고 불필요한 공백, 주석 등을 제거하여 파일 크기를 최소화
최적화 작업을 통해 초기 로딩 속도를 개선하고 대역폭을 절약
따라서 개발자는 웹팩을 설정하고 실행함으로써 코드 번들링과 최적화 작업 자동 수행
웹팩은 이러한 작업을 간편하게 수행하면서도 다양한 확장성과 커스터마이징 옵션을 제공하여 프로젝트의 요구 사항에 맞게 최적화를 조정할 수 있도록 도와줌
웹팩 기반 코드 번들링과 압축
1. 웹팩 설치: 프로젝트 루트 디렉토리에서 웹팩과 관련된 패키지 설치
npm install webpack webpack-cli --save-dev
2. 웹팩 설정 파일 생성: 프로젝트 루트에 webpack.config.js 파일을 생성하고 웹팩 설정 정의
// webpack.config.js
const path = require('path');
module.exports = {
entry: './src/index.js', // 애플리케이션 진입점
output: {
filename: 'bundle.js', // 번들된 파일 이름
path: path.resolve(__dirname, 'dist') // 번들된 파일이 저장될 경로
}
};
3. 웹팩 로더 설정: 웹팩에서는 다양한 로더를 사용하여 다양한 파일 형식을 처리
예를 들어, Babel 로더를 사용하여 ES6+ 코드 -> ES5로 변환
// webpack.config.js
module.exports = {
// ...
module: {
rules: [
{
test: /\.js$/, // .js 확장자를 가진 파일에 로더 적용
exclude: /node_modules/,
use: {
loader: 'babel-loader'
}
}
]
}
};
4. 웹팩 실행: 웹팩 명령어를 사용하여 번들링을 수행
npx webpack
위의 단계를 따라 웹팩을 설정하고 실행하면, src/index.js 파일을 번들하고 dist/bundle.js 파일을 생성
이때, 자바스크립트 코드는 최소화되어 압축
이미지 최적화
이미지를 최적화하여 파일 크기를 줄인다.
이미지 포맷 선택, 압축, 스프라이트 이미지, 이미지 지연 로딩(Lazy Loading) 등을 고려
웹 애플리케이션의 성능을 향상시키기 위해 이미지 파일의 크기를 줄이고 로딩 속도를 개선하는 작업
이미지 최적화를 통해 페이지의 로딩 속도를 개선하고 대역폭을 절약
- 이미지 포맷 선택: 적절한 이미지 포맷을 선택하여 사용합니다. 일반적으로 JPEG는 사진이나 복잡한 이미지에, PNG는 투명도가 필요한 이미지에, GIF는 애니메이션 이미지에 적합합니다. 최신 웹포맷인 WebP도 고려
- 이미지 압축: 이미지 파일을 압축하여 파일 크기를 줄입니다. 온라인 이미지 최적화 도구나 이미지 편집 소프트웨어를 사용하여 압축
- 이미지 크기 조정: 이미지의 크기를 웹에서 표시하는 크기에 맞게 조정합니다. 불필요한 큰 이미지를 사용하지 않도록 주의
- 스프라이트 이미지: 여러 개의 작은 이미지를 하나의 이미지로 결합하여 사용합니다. 이를 통해 여러 개의 이미지 요청을 하나로 줄여 로딩 속도를 개선
- 이미지 지연 로딩: 화면에 표시되지 않은 이미지를 늦게 로딩하도록 설정합니다. 사용자가 스크롤을 내리면 해당 이미지가 로딩되도록 하는 방식
- 레티나 이미지: 고해상도 디스플레이에서도 선명하게 보이도록 레티나 이미지를 제공합니다. 레티나 이미지는 더 큰 이미지 파일이므로 압축과 함께 사용
- 캐싱: 이미지를 브라우저 캐시에 저장하여 재로딩 시간을 줄입니다. 변경되지 않는 이미지는 캐시를 활용하여 로딩 속도를 개선
- Lazy Loading: 페이지의 중요한 부분에 로딩이 필요한 이미지를 먼저 로딩하고, 나머지 이미지는 필요할 때 로딩하는 방식을 사용
- Content Delivery Network (CDN): 이미지를 전 세계에 분산된 서버로 제공하는 CDN을 활용하여 로딩 속도를 개선
온라인 이미지 최적화 도구나 이미지 편집 소프트웨어를 사용하여 이미지를 압축하고 크기를 조정
웹페이지의 성능을 모니터링하고 필요한 최적화 작업을 식별하는 것도 중요
렌더링 최적화
불필요한 리렌더링을 줄이고 성능을 향상시키기 위해 React의 PureComponent나 React.memo를 활용
웹 애플리케이션의 성능을 향상시키기 위해 화면을 그릴 때 발생하는 렌더링 과정을 최적화하는 작업
사용자 경험을 향상시키고 웹 페이지의 반응성을 개선
- Virtual DOM 활용: React와 같은 라이브러리에서 사용하는 Virtual DOM을 활용하여 실제 DOM 조작을 최소화합니다. Virtual DOM은 메모리에 가상의 DOM 트리를 구성하고 변경된 부분만 실제 DOM에 반영하여 렌더링 성능을 개선
- PureComponent 및 React.memo 사용: PureComponent와 React.memo를 사용하여 불필요한 리렌더링을 방지합니다. 변경된 데이터만 업데이트하여 성능을 향상
- React에서 컴포넌트의 성능을 최적화하는 데 사용되는 두 가지 고급 리액트 컴포넌트
- PureComponent
Component 클래스를 확장한 특별한 유형의 컴포넌트입니다. PureComponent는 자체적으로 얕은(shallow) 비교를 수행하여 props와 state의 변경 사항을 감지하고, 변경이 없으면 리렌더링을 방지하여 성능을 최적화
import React, { PureComponent } from 'react';
class MyComponent extends PureComponent {
render() {
return <div>{this.props.data}</div>;
}
}
PureComponent를 사용할 때 주의할 점은 내부적으로 얕은 비교(shallow comparison)를 수행하기 때문에 복잡한 데이터 구조를 가진 props나 state에서는 원하는 결과가 나오지 않을 수 있습니다. 따라서 얕은 비교의 한계를 이해하고 사용하는 것이 중요
- React.memo
React.memo는 함수 컴포넌트의 리렌더링을 제어하는 데 사용되는 함수입니다. React.memo는 컴포넌트를 감싸는 형태로 사용하며, 이를 통해 이전 props와 현재 props를 비교하여 변경이 없으면 리렌더링을 방지
import React from 'react';
const MyComponent = React.memo((props) => {
return <div>{props.data}</div>;
});
클래스 컴포넌트의 PureComponent와 유사한 역할을 하지만, 함수 컴포넌트에 적용됩니다. 함수 컴포넌트의 경우 React.memo를 사용하여 리렌더링을 최적화할 수 있습니다.
두 경우 모두 컴포넌트의 성능을 향상시키기 위해 사용되는 기술입니다. 어떤 방법을 선택할지는 프로젝트의 특성과 요구 사항에 따라 다르며, 각각의 동작 원리와 제약 사항을 잘 이해하여 사용하는 것이 좋습니다.
- 컴포넌트 분할: 큰 규모의 컴포넌트를 작은 단위로 분할하여 로딩 시간을 줄이고 렌더링 속도를 개선
- 레이지 로딩: 필요한 컴포넌트만 로딩하도록 코드 스플리팅과 레이지 로딩을 활용합니다. 사용자가 실제로 필요한 시점에 컴포넌트를 로딩하여 초기 로딩 속도를 개선
- Memoization: 복잡한 계산을 자주 반복하는 경우 결과를 캐시하고 재사용하는 방식을 사용하여 계산량을 줄입니다.
- 컴퓨터 프로그래밍에서 사용되는 최적화 기법 중 하나로, 계산 비용이 높은 함수의 결과를 한 번 계산한 후 저장하여 이후 동일한 입력이 들어올 때 다시 계산하지 않고 저장된 값을 반환하는 것을 말합니다. 이를 통해 함수 호출의 반복적인 연산을 줄이고 성능을 향상
- 재귀적인 알고리즘에서 중복 계산을 피하거나, 동일한 입력에 대한 함수 호출 결과를 캐시하여 성능을 개선하는 데 사용
function factorial(n, memo = {}) {
if (n in memo) {
return memo[n]; // 이미 계산한 값이라면 캐시된 결과 반환
}
if (n === 0) {
return 1;
}
memo[n] = n * factorial(n - 1, memo); // 계산한 결과를 캐시에 저장
return memo[n];
}
console.log(factorial(5)); // 120
factorial 함수는 캐시 객체 memo를 활용하여 이미 계산한 팩토리얼 값을 저장하고 필요할 때마다 캐시된 값을 반환합니다. 이렇게 하면 중복 계산을 피하고 계산 비용을 줄일 수 있습니다
메모이제이션은 동적 프로그래밍 등에서 많이 활용되며, 재귀적인 알고리즘을 최적화하는 데에도 유용하게 사용
메모이제이션을 적용하면 함수 호출 횟수를 줄이고 계산 비용을 절감할 수 있기 때문에, 반복적으로 호출되는 계산이나 함수에 적용하는 것이 좋습니다. 하지만 모든 상황에서 메모이제이션을 사용하는 것이 항상 더 나은 것은 아닐 수 있습니다. 일부 경우에는 메모이제이션을 사용하는 것이 추가적인 메모리 사용과 복잡성을 야기할 수 있을 수 있으므로 상황에 맞게 판단
- CSS 최적화: CSS 선택자의 복잡도를 줄이고, 불필요한 스타일 규칙을 제거하여 스타일 렌더링 성능을 개선
- Window Resize 이벤트 최적화: 윈도우 크기 조절 시 자주 발생하는 리렌더링을 방지하기 위해 Resize 이벤트 핸들링을 최소화하거나 디바운싱하여 성능을 향상
- RequestAnimationFrame 활용: 애니메이션 및 스크롤 이벤트와 관련된 작업을 RequestAnimationFrame을 활용하여 브라우저의 리플로우와 리페인트를 최소화
- Web Workers 사용: 웹 워커를 활용하여 백그라운드에서 계산 작업을 처리하여 메인 스레드의 블로킹을 방지하고 렌더링 성능을 향상
- 성능 모니터링 및 프로파일링: 브라우저의 개발자 도구를 사용하여 렌더링 성능을 모니터링하고 병목 현상을 식별하여 개선
브라우저 환경과 프레임워크에 따라 다양한 방법을 사용할 수 있습니다. 프로젝트의 특정 상황과 요구 사항을 고려하여 최적화 전략을 선택하고 적용하는 것이 중요
캐싱 활용
브라우저 캐싱을 통해 자주 사용되는 리소스를 저장하고 재사용합니다. 브라우저 캐시 설정, 캐시 제어 헤더, 캐시 무효화 등을 고려
캐싱은 이전에 어떤 작업의 결과를 저장해 두어 다음에 같은 작업을 수행할 때 더 빠르게 결과를 가져올 수 있도록 하는 기술입니다. 웹 애플리케이션에서 캐싱을 활용하여 리소스나 데이터를 저장하고 재사용함으로써 로딩 속도를 개선할 수 있습니다.
브라우저 캐싱
웹 페이지의 정적 리소스(이미지, 스타일시트, 자바스크립트 파일 등)을 클라이언트의 브라우저 내부에 저장하여 이후 요청 시에 다시 서버에 요청하지 않고 사용
클라이언트의 브라우저에서 캐시 제어 헤더를 설정하여 캐시를 관리합니다. 웹 서버에서 응답 헤더에 Cache-Control, Expires, ETag 등을 추가하여 브라우저 캐싱을 제어
정적 리소스(이미지, 스타일시트, 자바스크립트 파일 등)에 대한 캐싱을 활용하여 웹 브라우저가 리소스를 로컬에 저장하고 다시 요청하지 않도록 합니다. 이를 통해 초기 로딩 속도를 개선할 수 있습니다.
브라우저는 캐싱을 통해 같은 리소스를 다시 요청하지 않고 로컬에 저장된 리소스를 사용함으로써 로딩 속도를 향상
- 위치: 브라우저 내부에서 발생합니다. 브라우저는 사용자의 컴퓨터 또는 장치에 캐시된 리소스를 저장
목적: 브라우저 캐싱은 정적 리소스(이미지, 스타일시트, 자바스크립트 파일 등)를 저장하고 재사용함으로써 웹 페이지의 로딩 속도를 개선합니다. 브라우저는 서버에 다시 요청하지 않고 캐시된 리소스를 사용
설정: 서버에서 HTTP 응답 헤더를 통해 캐싱 정책을 설정 - 캐싱 헤더 추가
서버에서 응답하는 리소스에 캐싱을 위한 헤더를 추가
이 헤더는 브라우저에게 리소스를 얼마 동안 캐시할 수 있는지 알려줍니다. 두 가지 중요한 헤더가 있습니다:- Cache-Control: 리소스의 캐시 제어를 설정
예를 들어, public, private, max-age 등을 사용하여 캐시 정책을 설정 - Expires: 리소스의 만료 날짜와 시간을 설정합니다. 현재는 Cache-Control이 더 권장되는 방법
- Cache-Control: 리소스의 캐시 제어를 설정
Cache-Control: public, max-age=3600
Cache-Control 헤더를 설정하는 방법은 리소스를 서버에서 제공할 때 해당 리소스의 HTTP 응답 헤더에 추가하는 것입니다. 이를 위해서는 웹 서버 또는 백엔드 프레임워크에서 캐싱 정책을 설정
- 웹 서버 설정
웹 서버 (예: Apache, Nginx)를 사용하고 있다면 서버 설정 파일에서 Cache-Control 헤더를 추가하거나 수정할 수 있습니다.Nginx의 설정 파일인 nginx.conf에서 다음과 같이 설정
location ~* \.(css|js|jpg|jpeg|png)$ {
expires 1h;
add_header Cache-Control "public, max-age=3600";
}
위의 예시에서는 정적 리소스 파일에 대해 1시간 동안 캐시를 유지하고, Cache-Control 헤더를 추가하도록 설정
- 백엔드 프레임워크 설정
백엔드 프레임워크 (예: Express.js, Django)를 사용하고 있다면 해당 프레임워크에서 Cache-Control 헤더를 설정
Express.js에서는 다음과 같이 설정
const express = require('express');
const app = express();
app.use(express.static('public', { maxAge: 3600000, setHeaders: cacheControl }));
function cacheControl(res, path) {
res.setHeader('Cache-Control', 'public, max-age=3600');
}
app.listen(3000);
Django의 경우, 뷰 함수에서 HttpResponse 객체에 Cache-Control 헤더를 추가
- 버전 관리 및 파일명 변경
리소스가 변경되면 파일명을 변경하거나 버전 번호를 업데이트하여 브라우저가 새로운 리소스를 가져오도록 유도합니다. 이렇게 하면 브라우저는 변경된 리소스를 다시 요청
<link rel="stylesheet" href="styles.css?v=2">
<script src="script.js?v=2"></script>
- 서버 설정 확인
웹 서버의 설정을 확인하여 정적 리소스에 대한 캐싱을 활성화하거나 수정할 수 있습니다. 웹 서버마다 설정 방법이 다를 수 있으므로 해당 웹 서버의 문서를 참고하거나 서버 관리자에게 문의 - 캐시 제어 헤더 재검토
브라우저 개발자 도구를 사용하여 서버에서 반환된 리소스의 캐시 제어 헤더를 확인하고 검토하세요. 이를 통해 캐시 정책이 제대로 설정되었는지 확인 - 캐시 비우기 및 무효화
브라우저에서 캐시된 리소스를 비우거나 무효화하여 변경된 리소스를 다시 가져오도록 할 수 있습니다. 개발자 도구에서 캐시 관련 옵션을 확인하고 조작
캐싱을 효과적으로 활용하여 웹 애플리케이션의 성능을 개선하려면 적절한 캐싱 정책을 설정하고 리소스의 변경 관리를 신중하게 진행
서버 캐싱
- 위치: 웹 서버나 백엔드 서버에서 발생합니다. 서버는 동적으로 생성되는 콘텐츠를 캐시하여 이전에 생성된 결과를 저장하고 재사용
- 목적: 서버 캐싱은 동적 데이터를 캐시하여 반복적인 요청에 대한 응답 속도를 향상시키고 서버의 부하를 줄입니다. 서버는 이전에 생성한 캐시된 데이터를 반환
- 설정: 백엔드 코드에서 캐싱 메커니즘을 설정하고 HTTP 응답 헤더를 통해 캐싱 전략을 제어
웹 서버나 백엔드 서버에서 동적으로 생성되는 콘텐츠를 캐시하여 이후 요청 시에 동일한 결과를 재사용
웹 서버나 백엔드 프레임워크 내부에서 캐싱 메커니즘을 설정하고, HTTP 응답 헤더를 통해 캐싱을 관리
서버 측에서 데이터나 페이지의 결과를 캐시하여 반복적인 요청에 대한 응답 속도를 향상
웹 서버 설정이나 프레임워크의 기능을 사용하여 서버 캐싱을 구성
웹 서버에서 동적으로 생성되는 콘텐츠를 캐시하여 이전에 생성된 결과를 저장하고 재사용
이를 통해 반복적인 요청에 대한 응답 속도를 향상시키고 서버 부하↓
서버 캐싱을 구현하려면 백엔드 코드에서 캐싱 메커니즘을 설정
- 캐싱 라이브러리 또는 모듈 사용
백엔드 프레임워크나 언어마다 캐싱을 처리하는 라이브러리나 모듈을 제공할 수 있습니다. 이러한 라이브러리를 사용하여 서버 캐싱을 구현 - 캐싱 지시어 설정
백엔드 코드에서 HTTP 응답에 캐싱 관련 헤더를 추가하여 캐싱을 설정할 수 있습니다. 주요 헤더
- Cache-Control: 캐싱 정책을 설정합니다. 예를 들어, public, private, max-age 등을 사용하여 캐시를 제어
- Expires: 캐시의 만료 날짜와 시간을 설정합니다. 현재는 Cache-Control이 더 권장되는 방법
- Expires: 캐시의 만료 날짜와 시간을 설정합니다. 현재는 Cache-Control이 더 권장되는 방법
- Cache-Control: 캐싱 정책을 설정합니다. 예를 들어, public, private, max-age 등을 사용하여 캐시를 제어
- 캐싱 전략 설정
서버에서 어떤 데이터나 콘텐츠를 캐싱할 것인지, 얼마 동안 캐시를 유지할 것인지 등에 대한 전략을 설정
- 정적 콘텐츠: 이미지, 스타일시트, 자바스크립트 파일 등과 같은 정적 파일은 일정 기간 동안 캐시되도록 설정
- 동적 콘텐츠: 동적으로 생성되는 데이터는 변경 빈도나 중요도에 따라 캐싱 전략을 설정합니다. 일부 데이터는 더 오래 캐시하고, 다른 데이터는 더 짧게 캐시
서버 캐싱을 구현하는 방법은 사용하는 백엔드 프레임워크나 언어, 웹 서버 등에 따라 다를 수 있다
CDN 사용
콘텐츠 전달 네트워크(CDN)를 활용하여 리소스를 전 세계에 분산된 서버로 배포하고 캐싱
-> 사용자가 가까운 서버에서 리소스를 로딩하므로 로딩 속도 개선
비동기 로딩
자바스크립트, 스타일시트, 이미지 등을 비동기적으로 로딩하여 초기 페이지 로딩 시간을 단축
웹 페이지의 요소들을 필요할 때 로딩하는 방식입니다. 이를 통해 초기 로딩 시간을 단축하고 페이지의 성능을 개선
- 이미지 비동기 로딩
웹 페이지의 이미지를 비동기적으로 로딩하여 초기 로딩 속도를 개선
loading="lazy" 속성을 사용하거나 자바스크립트를 통해 이미지를 동적으로 로딩 - 컴포넌트 비동기 로딩
필요한 컴포넌트만 로딩하도록 코드 스플리팅과 레이지 로딩을 활용
사용자가 해당 컴포넌트를 요청할 때 로딩되므로 초기 페이지 로딩 속도가 개선 - 데이터 비동기 로딩
페이지가 로드된 후에 필요한 데이터를 비동기적으로 로딩하여 초기 페이지 로딩 속도를 개선하고 사용자 경험을 향상 - XHR(XMLHttpRequest) 또는 Fetch API 사용
데이터를 비동기적으로 요청하고 응답을 처리하여 웹 페이지의 특정 부분만 업데이트하거나 데이터를 추가로 로딩
React 환경에서 비동기 로딩을 구현
React.lazy()와 Suspense 사용
React.lazy()와 Suspense는 React 자체의 공식적인 기능으로 포함
코드 스플리팅을 비교적 간단하게 구현
가장 간단한 비동기 컴포넌트 로딩 시나리오에 적합
React 애플리케이션에서 일반적으로 사용
React.lazy() 함수와 Suspense 컴포넌트를 사용하여 컴포넌트의 비동기 로딩을 지원 -> 이를 통해 코드 스플리팅
import React, { lazy, Suspense } from 'react';
const AsyncComponent = lazy(() => import('./AsyncComponent'));
function App() {
return (
<div>
<Suspense fallback={<div>Loading...</div>}>
<AsyncComponent />
</Suspense>
</div>
);
}
export default App;
React Loadable 라이브러리 사용
React Loadable은 비동기 로딩을 더 세부적으로 제어할 수 있는 라이브러리
React Loadable는 더 세부적인 컨트롤을 제공하며, 로딩 컴포넌트나 에러 컴포넌트를 더욱 세밀하게 조정
커스텀 로딩 컴포넌트를 구성하여 더 많은 제어
더 복잡한 비동기 로딩 시나리오에 유용
import Loadable from 'react-loadable';
const AsyncComponent = Loadable({
loader: () => import('./AsyncComponent'),
loading: () => <div>Loading...</div>
});
function App() {
return (
<div>
<AsyncComponent />
</div>
);
}
export default App;
간단한 비동기 로딩만 필요한 경우라면 React.lazy()와 Suspense를 사용하는 것이 편리할 것이고, 더 복잡한 상황에서는 React Loadable을 사용하여 더 많은 제어와 설정
데이터 비동기 로딩
데이터나 API 호출도 비동기 로딩의 일부로 간주될 수 있습니다. React의 useEffect나 Axios와 같은 라이브러리를 사용하여 데이터를 비동기적으로 로딩하고 화면에 표시할 수 있습니다.
import React, { useState, useEffect } from 'react';
import axios from 'axios';
function DataLoadingExample() {
const [data, setData] = useState(null);
useEffect(() => {
axios.get('https://api.example.com/data')
.then(response => setData(response.data))
.catch(error => console.error(error));
}, []);
return (
<div>
{data ? <p>{data.message}</p> : <p>Loading data...</p>}
</div>
);
}
export default DataLoadingExample;
컴포넌트 분할
큰 규모의 애플리케이션을 작은 컴포넌트로 분할하여 로딩 속도를 향상
필요한 컴포넌트만 로딩하면서 초기 페이지 로딩 시간↓
Tree Shaking
사용하지 않는 코드를 제거하여 번들 크기를 줄입니다. 이를 통해 불필요한 코드의 로딩을 방지
서버 사이드 렌더링(SSR) 또는 정적 사이트 생성(SSG)
서버 사이드 렌더링 또는 정적 사이트 생성을 활용하여 초기 페이지 로딩 속도를 개선하고 검색 엔진 최적화(SEO)를 향상
서버 사이드 렌더링 (Server Side Rendering, SSR)
SSR은 웹 페이지의 초기 렌더링을 서버에서 처리하는 방식
- 사용자가 페이지에 접근할 때, 서버는 해당 페이지의 HTML과 초기 데이터를 생성하여 반환
- 검색 엔진 크롤러가 페이지의 내용을 쉽게 파악할 수 있어 SEO에 유리
- 동적 데이터를 최신 상태로 유지
- 사용자 경험을 향상시키기 위해 서버에서 초기 렌더링을 수행하므로 빠른 첫 화면 로딩이 가능
- 초기 로딩 시간이 길어질 수 있다
예: Next.js와 같은 프레임워크를 사용한 SSR 구현
정적 사이트 생성 (Static Site Generation, SSG)
SSG는 웹 페이지의 미리 렌더링된 정적 HTML 파일을 생성하는 방식
- 빌드 단계에서 웹 페이지의 내용을 미리 렌더링하여 정적 파일로 생성 -> 서버에서 동적 렌더링을 하지 않아도 된다.
- 사용자가 페이지에 접근할 때, 서버에 추가 요청 없이 정적 HTML 파일을 제공하므로 빠른 로딩 속도를 제공
- 검색 엔진 크롤러에 의해 쉽게 인덱싱되어 SEO에 유리
- 초기 로딩 속도가 빠르고, 서버 부하가 적다.
- 동적 데이터가 자주 업데이트되는 경우에는 적합하지 않을 수 있다.
예: Gatsby나 Next.js의 정적 사이트 생성 기능을 사용한 구현
폰트 최적화
웹 폰트를 사용할 때 로딩 시간이 늘어나는 문제를 최소화하기 위해 폰트 서브셋(Subsetting)을 사용하거나 로컬 폰트를 활용
성능 모니터링 및 프로파일링
웹 브라우저의 개발자 도구를 사용하여 성능을 모니터링하고 병목 현상을 파악하여 개선
프로젝트의 특정 상황에 맞게 적절한 최적화 전략을 선택하고 적용하는 것이 중요
아직 업데이트 중..
'Front' 카테고리의 다른 글
성능 최적화 (0) | 2023.08.15 |
---|---|
사용자 경험 최적화 (0) | 2023.08.15 |
아주 쉬운 Data Fetching (0) | 2023.05.31 |
Next.js 시작하기! (0) | 2023.05.15 |
프레임워크와 라이브러리의 차이? (0) | 2023.04.09 |
댓글