项目优化


Performance

1.页面加载优化

1.1Bundle Size and Tree-shaking

  • 发布使用性能更加全面的 JavaScript 包
    • 如果通过现代构建工具捆绑 许多 Vue 的 API 都是 Tree-shaking。例如如果不使用内置的<Transition>组件 他将不会包含在最终的生产包中 Tree-shaking 还可以删除源代码中其他未使用的模块
    • 使用构建步骤时 模板是预编译的 因此我们不需要将 Vue 编译器发送到浏览器中 这避免了运行时编译成本
  • 引入依赖时要注意大小
    • 使用支持 ES 模块格式并且对 Tree-shaking 友好的依赖项 如引入 lodash-es 而不是 lodash
    • 检查依赖项的大小并评估它是否值得它提供的功能 bundle.js.org 之类的工具可用于快速检查 但使用实际构建设置进行测量始终是最准确的
  • 如果使用 VUE 进行渐进式增强并希望避免构建步骤 可以考虑使用 petite-vue

1.2.代码拆分

通过适当的代码拆分 可以立即下载页面加载所需的功能 仅再需要时才延迟加载额外的块 从而提高性能

  • Rollup(基于 Vite)或 webpack 之类的打包工具可以通过检查 ESM 动态导入元自动创建拆分块

  • ```vue
    function loadLazy() { return import(‘./lazy.js’) }

    1
    2
    3
    4
    5
    6
    7
    8

    - 延迟加载最好用于初始页面加载后不需要立即使用的功能。在 Vue 应用程序中 这通常与 vue 的异步组件结合使用 为组件树创建拆分快

    - ```vue
    import { defineAsyncComponent } from 'vue' // a separate chunk is created for
    Foo.vue and its dependencies. // it is only fetched on demand when the async
    component is // rendered on the page. const Foo = defineAsyncComponent(() =>
    import('./Foo.vue'))

    如果使用 Vue Router强烈建议使用异步组件作为路由组件

1.3.SSR/SSG

纯客户端渲染会遇到内容生成时间缓慢的问题。这可以通过服务器端渲染 (SSR) 或静态站点生成 (SSG) 来缓解。

2.更新优化

2.1Props Stability

在 Vue 中 子组件仅在接收到至少一个 props 发生改变时才更新

1
2
3
4
5
6
7
8
<ListItem v-for="item in list" :id="item.id" :active-id="activeId" />
//在listItem组件内部 它使用的id和activeId来确定它是否是当前活跃的项目
但是这会导致在activeId更改时 列表中的每个listItem都必须更新 //理想状态下
只有活动状态发生变化的项目才必须更新
我们可以通过将活动状态计算移至父级来实现这一点
<ListItem v-for="item in list" :id="item.id" :active="item.id === activeId" />
//现在 对于大多数组件来说 prop的active在activeId更改时将保持不变
因此它们不再更新

思想:保持传递给子组件的 prop 尽量稳定

2.2 v-once

依赖于运行时数据但是从不需要高兴的内容 它所使用的整个子树将跳过以进行所有未来的更新

2.3v-memo

可用于有条件地跳过大型子树或者 v-for 列表的更新

3.一般优化:会影响页面加载和更新性能

3.1 虚拟化大型列表

我们可以跳过列表虚拟化来极大地提高性能 该技术仅在大列表中呈现当前位于或靠近视口的视图

3.2 减少大型不可变结构的响应式开销

vue 的反应系统默认是深度的 可以使用 shallowReactive()来退出深度响应性

浅响应性 API 创建仅在根级别具有响应性 并未追踪嵌套对象 这是的嵌套属性访问保持快速 但是我们必须将所有的嵌套对象视为不可变的 并且只能通过替换根状态来触发更新

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
const shallowArray = shallowRef([
/* big list of deep objects */
]);

// this won't trigger updates...
shallowArray.value.push(newObject);
// this does:
shallowArray.value = [...shallowArr.value, newObject];

// this won't trigger updates...
shallowArray.value[0].foo = 1;
// this does:
shallowArray.value = [
{
...shallowArray.value[0],
foo: 1,
},
...shallowArray.value.slice(1),
];

shallowRef()通常用于大型数据结构的性能优化 或者于外部状态管理系统的集成

1
2
3
4
5
6
7
const state = shallowRef({ count: 1 });

// does NOT trigger change
state.value.count = 2;

// does trigger change
state.value = { count: 2 };

3.3 避免不必要的组件抽象


文章作者: olddog
版权声明: 本博客所有文章除特別声明外,均采用 CC BY 4.0 许可协议。转载请注明来源 olddog !
  目录