我们好,这儿是我们的林语冰。坚持阅览,自律打卡,每天一次,前进一点

免责声明

本文属所以语冰的直男翻译了属所以,略有删改,仅供粉丝参阅。英文原味版请传送 Optimizing A Vue App

本期同享的是 —— 在构建 Web App 时优先考虑功能能够改进 UX(用户体验),有助于它们被更多用户运用。本文将引导咱们深度学习若干前端优化技巧,让 Vue App 尽量保持高效。

SPA(单页应用程序)在处理实时动态数据时,能够供给丰富的交互式 UX。但 SPA 也或许很粗笨臃肿且功能尴尬。咱们会介绍若干前端优化技巧,保持 Vue App 相对精简,而且按需交给咱们需求的 JS。

粉丝请注意:咱们假设您对 Vue 及其组合式 API 有基本认知,但无论您挑选哪个结构,都能收获某些有用的东东。

结构的挑选

咱们挑选的 JS 结构是 Vue,部分原因是由于它是我最称心如意的结构。此前,与 React 相比,Vue 的整体包体积更小。虽然可是,自从最近的 React 更新以来,平衡似乎已经向 React 歪斜。这并非兹事体大,由于咱们会在本文中了解怎么按需导入内容。这两个结构都有优异的文档和巨大的开发者生态系统,这是另一个考虑要素。

作为演示各种优化的示例,自己构建了一个简单的 Vue App,它从 API 恳求数据,并运用 D3.js 烘托若干图表。

怎么优化 Vue App?

咱们运用一种人气爆棚的构建东西 Vite 来打包 App,但咱们在此介绍的一切优化都适用于我们挑选的任何打包程序。

诉诸构建东西树摇优化、紧缩和简化

按需发送代码、且开箱即用,是一种优异实践。Vite 构建时会删除未用的 JS 代码(tree shaking,树摇优化)。Vite 还会紧缩打包结果,且能够配置为运用 Gzip/Brotli 紧缩输出。

除了紧缩之外,咱们能够发现未运用效果域提升时,打包体积比优化和紧缩的版别高出约 5 倍。因而,无论您运用哪个打包器,公私分明,您或许期望保证它尽量履行优化。

即便咱们总体上交给的包较小,浏览器依然需求时间来解析和编译 JS,这或许会导致 UX 变慢。让咱们看看还能做些什么来减少浏览器的工作量。

Vue 组合式 API

Vue 3 引入了组合式 API,这是一组用于创造组件的新型 API,作为选项式 API 的竞品计划。通过专用组合式 API,咱们能够按需导入 Vue 函数,而不是整个包。它还使咱们能够运用组合式函数编写更多可复用代码。运用组合式 API 编写的代码更适合紧缩,且整个 App 更容易 tree-shaking

粉丝请注意:假如您运用的是旧版的 Vue,您依然能够运用组合式 API:它已向后移植到 Vue 2.7,且有一个适用于旧版的官方插件。

依靠导入

一个要害目标是减少客户端下载的初始 JS 包的大小。D3 可用于数据可视化,这是一个大型库,范围广泛。虽然可是,D3 库中有的模块咱们底子不需求。假如咱们查看整个 D3 包,咱们能够发现咱们的 App 运用了不到一半的可用模块,乃至或许没有运用这些模块中的一切功用。

保持包体积尽量小的最简单办法之一就是按需导入模块。

以 D3 的 selectAll 函数为例。咱们能够从 d3-selection 模块导入咱们需求的函数,而不是运用默认导入:

// 优化前:
import * as d3 from 'd3'
// 优化后:
import { selectAll } from 'd3-selection'

诉诸动态导入切割代码

动态导入答应咱们将模块精准导入到代码中需求的方位,而不是在文件顶部静态导入模块。

// 优化前:
import { Auth } from '@aws-amplify/auth'
const user = Auth.currentAuthenticatedUser()
// 优化后:
import('@aws-amplify/auth').then(({ Auth }) => {
  const user = Auth.currentAuthenticatedUser()
})

这意味着,该模块会被切割成一个独自的 JS 包或“组块”,当且仅当需求时,浏览器才会下载该模块。此外,浏览器能够缓存这些依靠,这些依靠的更改频率或许低于 App 其余部分的代码。

运用 Vue Router 路由懒加载

咱们的 App 运用 Vue Router 导航。与动态导入类似,咱们能够懒加载路由组件,因而当且仅当用户导航到该路由时,才会导入它们及其相关依靠。

index/router.js 文件中:

// 优化前:
import Home from "../routes/Home.vue";
import About = "../routes/About.vue";
// 优化后:
const Home = () => import("../routes/Home.vue");
const About = () => import("../routes/About.vue");
const routes = [
  {
    name: "home",
    path: "/",
    component: Home,
  },
  {
    name: "about",
    path: "/about",
    component: About,
  },
];

当且仅当用户单击“About”链接、并导航到该路由时,才会加载“About”路由的代码。

异步组件

除了懒加载每个路由之外,咱们还能够运用 Vue 的 defineAsyncComponent 办法懒加载单个组件。

const KPIComponent = defineAsyncComponent(() => import('../components/KPI.vue'))

这意味着,KPIComponent 的代码会动态导入。咱们还能够供给若干在加载或过错状况时显示的组件,假如咱们正在加载一个特别大的文件,这特别有用。

拆分 API 恳求

咱们的 App 首要触及数据可视化,而且严重依靠于从服务器恳求海量数据。其中某些恳求或许慢如龟速,由于服务器有必要对数据履行很多计算。在开端的原型中,咱们对每个路由的 REST API 宣布一个恳求。不幸的是,这导致用户有必要等待好久,有时高达 10 秒,在 App 成功接纳数据、并开端烘托可视化之前,用户只能看到加载组件。

咱们决定将 API 拆分为多个端点,并对每个小部件宣布恳求。虽然这或许会添加整体呼应时间,但这意味着,App 能够更快运用,由于用户在等待其他页面时,会看到页面的部分内容已烘托。此外,或许发生的任何过错都会被部分化,而页面的其余部分依然可用。

条件加载组件

现在咱们能够将其与异步组件结合起来,这样当且仅当收到服务器的成功呼应时,才会加载组件。这儿咱们正在恳求数据,然后在 fetch 函数成功回来时导入组件:

怎么优化 Vue App?

此形式能够扩展到 App 中在用户交互时烘托组件的恣意方位。举个栗子,当且仅当用户单击“地图”选项卡时,咱们才加载地图组件及其依靠。这称为交互导入。

CSS

假如运行示例代码,咱们会看到单击“方位”导航链接会加载地图组件。除了动态导入 JS 模块之外,在组件的 <style> 块中导入依靠也会延迟加载 CSS:

// MapView.vue
<style>
  @import '../../node_modules/leaflet/dist/leaflet.css';
  .map-wrapper {
    aspect-ratio: 16 / 9;
  }
</style>

间断 API 恳求

在一个有很多 API 恳求的页面上,假如用户在一切恳求完成之前就跑路了,那会怎样?咱们或许不期望这些恳求持续在后台运行,降低 UX。

咱们能够运用 AbortController 接口,它使咱们能够按需间断 API 恳求。

setup 函数中,咱们创建一个 controller,并将其 signal 传递到 fetch 恳求参数中:

setup(props) {
    const controller = new AbortController();
    const loadComponent = () => {
      return fetch(url, { signal: controller.signal })
        .then((response) => response.json())
        .then((response) => (data.value = response))
        .then(importFunction)
        .catch((e) => console.error(e))
        .finally(() => (loading.value = false));
        };
}

然后,咱们运用 Vue 的 onBeforeUnmount 函数在组件卸载前间断恳求:

onBeforeUnmount(() => controller.abort())

假如咱们在恳求完成之前运行项目并导航到另一个页面,咱们会看到控制台中打印的过错,标明恳求已间断。

结束撒花

在构建 Web App 时优先考虑功能能够改进 UX,并有助于它们被更多用户运用。SPA 能够很好地工作,但它们也或许成为功能瓶颈。因而,让咱们测验将它们构建得更好。

本期论题是 —— 你运用过哪些 Vue 优化的终极小技巧?

欢迎在本文下方群聊自由言论,文明同享。谢谢我们的点赞,掰掰~

《前端 9 点半》每日更新,坚持阅览,自律打卡,每天一次,前进一点

怎么优化 Vue App?