为你的 Vue.js 单页应用提速

做者:Matthias Sommer

翻译:疯狂的技术宅javascript

原文:https://dzone.com/articles/sp...html

未经容许严禁转载前端

我有一个项目用了 Vue.js 来构建单页应用程序。随着上线日期的临近,性能优化的工做变得愈来愈重要。在本文中,我收集了有关在加载时间和渲染性能方面提升 Vue.js 应用性能的全部知识。vue

使用 Vue.js,你能够快速构建单页应用。 Webpack 会为你将全部内容捆绑到文件(HTML、JavaScript、CSS)中,最后能够用 nginx 来提供。至少,这是咱们的设置。可是 Webpack 会警告你某些资源太大。java

须要注意的是,一旦用户访问 SPA,这三个文件将会被加载,而且只有在加载完毕以后才会渲染页面。可是最初加载的页面通常不须要太多文件内容,而且不该拖慢用户访问咱们的网站的速度。webpack

如下介绍了有关如何缓解此类问题的几种方法,以及在响应性和性能方面进一步改进 Vue.js 应用的其余方法。ios

功能组件

功能组件是不包含任何状态和实例的组件。将无状态 Vue 组件转换为功能组件能够大大提升渲染性能。nginx

只需在顶层 template 标记中添加 functional 关键字便可:程序员

<template functional>  <div>...</div> </template>

要像之前同样访问 prop 和数据,你必须进行一些小的调整。web

<template functional>  
  <div>{{ props.someProp }}</div> 
</template> 
<script> 
  export default {  
    props: {    
      someProp: String  
    } 
  }
</script>

若是你使用 i18n 进行国际化,则必须在 parent 以前加上 $t

{{ parent.$t('app.not-found.message') }}

使用功能组件,咱们无权使用方法或计算的 prop。可是,咱们仍然可使用 $options 访问方法。

<template functional>  
  <div>
    {{ $options.username(props.user) }}
  </div> 
</template> 
<script> 
  export default {  
    props: {    
      user: User,  
    },   
    username(user: User): string {    
        return user.name;  
    } 
  }
</script>

延迟加载组件

延迟加载组件能够节省大量的初始下载时间。调用 import() 函数时,将会下载全部延迟加载的资源。对于 Vue 组件,仅在请求渲染时才发生。对话框是注定会这样的。一般仅在用户交互后才显示它们。

<template> 
  <div>     
    ...    
    <app-modal-dialog v-if="showDialog" />  
  </div> 
</template> 
<script> 
  export default {  
    components: {    
      ModalDialog: () => import('./ModalDialog.vue')  
    } 
  }
</script>

Webpack 将为 ModalDialog 组件建立一个单独的块,该块不会在页面加载时当即下载,而是仅在须要时才下载。

注意不要延迟加载应自动显示的组件。例如如下内容(无提示)将没法加载模式对话框。

mounted() {
  this.$bvModal.show('password-check'); 
},

缘由是已安装的 hook 是在延迟加载模态组件以前进行评估的。

延迟加载路由

构建 SPA 时,JavaScript 捆绑包可能会变得很大,从而增长页面加载时间。若是咱们能够将每一个路由的组成部分拆分为一个单独的块,而后仅在访问路由时才加载它们,则效率会更高。

import ProjectList from '@/components/ProjectList.vue'; 
export const routes = [  
  {    
    path: '/projects',    
    name: 'projects',    
    component: ProjectList,  
  }, 
]

定义一个异步组件很是容易,该组件将由 Webpack 自动进行代码拆分。只需更改导入语句:

const ProjectList = () => import('@/components/ProjectList.vue');

除此以外,无需更改路由配置。经过如下方式在生产模式下构建你的应用:

"build": "vue-cli-service build --mode production"

并确认会生成不少块

Vue 和 Webpack 中的代码拆分

你还能够经过在浏览器中打开开发者控制台来验证此功能是否正常。在 Network 标签中,一旦你访问新路由,就会异步加载多个 JavaScript 文件。在开发模式下,每一个块都将被赋予一个自动递增的数字。在生产模式下,将使用自动计算的哈希值代替。

延迟加载的块和预取缓存

Vue 有一个很酷的功能就是 Vue 自动添加 Webpack 的魔术注释,以便进一步自动预取其余块(请参阅预取缓存一节) 。可是,预取仅在浏览器完成初始加载并变为空闲以后才开始。

使对象列表不可变

一般,咱们将从后端获取对象列表,例如用户、项目、文章等。默认状况下,Vue 使数组中每一个对象的每一个第一级属性都具备响应性。对于大量对象而言,这代价可能会很大。有时咱们只想显示对象时就不须要去修改它们。

因此在这种状况下,若是咱们阻止 Vue 使列表具备响应性,那么就能够得到一些性能。咱们能够经过使用列表中的 Object.freeze 来作到这一点,例如使其一直不变。

export async function get(url: string): Promise<User[]> {   
  const response = await Object.freeze(axios.get<User[]>(url));   
  return response.data; 
}

评估运行时性能

咱们已经讨论了许多改进 Vue SPA 的方法,可是不知道咱们实际得到了多少性能。能够经过使用浏览器中开发者工具的 Performance 标签来实现。

为了得到准确的数据,咱们必须在 Vue 应用中激活性能模式。让咱们在 main.ts 文件中用开发模式激活它

Vue.config.performance = process.env.NODE_ENV !== "production";

这将激活 Vue 内部使用的 User Timing API

打开浏览器,而后按 F12 键打开开发者控制台。切换到 Performance 选项卡,而后单击 Start Profiling。在 Chrome 中,“ Timings” 行显示重要标记,例如 “First Contentful Paint” 和 “First Meanfulful Paint” 时间。你应该尝试减小它们,以便你的用户能够尽快使用该网站。

总结

在本文中,咱们了解了如何对路由和组件使用延迟加载以将 SPA 分红多个块,功能组件如何提升性能以及如何衡量这些改进。


本文首发微信公众号:前端先锋

欢迎扫描二维码关注公众号,天天都给你推送新鲜的前端技术文章

欢迎扫描二维码关注公众号,天天都给你推送新鲜的前端技术文章

欢迎继续阅读本专栏其它高赞文章:


相关文章
相关标签/搜索