Back home

Série 03 de otimização de desempenho do iOS|Problemas comuns com gagueira da lista do iOS

O atraso da lista geralmente é causado pelo fato de o thread principal assumir muito trabalho que compete com o quadro atual durante o processo de rolagem.

O atraso da lista é o problema de desempenho mais comum e mais facilmente mal avaliado em projetos iOS.

Assim que eu vir esta situação e a lista não estiver indo bem, direi imediatamente:

  • SwiftUI List é muito lento?
  • O UICollectionView está configurado incorretamente?
  • Esse controle está inerentemente travado?

Às vezes, esses julgamentos não são totalmente errados, mas muitas vezes são superficiais. A questão real e mais central geralmente é:

Na rolagem, uma ação que depende muito da resposta oportuna do thread principal, quanto trabalho extra o sistema realiza ao mesmo tempo?

Portanto, embora UITableView, UICollectionView e SwiftUI List sejam implementados de maneiras diferentes, eles geralmente enfrentam problemas muito semelhantes.

1. As listas têm maior probabilidade de expor problemas de desempenho do que muitas páginas.

Porque a lista é uma cena contínua e de alta frequência que é sensível a cada quadro.

À medida que o usuário rola, o sistema precisa concluir continuamente o seguinte:

  • Calcular layout
  • Prepare unidades visíveis
  • Unidades de reutilização e reciclagem
  • desenhar conteúdo
  • Responder a gestos

Se o thread principal também for solicitado a realizar muito trabalho extra ao mesmo tempo, como:

  • Decodificação de imagem
  • Montagem de rich text
  • Análise JSON
  • Cálculos de layout automático de alto custo
  • Mudanças freqüentes de status levam à atualização completa

Esse atraso é quase um resultado inevitável.

A razão pela qual a lista é tão popular é que ela parece misteriosa na superfície, mas na verdade está mais próxima disso, o que amplifica a pressão sobre o segmento principal de forma muito óbvia.

2. O problema mais comum é que você faz algo que não deveria fazer neste momento enquanto rola.

Uma abordagem comum ao otimizar é focar apenas no comprimento do código da célula ao otimizar listas. Mas em projetos reais, os motivos dos cartões de lista costumam ser mais parecidos com os seguintes:

  • A imagem não é decodificada até ser exibida
  • A altura do texto é calculada repetidamente durante a rolagem
  • a célula é reformatada e os dados convertidos sempre que aparecem.
  • Muitas atualizações de estado da camada pai acionadas ao rolar a lista
  • Uma pequena alteração faz com que toda a lista seja redesenhada ou o diff fique muito caro

As características comuns desses problemas são: Eles devem ser “não devem ser feitos neste momento da rolagem”.

Portanto, a ideia mais importante para otimização de lista é:

  • Que tarefas podem ser feitas com antecedência?
  • Quais trabalhos podem ser armazenados em cache
  • Quais tarefas podem ser adiadas
  • Quais atualizações podem ser localizadas

3. As imagens costumam ser as culpadas dos atrasos na lista. Superficialmente, eles parecem downloads, mas na verdade estão mais próximos da decodificação e do processamento de tamanho.

Muitas equipes dizem “muitas fotos” quando encontram cartões de lista. Às vezes a direção desta frase está certa, mas a razão muitas vezes está errada.

O que realmente retarda a rolagem é frequentemente:

  • Decodificação de imagem
  • Zoom da imagem
  • Carregamento de tamanho inadequado
  • Aciona frequentemente o processamento de imagem no thread principal

Dito isto, o mais assustador sobre o problema gráfico é que ele pode facilmente inserir trabalhos dispendiosos no caminho crítico de um rolo.

Portanto, o núcleo da otimização de imagens na lista geralmente não é apenas o cache, mas:

  • Prepare o tamanho apropriado com antecedência
  • Reduza a pressão de decodificação no momento da exibição
  • Evite processamento pesado de imagens ao rolar

4. O processamento de dados muitas vezes prejudica silenciosamente a experiência de rolagem.

Isso é mais comum do que se imagina.

Por exemplo, um item da lista precisa ser exibido:

  • Formatação de hora
  • Formatação de valor
  • Combinação de rich text
  • Mapeamento de tags
  • Redação de status complexo

Se essas coisas forem feitas temporariamente durante a fase de configuração da célula, o thread principal continuará a consumir esse custo durante a rolagem.

A parte mais problemática desse tipo de problema é:

  • Funcionalmente completamente correto
  • O custo único não parece exagerado
  • Mas na rolagem de alta frequência, ela será ampliada exponencialmente

Portanto, um princípio muito importante para a otimização do desempenho da lista é: **Deixe a camada de exibição tentar consumir os dados de exibição preparados em vez de fazer muitas conversões durante a rolagem. **

5. Se o método de atualização de status estiver errado, a lista ficará travada e muitas vezes será confundida com um problema de layout.

Alguns problemas de lista não são nada complicados pela célula, mas também pela granularidade da atualização do estado ser muito grosseira.

Por exemplo:

  • Atualize a lista inteira assim que a palavra-chave de pesquisa mudar
  • Curta um item e toda a árvore de status da página será reconstruída
  • Um resultado paginado volta e toda a lista é recalculada

Este tipo de problema é facilmente diagnosticado erroneamente como:

  • Os componentes da UI são muito lentos
  • O sistema de layout não é eficiente

Na verdade, o verdadeiro problema costuma ser:

**Uma mudança em uma pequena empresa desencadeou uma atualização da IU que foi muito maior do que o necessário. **

Portanto, ao solucionar problemas de atrasos na lista, uma coisa que costumo perguntar é:

Quais itens devem ser afetados por esta mudança de status? Por que isso afetou uma área tão grande no final?

6. Quais são os problemas comuns de UITableView, UICollectionView e SwiftUI List?

Embora os detalhes de implementação desses três sistemas sejam muito diferentes, os problemas de desempenho de alta frequência são, na verdade, muito semelhantes:

  • fazendo muito trabalho no thread principal durante a rolagem
  • O item da lista mostra que os dados foram preparados tarde demais
  • O processamento de imagens e textos é colocado no caminho crítico
  • A granularidade da atualização é muito grande
  • Certos layouts ou hierarquias de visualização são muito complexos

Em outras palavras, seus problemas comuns não são:

**A forma interativa da lista em si é particularmente sensível ao tempo do thread principal e à alocação de trabalho. **

Portanto, o mesmo design errado pode causar travamentos semelhantes em três controles de lista diferentes.

7. Uma sequência de solução de problemas mais próxima do combate real

Se eu quiser verificar o problema do atraso da lista hoje, normalmente não alterarei o código primeiro, mas primeiro julgarei nesta ordem:

  1. A gagueira ocorre quando a primeira tela aparece, ao rolar rapidamente ou quando ocorre a paginação.
  2. Se o item da lista atual possui imagens, rich text ou layout complexo.
  3. Se muitas conversões em tempo real são feitas antes da célula ser exibida.
  4. Se uma determinada mudança de estado local desencadeou uma atualização excessivamente em grande escala.
  5. Se há decodificação, dimensionamento ou recálculo sincronizados durante a rolagem.

O valor desta sequência é: Primeiro descubra “que trabalho está ocupando o thread principal com rolagem” em vez de adivinhar primeiro o problema da estrutura.

8. Conclusão: A essência do atraso da lista geralmente é que há muito trabalho acumulado no caminho crítico que não deveria ser preenchido.

Para resumir, eu diria:

A lista está travada e o núcleo geralmente está rolando. Neste cenário de alta frequência, o thread principal carrega muitos custos de layout, decodificação, conversão e atualização excessiva ao mesmo tempo.

Portanto, as coisas mais importantes para a otimização da lista são:

  • Coloque o trabalho com antecedência
  • Armazenar em cache os resultados
  • Reduza a granularidade da atualização
  • Tire a carga extra do caminho crítico

Se você fizer essas quatro coisas corretamente, a experiência da lista geralmente será mais estável do que simplesmente ajustar alguns parâmetros.

FAQ

What to read next

Related

Continue reading