阿里云主机折上折
  • 微信号
Current Site:Index > The general approach to performance optimization

The general approach to performance optimization

Author:Chuan Chen 阅读数:55757人阅读 分类: Vue.js

Overall Approach to Performance Optimization

Performance optimization is a crucial aspect of Vue 3's source code, permeating the entire framework's design and implementation. Vue 3 has made significant improvements in performance, from compile-time optimizations to runtime optimizations, as well as a complete overhaul of the reactivity system, all reflecting an extreme pursuit of performance.

Compile-Time Optimizations

Vue 3's compiler has been completely refactored, introducing many compile-time optimization strategies:

  1. Static Hoisting: The compiler identifies static content in templates and hoists it outside the render function to avoid repeated creation.
// Before compilation
<div>
  <span>Static content</span>
  <span>{{ dynamic }}</span>
</div>

// After compilation
const _hoisted_1 = /*#__PURE__*/_createVNode("span", null, "Static content", -1 /* HOISTED */)

function render() {
  return (_openBlock(), _createBlock("div", null, [
    _hoisted_1,
    _createVNode("span", null, _toDisplayString(_ctx.dynamic), 1 /* TEXT */)
  ]))
}
  1. Patch Flags: The compiler adds patch flags to dynamic nodes, allowing the runtime to perform targeted updates based on these flags.
// Different patch flags
export const enum PatchFlags {
  TEXT = 1,                // Dynamic text node
  CLASS = 1 << 1,          // Dynamic class
  STYLE = 1 << 2,          // Dynamic style
  PROPS = 1 << 3,          // Dynamic props (excluding class and style)
  FULL_PROPS = 1 << 4,     // Props with dynamic keys
  HYDRATE_EVENTS = 1 << 5, // Nodes with events
  STABLE_FRAGMENT = 1 << 6,// Fragment with stable child order
  KEYED_FRAGMENT = 1 << 7, // Fragment with keys
  UNKEYED_FRAGMENT = 1 << 8,// Fragment without keys
  NEED_PATCH = 1 << 9,     // Only requires non-props patching
  DYNAMIC_SLOTS = 1 << 10, // Dynamic slots
  DEV_ROOT_FRAGMENT = 1 << 11,
  HOISTED = -1,            // Static node
  BAIL = -2                // Indicates the diff algorithm should terminate
}
  1. Tree Flattening: Separates static and dynamic nodes, reducing the number of nodes that need to be traversed during diffing.

Runtime Optimizations

Vue 3's runtime has also undergone significant optimizations:

  1. Faster Virtual DOM: The virtual DOM implementation has been rewritten, making the diff algorithm more efficient.
// Example of the new diff algorithm
function patchKeyedChildren(
  c1: VNode[],
  c2: VNodeArrayChildren,
  container: RendererElement,
  parentAnchor: RendererNode | null,
  parentComponent: ComponentInternalInstance | null,
  parentSuspense: SuspenseBoundary | null,
  isSVG: boolean,
  slotScopeIds: string[] | null,
  optimized: boolean
) {
  // Preprocessing: compare from both ends toward the middle
  // Middle section uses the longest increasing subsequence algorithm
}
  1. Lighter Reactivity System: Uses Proxy instead of Object.defineProperty, reducing recursive traversal during initialization.
// Core of reactivity implementation
function reactive(target: object) {
  // If already a reactive object, return directly
  if (target && (target as Target)[ReactiveFlags.IS_REACTIVE]) {
    return target
  }
  return createReactiveObject(
    target,
    false,
    mutableHandlers,
    mutableCollectionHandlers,
    reactiveMap
  )
}
  1. Composition API: Provides a more flexible way to organize code, enabling better logic reuse and performance optimization.

Reactivity System Optimizations

Vue 3's reactivity system has been completely overhauled:

  1. Proxy-Based Implementation: Solves issues in Vue 2 where array mutations and object property additions/deletions couldn't be detected.
const arrayInstrumentations = /*#__PURE__*/ createArrayInstrumentations()

function createArrayInstrumentations() {
  const instrumentations: Record<string, Function> = {}
  // Override array methods
  ;(['push', 'pop', 'shift', 'unshift', 'splice'] as const).forEach(key => {
    instrumentations[key] = function (this: unknown[], ...args: unknown[]) {
      pauseTracking()
      const res = (toRaw(this) as any)[key].apply(this, args)
      resetTracking()
      return res
    }
  })
  return instrumentations
}
  1. Lazy Reactivity: Converts properties to reactive only when accessed, reducing unnecessary overhead.

  2. Finer-Grained Dependency Tracking: Precisely tracks dependencies for each property.

Component Rendering Optimizations

Vue 3 has also made significant optimizations in component rendering:

  1. Fragment Support: Allows components to return multiple root nodes, reducing unnecessary wrapper elements.

  2. Teleport Component: Renders content anywhere in the DOM tree, optimizing performance for components like modals.

  3. Suspense Component: Provides a better experience for async component loading.

// Example of Suspense usage
<template>
  <Suspense>
    <template #default>
      <AsyncComponent />
    </template>
    <template #fallback>
      <div>Loading...</div>
    </template>
  </Suspense>
</template>

Memory Management Optimizations

Vue 3 has also improved memory management:

  1. Better GC Friendliness: Reduces unnecessary closures and references, making garbage collection more efficient.

  2. Scoped Styles Optimization: More efficient implementation of scoped styles, reducing memory usage.

  3. Smaller Runtime Size: Reduces unnecessary code through techniques like Tree-shaking.

Developer Tools Integration

Vue 3's developer tools have also been optimized:

  1. More Accurate Performance Analysis: Provides detailed analysis of component rendering times.

  2. Better Time-Travel Debugging: More accurately tracks state changes.

  3. Custom Plugin Support: Allows developers to extend the functionality of the developer tools.

Practical Optimization Techniques

In practical development, you can leverage Vue 3's features for further optimizations:

  1. Use v-memo Wisely: For components that update frequently but may not change content, use v-memo for memoization.
<div v-memo="[valueA, valueB]">
  <!-- Only updates when valueA or valueB changes -->
  {{ valueA }} {{ valueB }}
</div>
  1. Avoid Unnecessary Reactivity: For data that doesn't need reactivity, use shallowRef or markRaw.
const largeList = markRaw([...]) // Won't be converted to reactive
  1. Use Computed Properties Wisely: Computed properties are cached, making them ideal for derived data calculations.
const sortedList = computed(() => {
  return [...list.value].sort()
})

Performance Monitoring and Analysis

Vue 3 provides better performance monitoring capabilities:

  1. Rendering Performance Analysis: Enable recording of component rendering times via configuration.
app.config.performance = true
  1. Custom Performance Markers: Use the performance API for more granular performance analysis.
import { mark, measure } from 'vue'

mark('start')
// Perform some operations
mark('end')
measure('my-measure', 'start', 'end')
  1. Memory Leak Detection: Use developer tools to detect potential component memory leaks.

本站部分内容来自互联网,一切版权均归源网站或源作者所有。

如果侵犯了你的权益请来信告知我们删除。邮箱:cc@cccx.cn

Front End Chuan

Front End Chuan, Chen Chuan's Code Teahouse 🍵, specializing in exorcising all kinds of stubborn bugs 💻. Daily serving baldness-warning-level development insights 🛠️, with a bonus of one-liners that'll make you laugh for ten years 🐟. Occasionally drops pixel-perfect romance brewed in a coffee cup ☕.