1. Comece a otimização
1. Partida a frio (começar do zero)
Três estágios de partida a frio
1.1 Antes da execução da função principal
- Carregar arquivo executável (arquivo mach-o)
- Carregue a biblioteca de vínculo dinâmico, execute o ajuste do ponteiro de rebase e vincule a ligação do símbolo
- Processamento de inicialização do tempo de execução do Objc, incluindo registro de classes relacionadas ao Objc, registro de categoria e verificação de exclusividade do seletor
- Inicialização, incluindo a execução do método +load(), chamadas de função modificadas por atributo((construtor)) e criação de variáveis globais estáticas em C++
Otimização
- Reduza o carregamento dinâmico da biblioteca . Cada biblioteca em si tem dependências. A Apple recomenda usar menos bibliotecas dinâmicas e tentar mesclar várias bibliotecas dinâmicas quando um grande número de bibliotecas dinâmicas for usado. Em termos de quantidade, a Apple recomenda o uso de até 6 bibliotecas dinâmicas que não sejam do sistema.
- Reduza o carregamento de classes ou métodos que não serão usados após a inicialização
- O conteúdo do método +load() pode ser executado após a conclusão da primeira renderização da tela ou substituído pelo método +initialize() . Porque, em um método +load() , a operação de substituição do método de tempo de execução causará um consumo de 4 milissegundos. Não subestime esses 4 milissegundos. Um pouco faz sentido. A execução do método +load() terá um impacto crescente na velocidade de inicialização.
- Controlar o número de variáveis globais C++
1.2 Depois que a função Main for executada
Refere-se principalmente ao início da execução da função main() e à execução dos métodos relacionados à renderização da primeira tela no método didFinishLaunchingWithOptions de Appdelegate .
- Operações de leitura e gravação de arquivos de configuração necessárias para a inicialização da primeira tela
- Lendo big data da lista da primeira tela
- Muitos cálculos para renderização acima da dobra
Otimização
Classifique funcionalmente quais funções de inicialização são necessárias para a renderização na primeira tela, quais são necessárias para a inicialização do aplicativo e quais só precisam ser inicializadas quando a função correspondente começar a ser usada. Depois de resolver, coloque essas funções de inicialização nos estágios apropriados.
1.3 Primeira renderização de tela concluída
Começa quando a renderização é concluída e termina quando o escopo do método didFinishLaunchingWithOptions termina
Otimização
- Otimização de nível funcional:
Depois que a função main() começa a ser executada e antes que a renderização da primeira tela seja concluída, apenas o negócio relacionado à primeira tela é processado. A inicialização de outros serviços que não sejam da primeira tela, monitoramento de registro, leitura de arquivo de configuração, etc. tudo feito após a conclusão da primeira renderização da tela. - A otimização em nível de método
verifica quais métodos demorados estão no thread principal antes que a primeira renderização da tela seja concluída e atrasa ou executa de forma assíncrona métodos desnecessários e demorados. Normalmente, o método demorado ocorre principalmente quando uma grande quantidade de dados é calculada. O desempenho específico é carregar, editar e armazenar recursos como imagens e arquivos.
2. Início quente
- O aplicativo está na memória e ativo em segundo plano. Clique no ícone novamente para entrar no aplicativo.
3. Métodos de monitoramento para inicialização do APP
- Capture regularmente a pilha de chamadas de método no thread principal e calcule o consumo de tempo de cada método durante um período de tempo
- Conecte o método objc_msgSend para entender o tempo de execução de todos os métodos
2. Problema de Caton
2.1 CPU soma GPU
CUP (Unidade Central de Processamento, unidade central de processamento)
Criação e destruição de objetos, ajuste de atributos de objetos, cálculo de layout, cálculo e composição tipográfica de texto, conversão e decodificação de formato de imagem, desenho de imagem (Core Graphics)
Solução de otimização CUP
- Tente usar objetos leves. Por exemplo, onde o processamento de eventos não é necessário, você pode considerar usar CALayer em vez de UIView.
- Não modifique frequentemente as propriedades relacionadas do UIView, como quadro, limites, transformação, etc.
- Tente calcular o layout com antecedência , calcular o quadro, os limites, etc., e modificá-lo uma vez , não várias vezes ;
- Usar o Autolayout consumirá mais recursos do que definir o quadro diretamente.
- É melhor manter o tamanho da imagem consistente com o tamanho do UIImageView para reduzir os recursos da CPU para operações de escalonamento;
- Controle o número máximo de threads simultâneos
- Tente colocar operações demoradas em subthreads (tamanho do texto, processamento de imagem)
GPU (unidade de processamento gráfico, processador gráfico)
Renderização de textura
Solução de otimização de GPU
- Reduza o número e os níveis de visualizações tanto quanto possível. O desenho de visualizações em vários níveis consome mais recursos da GPU.
- Tente evitar exibir um grande número de imagens em um curto período de tempo e tente combinar várias imagens em uma para exibição.
- O tamanho máximo da imagem que a GPU pode processar é 4096 x 4096. Uma vez ultrapassado esse tamanho, os recursos da CPU serão ocupados para processamento, portanto a textura não deve ultrapassar esse tamanho tanto quanto possível.
- Reduza a visualização transparente (alfa<1). Se houver transparência, será necessário o cálculo da mesclagem . Se não for transparente, defina opaco como SIM.
2.2 Renderização fora da tela (tente evitar a renderização fora da tela)
No OpenGL, a GPU possui 2 métodos de renderização
- Renderização na tela: renderização da tela atual, as operações de renderização são executadas no buffer de tela atualmente usado para exibição
- Renderização fora da tela: renderização fora da tela, abrindo um novo buffer fora do buffer de tela atual para operações de renderização
Razões pelas quais a renderização fora da tela consome desempenho
- Novo buffer precisa ser criado
- Todo o processo de renderização fora da tela requer a troca do ambiente de contexto várias vezes. Primeiro, mude da tela atual (na tela) para fora da tela (fora da tela); após a conclusão da renderização fora da tela, a renderização os resultados do buffer fora da tela são exibidos na tela, você precisa mudar o contexto de fora da tela para a tela atual
Otimização
- Rasterização, reduza o uso de layer.shouldRasterize = YES
- Máscara, reduza o uso de layer.mask
- Cantos arredondados, reduza e defina layer.masksToBounds = YES, layer.cornerRadius maior que 0 (você pode considerar desenhar e cortar cantos arredondados por meio do CoreGraphics ou pedir à IU para fornecer imagens de cantos arredondados)
- Shadow, reduza o uso de layer.shadowXXX (se layer.shadowPath estiver definido, a renderização fora da tela não ocorrerá)
3. Otimização do consumo de energia
- Reduza o consumo de energia da CPU e GPU tanto quanto possível
- Use temporizadores com moderação
- Otimize as operações de E/S
- Tente não gravar dados pequenos com frequência. É melhor escrever em lotes de uma só vez.
- Ao ler e gravar grandes quantidades de dados importantes, considere usar o dispatch_io, que fornece uma API para operações assíncronas de E/S de arquivos baseadas em GCD. Usando dispatch_io o sistema otimizará o acesso ao disco
- Se a quantidade de dados for relativamente grande, é recomendado usar um banco de dados (como SQLite, CoreData)
4. Otimização de rede
- Reduza e comprima dados de rede
- Se os resultados de várias solicitações forem iguais, tente usar o cache
- Use a retomada do ponto de interrupção, caso contrário, o mesmo conteúdo poderá ser transmitido várias vezes quando a rede estiver instável.
- Não tente realizar solicitações de rede quando a rede estiver indisponível
- Permitir que os usuários cancelem operações de rede lentas ou de longa duração e definam tempos limite apropriados
- Para transferências em lote, por exemplo, ao baixar um stream de vídeo, não transfira pacotes muito pequenos, baixe o arquivo inteiro diretamente ou baixe-o em pedaços grandes. Se você baixar anúncios, baixe mais de uma vez e exiba-os lentamente. Se estiver baixando e-mails, baixe vários e-mails de uma vez, não baixe-os um por um
5. Otimização de posicionamento
- Se você precisar apenas determinar rapidamente a localização do usuário, é melhor usar o método requestLocation do CLLocationManager. Após a conclusão do posicionamento, o hardware de posicionamento será desligado automaticamente.
- Caso não seja um aplicativo de navegação, tente não atualizar a localização em tempo real e desligue o serviço de localização após a conclusão do posicionamento.
- Tente reduzir ao máximo a precisão do posicionamento. Por exemplo, tente não usar kCLLocationAccuracyBest, que tem a maior precisão.
- Quando o posicionamento em segundo plano for necessário, tente definir pausesLocationUpdatesAutomaticamente como SIM. O sistema pausará automaticamente as atualizações de localização se for improvável que o usuário se mova.
- Tente não usar startMonitoringSignificantLocationChanges, dê prioridade a startMonitoringForRegion:
- Quando o usuário move, sacode ou inclina o dispositivo, eventos de movimento são gerados e esses eventos são detectados por hardware como acelerômetros, giroscópios e magnetômetros. Em situações onde a detecção não é necessária, estes hardwares devem ser desligados a tempo