언어/Vue.js

[Vue.js] 페이지 속도를 최적화하는 라우터 방식 3가지 (webpackChunkName, webpackPrefetch)

seongEun95 2022. 11. 5. 19:48

먼저 vue.js란 자바스크립트 프레임워크로 SPA(Single Page Application)을 구현하는데 최적화되어 있습니다.

SPA의 장점으로 단일 페이지로 구성되어 있기 때문에 페이지 내에 메뉴를 클릭하여 이동하더라도 새로고침이 진행되지 않아 사용자에게 좋은 이용 경험을 제공해줄 수 있습니다.

즉, 하나의 페이지에서 메뉴 이동시 전체 페이지가 변경되는 것이 아니라 변경이 필요한 부분만 교체됩니다.

 

SPA의 장점도 존재하지만 처음 페이지를 접속할 때 다른 페이지들의 소스들도 한 번에 로드되기 때문에

처음 페이지 접속 시 느리다는 단점도 존재합니다.

 

vue의 라우터 방식을 통해 javaScript파일들을 미리 캐시에 담아 최적화된 웹 페이지를 제공한다면 위의 단점을 보완할 수 있게 됩니다.

 

SPA의 단점을 보완할 수 있는 vue 라우터 방식에 대해서 알아봅시다.


- 목차 -

가. 라우터 기본 구조

나. 라우터 방식 3가지

 1. app.js 파일에 포함되는 방식

 2. app.js가 아닌 별도의 js파일로 분리되는 방식

 3. webpackPrefetch:true가 포함된 방식

다. 참고자료

 


가. 라우터 기본 구조

vue를 vscode 터미널로 초기 설치 시 아래 이미지와 같은 폴더 구조로 되어있습니다.

이 중 src폴더 - router폴더 안 index.js를 클릭하셔서 확인하시면 됩니다.

vue 폴더 구조

 

index.js 파일의 routes 배열 코드는 아래와 같습니다.

// index.js 코드의 일부
import HomeView from '../views/HomeView.vue' // HomeView
const routes = [
  {
    path: '/', // URL 경로
    name: 'home', // 유일한 값
    component: HomeView // 실제 컴포넌트 경로
  }
]

1. path

App.vue의 <router-link to="경로">에서의 경로를 의미합니다. 실제로 url 경로를 입력하면 해당 페이지로 이동합니다.

만약 path : "/about" 이고 <router-link to="/about"></router-link>이라면

Home에서 주소창에 "/about" 경로를 입력하게 되면 about페이지로 이동하게 됩니다.

* router-link는 컴파일 시 a 태그로 변환됩니다. to 경로는 href 속성으로 변환됩니다.

about 페이지 주소

 

2. name

페이지가 작성되고 메뉴가 추가되는데, name은 브라우저의 독립적인 url로 접근 가능한 모든 페이지를 의미합니다. 계속 메뉴가 추가되더라도 동일한 이름이 있으면 안 되며 유일한 값만 가져야 합니다.

 

3. component

path로 이동했을 때 연결할 페이지 컴포넌트(확장자 : .vue)에 대한 정보를 입력합니다.

위의 코드에서 컴포넌트 경로가 '../views/HomeView.vue' 으로 되어 있으므로

Home 메뉴로 이동하면 해당 경로의 vue컴포넌트가 로드됩니다.


나. 라우터 방식 3가지

라우터 방식에는 3가지 방식이 있습니다.

라우터 방식에 따라 적절하게 사용된다면 전체 앱의 사용 속도를 최적화할 수 있게 됩니다.

 

1. app.js 파일에 포함되는 방식

// index.js 파일
import HomeView from '../views/HomeView.vue'
const routes = [
  {
    path: '/',
    name: 'home',
    component: HomeView
  }
]

1번 방식은 routes 배열 밖에 별도의 import 코드가 존재하며 routes 안 component에 import 명만 넣는 형태입니다.

 

웹 개발이 완료되고 vue 컴포넌트들이 컴파일되면 브라우저에서 이해할 수 있는 javaScript 코드들로 변환됩니다.

이때 라우터 1번 방식으로 작성된 파일들은 app.js 파일에 포함됩니다.

 

app.js는 첫 화면이 로드될 때 같이 실행되므로

사용자가 무조건 해당 페이지에 접속하는 경우 1번 방식을 사용하게 됩니다.

첫 화면 로드 시 app.js는 같이 로드

* chunk-vendors.js는 개발한 코드를 제외하고 참조하고 있는 외부 js라이브러리 스크립트 코드가 포함됩니다.

 

 

2. app.js가 아닌 별도의 js파일로 분리되는 방식

// index.js 파일
const routes = [
  {
    path: '/about',
    name: 'about',
    component: () => import(/* webpackChunkName: "about" */ '../views/AboutView.vue')
  }
]

2번 방식은 routes의 component 함수 안에 import로 작성된 방식입니다.

 

/* webpackChunkName : "about" */

여기에 어떤 이름을 지정하는가에 따라 페이지에 접속했을 때 지정한 이름의 js파일로 로드됩니다. 위의 코드의 결과로는 아래와 같습니다.

about.js 로드

2번 방식은 about 페이지로 이동되는 순간에 서버로부터 about.js파일을 불러오게 됩니다.

app.js 파일과 분리되어 생성됩니다.

 

아래 3번 방식의 경우 방문할 페이지의 js소스를 미리 캐시에 담아 해당 페이지에 접속했을 때 캐시에 있는 js파일이 실행되면서 더 빠르게 화면이 로드됩니다.

 

반면 2번 방식은 이동할 페이지에 방문할 가능성이 낮거나 파일 용량이 가벼운 경우

첫 번째 페이지 접속 시 js파일을 캐시에 담아 첫 화면 로드 시간을 늘릴 이유가 없으므로 2번 방식을 사용할 수 있습니다.

 

 

3. webpackPrefetch:true가 포함된 방식

const routes = [
  {
    path: '/about',
    name: 'about',
    component: () =>
      import(
        /* webpackChunkName: "about", webpackPrefetch:true */ '../views/AboutView.vue'
      )
  }
]

3번 방식은 기존 2번 방식 webpackChunkName : "about" 오른쪽에 ,(콤마) webpackPrefetch:true가 추가된 방식입니다.

 

webpackPrefetch:true가 포함된 페이지에 접속 시 네트워크 탭에서 (prefetch cache)가 표시됩니다.

 

(prefetch cahce)

 

그리고 개발자 창 코드에서도 <head> 태그 안에 <link rel="prefetch" as="script" href="/js/about.js"> 코드를 확인할 수 있습니다.

 

link rel prefetch

link rel="prefetch"은 사용자가 요청할 가능성이 높은 페이지의 리소스를 미리 캐시에 담아 다음 요청이 빨리 이루어질 수 있도록 합니다.

 

따라서 3번 방식은 사용자가 방문할 가능성이 높거나 용량이 높은 페이지인 경우 소스들을 미리 캐시에 가져오고

해당 페이지 이동 시점에 캐시에 있는 소스를 가져와 빠르게 화면을 로드할 수 있도록 합니다.

 

* javascript는 파서 차단 리소스 입니다.

브라우저 렌더링이 진행될 때 javascript를 만나게 되면 html 페이지 파싱이 중단됩니다.

html 파싱이 중단되면 javascript 분석이 진행되는 동안 웹 화면이 빈 화면으로 유지됩니다.

이런 경우 사용자는 웹 사이트가 느리게 느껴질 수도 있습니다.

하지만 prefetch로 가져온 리소스는 캐시에 저장만 하고 스크립트를 해석하지 않기 때문에 브라우저 렌더링을 중단하지 않습니다.

따라서 서버에서 javascript 파일은 가져오지만 해석하지 않고 렌더링을 차단하지 않기 때문에 성능에 이점이 발생하게 됩니다.

 


 

라우터 방식 3가지를 정리하면

1. app.js 파일에 포함되는 방식은 사용자가 무조건 접속하게 되는 메뉴의 페이지인 경우 사용합니다.

2. app.js 파일이 아닌 별도의 js파일로 분리되는 2번 방식은 사용자가 방문할 가능성이 적거나 용량이 가벼운 경우 사용하게 됩니다.

3. webpackPrefetch:true로 미리 캐시에 담아두는 방식인 3번은 사용자가 방문할 가능성이 높거나 페이지 용량이 무거운 경우 미리 캐시에 담아 접속 시점에 페이지 로드를 빠르게 할 수 있도록 합니다.

 

위의 3가지 방식을 알맞게 사용하여 전체 페이지 설계를 진행하면 SPA 단점의 보완과 웹 페이지 로드 시간을 최적화할 수 있게 됩니다.

 


다. 참고자료

1. https://www.youtube.com/c/개발자의품격 - 부트캠프, Vue.js 라우터 이해하기

2. https://v3.router.vuejs.org/kr/guide/ - Vue Router, 시작하기

3. http://www.tcpschool.com/html-tag-attrs/link-rel - TCPSCHOOL, <link> 태그의 rel 속성