Otimização de desempenho de front-end: Use a rolagem virtual para melhorar o desempenho de renderização de lista longa

No desenvolvimento front-end, geralmente encontramos cenários em que uma grande quantidade de dados precisa ser renderizada, como listas de produtos em sites de comércio eletrônico, fluxos de informações em plataformas sociais e assim por diante. Quando a quantidade de dados é grande, a renderização direta de todos os dados para a página fará com que a página congele ou até falhe. Para resolver esse problema, podemos usar a tecnologia Virtual Scrolling (Rolagem virtual) para melhorar o desempenho de renderização de lista longa.

Este artigo apresentará o princípio da rolagem virtual em detalhes e demonstrará como implementar a rolagem virtual por meio de um exemplo simples.

Princípio da rolagem virtual

A ideia central da rolagem virtual é renderizar apenas os itens da lista na área visível, não todos os dados. Quando o usuário rola a página, calculamos dinamicamente os itens da lista na área visível atual e renderizamos apenas essa parte dos dados. Dessa forma, não importa o tamanho da lista, só precisamos manter um certo número de nós DOM, o que melhora muito o desempenho.

Exemplo: Implementando um scroll virtual simples

Para demonstrar a implementação da rolagem virtual, criaremos uma lista longa simples. Cada item da lista consiste em um número de sequência e um quadrado de cor aleatória.

Primeiro, precisamos criar um array com muitos dados:

javascript复制
const itemCount = 10000;
const items = Array.from({ length: itemCount }, (_, index) => ({
  id: index,
  color: `#${Math.floor(Math.random() * 16777215).toString(16)}`,
}));

Em seguida, criamos um VirtualListcomponente chamado para implementar a rolagem virtual. Este componente precisa receber os seguintes parâmetros:

  • items: dados da lista
  • itemHeight: a altura do item da lista
  • visibleCount: o número de itens da lista na área visível
javascript复制
class VirtualList {
  constructor({ items, itemHeight, visibleCount }) {
    this.items = items;
    this.itemHeight = itemHeight;
    this.visibleCount = visibleCount;
    this.init();
  }

  // ...
}

No initmétodo, precisamos criar um elemento contêiner e definir suas propriedades de altura e estouro. Ao mesmo tempo, precisamos criar um elemento de espaço reservado para expandir a altura do contêiner para que ele possa rolar normalmente.

javascript复制
init() {
  this.container = document.createElement('div');
  this.container.style.height = `${this.visibleCount * this.itemHeight}px`;
  this.container.style.overflow = 'auto';

  this.placeholder = document.createElement('div');
  this.placeholder.style.height = `${this.items.length * this.itemHeight}px`;
  this.container.appendChild(this.placeholder);

  this.renderItems();
  this.bindEvents();
}

No renderItemsmétodo, precisamos calcular os itens da lista na área visível atual e renderizá-los na página.

javascript复制
renderItems() {
  const scrollTop = this.container.scrollTop;
  const startIndex = Math.floor(scrollTop / this.itemHeight);
  const endIndex = Math.min(startIndex + this.visibleCount, this.items.length);

  const fragment = document.createDocumentFragment();
  for (let i = startIndex; i < endIndex; i++) {
    const item = this.items[i];
    const itemElement = document.createElement('div');
    itemElement.style.height = `${this.itemHeight}px`;
    itemElement.style.backgroundColor = item.color;
    itemElement.textContent = `Item ${item.id}`;
    fragment.appendChild(itemElement);
  }

  this.container.innerHTML = '';
  this.container.appendChild(this.placeholder);
  this.container.appendChild(fragment);
}

Por fim, precisamos ouvir o scrollevento do contêiner para atualizar os itens da lista à medida que o usuário rola a página.

javascript复制
bindEvents() {
  this.container.addEventListener('scroll', () => {
    this.renderItems();
  });
}

Agora podemos criar uma VirtualListinstância de e adicioná-la à página:

javascript复制
const virtualList = new VirtualList({
  items,
  itemHeight: 50,
  visibleCount: 10,
});

document.body.appendChild(virtualList.container);

Com este exemplo simples, implementamos uma longa lista com rolagem virtual. Embora este exemplo seja relativamente simples, ele demonstra os fundamentos da rolagem virtual. Em projetos reais, podemos otimizá-lo e expandi-lo conforme necessário.

Resumir

虚拟滚动是一种提升长列表渲染性能的有效方法。通过只渲染可视区域内的列表项,我们可以大大减少 DOM 节点的数量,从而提高页面性能。希望本文能帮助你理解虚拟滚动的原理,并在实际项目中应用这一技术。

Acho que você gosta

Origin juejin.im/post/7250374485567389755
Recomendado
Clasificación