Vue Router - prefetch, Lazy Loading(지연된 로딩)

2022. 4. 7. 23:03Vue

SPA(Single Page Aapplication)의 큰 특징은 처음 페이지 진입 시

리소스를 한번에 다운받아 이후 페이지 전환이 매우 빠르다는 이점을 갖고 있다.

하지만 프로젝트의 규모가 큰 경우 처음 초기 랜더링 시간이 오래 걸리게 되는 단점을 초래할 수 있음.

이러한 단점을 보완하기 위해 Angular, React, Vue 에서는 지연된 로딩(Lazy Loading)을 활용한다.

 

1.prefetch 기능이란?

나중에 사용될 리소스를 캐시에 저장함으로써, 사용자가 접속했을 때 빠르게 리소스를 내려줄 수 있는 기능

- webpack 4.6.0 부터 지원

- Vue CLI3가 webpack4를 탑재하면서 사용된 기능

- 기본값 true(prefetch 기능이 사용되도록 설정되어있음)

- 첫 화면 접속 시 랜더링 속도가 느려질 수 있음

 

 

2.Lazy Loading 이란?

리소스를 컴포넌트 단위로 분리하여 컴포넌트 혹은 라우터 단위로 필요한 것들만 그때 그때 다운받을 수 있는 방법

const 컴포넌트명 = () => import (/* webpackChunkName: "리소스이름" */ '컴포넌트경로');

const routes = [
  {
    path: 'URL 주소',
    name: '라우터명',
    component: 컴포넌트명
  },
  {
    path: 'URL 주소',
    name: '라우터명',
    component: () => import(/* webpackChunkName: "리소스이름" */ '컴포넌트경로');
  }
]

 

 

3. 같은 Chunk로 컴포넌트 묶기

- 동일한 라우트에 사용되는 모든 컴포넌트를 하나의 비동기 Chunk로 묶기

const Foo1 = () => import(/* webpackChunkName: "group-foo" */ './Foo1.vue')
const Foo2 = () => import(/* webpackChunkName: "group-foo" */ './Foo2.vue')
const Foo3 = () => import(/* webpackChunkName: "group-foo" */ './Foo3.vue')

사용예시 )

// 기존 소스 : 모든 컴포넌트가 prefetch 적용
// 첫 페이지 접속 시 모든 리소스를 받음
import Login from './components/Login.vue'
import Home from './components/Home.vue'
import About from './components/About.vue'

const router = new VueRouter({
  routes: [
    { path: '/login', component: Login },
    { path: '/home', component: Home },
    { path: '/about', component: About }
  ]
})

// Lazy Loading 사용
// 해당 페이지 리소스만 로드함
// 로드된 페이지는 캐시에 저장되어 재사용됨
const router = new VueRouter({
  routes: [
    { path: '/login', component: () => import('./components/Login.vue') },
    { path: '/home', component: () => import('./components/Home.vue') },
    { path: '/about', component: () => import('./components/About.vue') },
  ]
})

 

 

4. prefetch를 비활성화하고 특정 리소스에만 적용하기

prefetch 설정을 끄는 방법 :  vue.config.js 파일에 아래와 같이 추가하면 된다.

아래와 같은 설정을 하지 않으면 디폴트로 prefetch 설정은 켜진다.

// vue.config.js
module.exports = {
  chainWebpack: config => {
    config.plugins.delete('prefetch');
  }
}

이렇게 작성하여 prefetch 기능을 삭제한다.

prefetch 기능을 삭제해도 우리는 Lazy Load로 컴포넌트를 사용할 수 있다. 다시 index.js로 가서

 

5. prefetch 적용 (특정 컴포넌트)

import(/* webpackPrefetch: true */ '컴포넌트경로');

이렇게 컴포넌트 import시 Lazy Load가 필요한 컴포넌트에 webpackPrefetch : true 로 prefetch 기능을 사용할 수 있다.

 

 

  SPA(Single Page Aapplication)의 큰 특징은
처음 페이지 진입 시
리소스를 한번에 다운받아
이후 페이지 전환이 매우 빠르다는 이점
Lazy Loading (비동기 컴포넌트) default 
리소스(자원)를 컴포넌트 단위로 분리하여
컴포넌트 혹은 라우터 단위로 필요한 것들만
그때 그때 다운받을 수 있는 방법
미리 로드 O, 다 받아 놓기
나중에 사용될 리소스를 캐시에 저장함으로써,
사용자가 접속했을 때 빠르게 리소스를 내려줄 수 있는 기능
첫 로딩 빠름 첫 로딩 느림
Prefetch 꺼두는 설정  Prefetch 켜진 설정 
/ * webpackPrefetch : true */
about.js X about.js O
request 요청수가 적다 request 요청수가 많다

 

 

 

 

 

vue.config.js
0.00MB

 

 

const path = require('path')

module.exports = {
  lintOnSave: false,
  'outputDir': './dist',
  'devServer': {
    'hot': true,
    'port': 7010,
    'open': false,
    'proxy': {
      '/api': {
        'target': process.env.VUE_APP_PROXY_TARGET,
        'changeOrigin': true,
        'pathRewrite': {
          '^/api': ''
        },
        'logLevel': 'debug',
        'secure': false
      }
    },
    'inline': true,
    // error display on the console
    'overlay': false
  },
  chainWebpack: config => {
    config.plugin('html').tap(args => {
      args[0].title = 'ICT APP'
      return args
    })
    config.plugins.delete('prefetch')
    // Disable prefetch and preload of async modules for 'app' page
    config.plugins.store.delete('prefetch-app');
    config.plugins.store.delete('preload-app');
    // Use this syntax if not using multipage setup
    config.plugins.store.delete('prefetch');
    config.plugins.store.delete('preload');

    // config.output.chunkFilename('[id].[chunkhash:8].js')
    // config.entry('index').add('babel-polyfill')
  },
  configureWebpack: {

    module: {
      rules: [
        {
          test: /\.js$/,
          exclude: /node_modules/,
          use: 'babel-loader'
        }
      ]
    },
    resolve: {
      alias: {
        '@': path.resolve(__dirname, 'src')
      }
    },
    // performance: {
    //   hints: false
    // },
    optimization: {
      splitChunks: {
        chunks: 'async',
        minSize: 30000,
        maxSize: 0,
        minChunks: 1,
        maxAsyncRequests: 5,
        maxInitialRequests: 3,
        automaticNameDelimiter: '~',
        name: true,
        cacheGroups: {
          vendors: {
            test: /[\\/]node_modules[\\/]/, // this is what you are looking for
            priority: -10
          },
          default: {
            minChunks: 2,
            priority: -20,
            reuseExistingChunk: true
          }
        }
      }
    },
    plugins: []
  },
  transpileDependencies: []
}

https://blog.jeongwoo.in/vue-js-lazy-load-%EC%A0%81%EC%9A%A9%ED%95%98%EA%B8%B02-3f1a2f4a4ee8

'Vue' 카테고리의 다른 글

Style Guide : 우선순위 권장  (0) 2022.04.19
Bootstrap 적용하기  (0) 2022.04.13
[Vue-Project] Todo-App  (0) 2022.04.01
[Vue] Props Emit 부모 자식 간에 데이터 주고 받기  (3) 2022.03.18
[Vue] Slot  (0) 2022.03.17