Lazy loading

Lazy loading — это техника отложенной загрузки компонентов или данных, которая позволяет существенно оптимизировать производительность приложений на Vue.js, особенно при работе с тяжёлыми компонентами интерфейса. В Element Plus lazy loading применяется в основном для компонентов Tree, Table, а также динамических диалогов и модальных окон.

Lazy Loading в компоненте Tree

Компонент el-tree поддерживает ленивую загрузку дочерних узлов через свойства lazy и load.

Пример базовой конфигурации:

<template>
  <el-tree
    :data="data"
    :props="defaultProps"
    lazy
    :load="loadNode"
    node-key="id"
    highlight-current
  />
</template>

<script>
import { ref } from 'vue'

export default {
  setup() {
    const data = ref([
      { id: 1, label: 'Главный узел', isLeaf: false }
    ])

    const defaultProps = {
      children: 'children',
      label: 'label',
      isLeaf: 'isLeaf'
    }

    const loadNode = (node, resolve) => {
      if (node.level === 0) {
        resolve(data.value)
      } else {
        // Имитация асинхронной загрузки с сервера
        setTimeout(() => {
          const childNodes = [
            { id: `${node.data.id}-1`, label: `Дочерний узел ${node.data.id}-1`, isLeaf: true },
            { id: `${node.data.id}-2`, label: `Дочерний узел ${node.data.id}-2`, isLeaf: true }
          ]
          resolve(childNodes)
        }, 500)
      }
    }

    return {
      data,
      defaultProps,
      loadNode
    }
  }
}
</script>

Ключевые моменты:

  • lazy — включает ленивую загрузку узлов.
  • load — функция, вызываемая для загрузки дочерних элементов.
  • node.level позволяет различать корневой и дочерние уровни.
  • Асинхронная загрузка может использовать API-запросы к серверу вместо setTimeout.

Lazy Loading в Table

В el-table lazy loading реализуется через компонент el-table-column с type="expand" для динамической загрузки данных расширяемого ряда. Это особенно полезно при работе с большим объёмом данных, где детали строки нужно подгружать только по необходимости.

<template>
  <el-table :data="tableData">
    <el-table-column prop="name" label="Имя"/>
    <el-table-column type="expand">
      <template #default="props">
        <el-table :data="props.row.children" v-if="props.row.childrenLoaded">
          <el-table-column prop="detail" label="Детали"/>
        </el-table>
      </template>
    </el-table-column>
  </el-table>
</template>

<script>
import { ref } from 'vue'

export default {
  setup() {
    const tableData = ref([
      { id: 1, name: 'Запись 1', children: [], childrenLoaded: false }
    ])

    const loadChildren = (row) => {
      return new Promise(resolve => {
        setTimeout(() => {
          row.children = [
            { id: `${row.id}-1`, detail: 'Подробности 1' },
            { id: `${row.id}-2`, detail: 'Подробности 2' }
          ]
          row.childrenLoaded = true
          resolve()
        }, 500)
      })
    }

    return {
      tableData,
      loadChildren
    }
  }
}
</script>

Особенности:

  • Дочерние строки загружаются только при раскрытии.
  • Признак childrenLoaded предотвращает повторные запросы.
  • Можно интегрировать с API для получения данных на лету.

Lazy Loading модальных окон и динамических компонентов

el-dialog или любые динамические компоненты можно загружать только при их вызове с помощью Vue Dynamic Import и defineAsyncComponent.

<script setup>
import { ref, defineAsyncComponent } from 'vue'

const showDialog = ref(false)
const AsyncDialog = defineAsyncComponent(() => import('./MyDialog.vue'))

const openDialog = () => {
  showDialog.value = true
}
</script>

<template>
  <el-button @click="openDialog">Открыть диалог</el-button>
  <component v-if="showDialog" :is="AsyncDialog" @close="showDialog = false"/>
</template>

Преимущества:

  • Снижается первоначальный вес приложения.
  • Компонент загружается только при необходимости.
  • Можно комбинировать с кэшированием для многократного использования без повторной загрузки.

Настройки оптимизации lazy loading

  1. Загрузка порциями: использовать серверный API с пагинацией.
  2. Кэширование загруженных узлов или данных: предотвращает повторные запросы.
  3. Индикация загрузки: добавление спиннера через el-loading улучшает UX.
  4. Контроль глубины загрузки: особенно в деревьях с большим количеством уровней.

Вывод

Lazy loading в Element Plus — ключевой инструмент для создания высокопроизводительных интерфейсов с большим объёмом данных. Он позволяет загружать элементы по мере необходимости, минимизируя использование ресурсов и ускоряя первый рендер страницы. Комбинация el-tree, el-table и динамических компонентов с отложенной загрузкой делает интерфейс приложения плавным и отзывчивым.