서버 사이드 렌더링(SSR)은 웹 애플리케이션의 성능을 향상시키는 중요한 기술 중 하나입니다. Vue.js는 클라이언트 사이드 렌더링(CSR)에 초점을 맞춘 프레임워크이지만, SSR을 통해 CSR의 단점을 극복할 수 있습니다. 이번 포스팅에서는 Vue.js를 사용하여 서버 사이드 렌더링을 구현하는 방법과 이점에 대해 알아보겠습니다.
서버 사이드 렌더링(SSR)의 이점
1. 검색 엔진 최적화(SEO)
CSR 방식에서는 초기 렌더링 시 클라이언트 측에서 JavaScript를 실행해야 하므로, 일부 검색 엔진은 초기 페이지 콘텐츠를 인식하지 못할 수 있습니다. 반면에 SSR은 서버 측에서 페이지를 완전하게 렌더링하고 HTML로 제공하므로 검색 엔진이 페이지 내용을 쉽게 파악할 수 있습니다.
2. 초기 로딩 성능 개선
CSR 방식에서는 초기 페이지 로딩 시에 모든 JavaScript와 데이터를 받아와야 하므로 초기 로딩 시간이 길어질 수 있습니다. SSR은 서버에서 미리 렌더링된 HTML을 제공하므로 초기 로딩 성능을 향상시킵니다.
3. 소셜 미리보기 및 링크 공유
SSR을 사용하면 소셜 미리보기와 링크 공유 시에도 미리보기 이미지와 적절한 메타 데이터를 제공할 수 있습니다. 이는 소셜 미디어에서 페이지를 공유할 때 중요한 역할을 합니다.
Vue.js로 서버 사이드 렌더링 구현하기
Vue.js를 사용한 서버 사이드 렌더링을 구현하려면 다음 단계를 따를 수 있습니다.
1. Vue CLI로 프로젝트 생성
Vue CLI를 사용하여 Vue.js 프로젝트를 생성합니다.
vue create vue-ssr-app
2. SSR 플러그인 설치
Vue CLI 플러그인 중 SSR 플러그인을 설치합니다.
vue add @vue/server-renderer
3. 서버 엔트리 포인트 생성
서버 사이드 렌더링을 위한 서버 엔트리 포인트를 생성합니다. 예를 들어, src/entry-server.js
파일을 만들고 다음과 같이 작성합니다.
import { createApp } from './main';
export default (context) => {
return new Promise((resolve, reject) => {
const { app, router, store } = createApp();
// 서버 사이드 라우팅
router.push(context.url);
// 데이터 프리로딩
router.onReady(() => {
const matchedComponents = router.getMatchedComponents();
if (!matchedComponents.length) {
return reject({ code: 404 });
}
// 데이터 로딩 및 상태 초기화
Promise.all(
matchedComponents.map((component) => {
if (component.asyncData) {
return component.asyncData({
store,
route: router.currentRoute,
});
}
})
)
.then(() => {
context.state = store.state;
resolve(app);
})
.catch(reject);
}, reject);
});
};
4. 클라이언트 엔트리 포인트 수정
클라이언트 엔트리 포인트인 src/entry-client.js
파일을 수정하여 클라이언트 사이드와 서버 사이드에서 동일한 앱 인스턴스를 사용하도록 설정합니다.
import { createApp } from './main';
const { app, router, store } = createApp();
if (window.__INITIAL_STATE__) {
store.replaceState(window.__INITIAL_STATE__);
}
router.onReady(() => {
app.$mount('#app');
});
5. 서버 설정 및 빌드
서버 설정 파일(server.js
)을 작성하고 서버를 빌드합니다. 예를 들어, Express.js를 사용한 서버 설정 파일은 다음과 유사할 수 있습니다.
const express = require('express');
const fs = require('fs');
const { createBundleRenderer } = require('vue-server-renderer');
const server = express();
const renderer = createBundleRenderer(
require('./dist/vue-ssr-server-bundle.json'),
{
template: fs.readFileSync('./public/index.html', 'utf-8'),
}
);
server.use(express.static('dist'));
server.get('*', (req, res) => {
const context = { url: req.url };
renderer.renderToString(context, (err, html) => {
if (err) {
res.status(500).end('Internal Server Error');
return;
}
res.end(html);
});
});
const port = process.env.PORT || 8080;
server.listen(port, () => {
console.log(`Server is listening on port ${port}`);
});
6. 빌드 및 실행
프로젝트를 빌드하고 서버를 실행합니다.
npm run build
npm run start
SSR로 페이지 데이터 로딩
Vue.js 컴포넌트에서 서버 사이드 렌더링을 위해 데이터를 불러오려면 asyncData
메서드를 사용할 수 있습니다. 이 메서드는 컴포넌트가 렌더링되기 전에 호출되어 데이터를 미리 불러올 수 있습니다.
export default {
async asyncData({ params }) {
const response = await fetch(`https://api.example.com/posts/${params.id}`);
const post = await response.json();
return { post };
},
};
SSR로 상태 관리
SSR에서도 상태 관리를 유지하려면 Vuex를 사용할 수 있습니다. 서버에서 초기 상태를 생성하고 클라이언트에서 상태를 복원할 수 있습니다.
import Vuex from 'vuex';
export default () => {
return new Vuex.Store({
state: {
// 초기 상태
posts: [],
},
mutations: {
setPosts(state, posts) {
state.posts = posts;
},
},
actions: {
async fetchPosts({ commit }) {
const response = await fetch('https://api.example.com/posts');
const posts = await response.json();
commit('setPosts', posts);
},
},
});
};
결론
서버 사이드 렌더링(SSR)은 Vue.js 애플리케이션의 성능과 검색 엔진 최적화를 향상시키는 중요한 기술입니다. Vue.js를 사용하여 SSR을 구현하면 초기 로딩 성능을 개선하고 검색 엔진에서 더 잘 인식되는 웹 애플리케이션을 개발할 수 있습니다.
위에서 설명한 단계를 따라 Vue.js 애플리케이션을 서버 사이드 렌더링으로 업그레이드할 수 있습니다. 이를 통해 사용자 경험과 검색 엔진 최적화를 향상시키세요!