Vue性能优化方法

170 阅读1分钟

路由懒加载

const router = new VueRouter({
    routes: [
        {path: '/about', component: () => import('../views/About.vue'),  }
    ]
})

keep-alive

<div id="app">
    <keep-alive>
        <router-view />
    </keep-alive>
</div>

v-show 复用 Dom

// 针对渲染时间较长
<div class="cell">
    <div v-show="value" class="on">
        <Heavy />
    </div>
    <div v-show="!value" class="off">
        <Heavy />
    </div>
</div>

v-for 遍历避免同时使用 v-if

<template>
    <ul>
        <li
            v-for="user in activeUsers"
            :key="user.id">
            {{ user.name }}
        </li>
    </ul>
</template>
<script>
    export default {
        computed: {
            activeUsers() {
                return this.users.filter(user => user.isActive)
            }
        }
    }
</script>

长列表性能优化

数据只是展示,无变化,不需要响应式

export default {
    data: () => {
        users: []
    },
    async created() {
        const users = await axios.get('/api/users')
        this.users = Object.freeze(users)
    }
}

虚拟滚动,只渲染少部分的内容

// vue-virtual-scroller  vue-virtual-scroll-list
<recycle-scroller
    class="items"
    :items="items"
    :item-size="24">
    <template v-slot="{item}">
        <FetchItemView
            :item="item"
            @vote="voteItem(item)"
        />
    </template>
</recycle-scroller>

事件销毁

Vue组件销毁时,会自动解绑它的全部指令及事件监听事件,但仅限于组件本身的事件
created() {
    this.timer = setInterval(this.refresh, 3000)
}
beforeDestroy() {
    clearInterval(this.timer)
}

图片懒加载

图片过多的页面,为了加速页面加载速度,需要将未在页面出现的图片先不做加载,等滚动到视图区域后再加载。
// vue-lazyload
<img v-lazy="/static/img/1.jpg" />

第三方按需引入

如 element-ui 可以按需引入,避免体积过大
import Vue from 'vue'
import { Button, Select } from 'element-ui'

Vue.use(Button)
Vue.use(Select)

无状态组件标记为函数式组件

<template functional>
    <div class="cell">
        <div v-if="props.value" class="on"></div>
        <section v-else class="off"></section>
    </div>
</template>
<script>
export default {
    props: [value]
}
</script>

子组件分割

<template>
    <div>
        <ChildComp />
    </div>
</template>
<script>
    export default {
        components: {
            ChildComp: {
                methods: {
                    heavy() // 耗时任务
                },
                render(h) {
                    return h('div', this.heavy())
                }
            }
        }
    }
</script>

变量本地化

<template>
    <div :style="{ opacity : start / 300 }">
        {{ result }}
    </div>
</template>
<script>
    import { heavy } from '@/utils'
    
    export default {
        props: ['start'],
        computed: {
            base() { return 42 },
            result() {
                const base = this.base
                let result = this.start
                for (let i=0; i<1000; i++) {
                    result += heavy(base)
                }
                return result
            }
        }
    }
</script>

SSR

  • SEO
  • 首屏渲染速度