티스토리 뷰

안녕하세요.

 

오늘은 client side rendering 방식에서 동일한 리소스의 변경시 변경사항을 client에 제대로 적용하는 방법에 대해 설명드리겠습니다.

 

배경을 간단히 설명드리자면 

저희가 Vue로 개발을 하고 서비스를 하면서 웹서버를 별도로 둘까하다 인원이 작고 관리도 힘들것 같아. 

aws s3-cloudfront 조합으로 Client side rendering 방식으로 서비스를 하기로 결정하였는데

 

이미 아시겠지만 Client side rendering 방식은 필요한 리소스 (html, css, js) 를 사용자가 접근시 client에 내려주고

client에서 내려받은 리소스를 바탕으로 rendering 하게 됩니다. 

 

맨 처음 접속시 리소스를 받느라 느려지는 점을 제외하면 (lazy loading이나 chunk 를 해도 한계가 있어 다른 방법을 개발 중에 있습니다.) 여러모로 장점이 있는 방식이라고 생각하고 있었습니다만, 

 

동일한 vue 페이지 변경시 변경된 내용이 적용되지 않는 문제가 발생했습니다. 

 

사용자에게 이미 해당 리소스가 있다보니 새로고침 전까지는 구 버전의 리소스가 실행되는 점 때문이었는데요.

 

여러가지 방법을 생각해 보았습니다.

 

1. 소스 버전 관리

 - app.vue나 env 파일의 환경변수에 소스 버전을 관리하고 사용자 cookie와 버전을 비교하여 강제로 새로고침 실행하기 => 새로고침 하는 법을 찾는 것도 문제였지만, 새로고침시 전체 리소스를 다시 받아야 하는 점 때문에 (속도 문제) 기각,

 

2. 공지 띄워서 사용자가 스스로 새로고침 하도록 유도.

- 사용자 판단에 맡기는 방법이라 기각.

 

뭐.. 잘 모르다 보니 위와 같이 얼토당토 않은 생각을 하던중, 아래와 같은  방법을 찾았습니다.

import Vue from 'vue'
import Router from 'vue-router'

Vue.use(Router)

export const router = new Router({
  routes: .... // 설명에 필요한 부분이 아니므로 생략
})

router.afterEach(() => {
  // Check if a new cache is available on page load.
  window.addEventListener('load', function () {
    window.applicationCache.addEventListener('updateready', function () {
      if (window.applicationCache.status == window.applicationCache.UPDATEREADY) {
        // Browser downloaded a new app cache.
        // Swap it in and reload the page to get the new hotness.
        window.applicationCache.swapCache()
        window.location.reload()
      } else {
        // Manifest didn't changed. Nothing new to server.
      }
    }, false)
  }, false)
})

간단히 설명드리자면 vue router에서 router 변경 직후 afterEach event가 발생하는데, 여기에서 update할 부분이 있는지 찾아내서 있으면 reload를 실행하도록 한 코드입니다.

 

위 코드를 적용한 뒤로는 아직까지 문제없이 작동하고 있습니다.

 

써놓고 나니 별거 없는데..

저와 같이 vue를 웹서버 없이 직접 client 로 내리는 방식을 사용하고 있다면

위 코드를 router 부분에 추가하시면 되겠습니다. :)

 

감사합니다. 

댓글