iQIYI APP Android otimização de desempenho de máquina de baixo custo

01

   fundointroduzir

No mercado de smartphones, os modelos topo de linha costumam atrair mais atenção, mas os modelos de baixo custo também ocupam uma fatia que não pode ser ignorada. Para atender às necessidades do mercado de baixo custo, muitos fabricantes continuam a lançar séries de telefones celulares de baixo custo. Além disso, os modelos de médio a alto padrão nos últimos anos foram agora classificados como modelos de baixo custo com a rápida iteração do hardware do sistema. O iQiyi APP possui uma enorme base de usuários, entre os quais os usuários de modelos de baixo custo também representam uma parte considerável. A otimização de máquinas de baixo custo pode trazer uma experiência de usuário estável, suave e eficiente para esses usuários. A seguir, será apresentada a estratégia de otimização do iQiyi APP para máquinas de baixo custo em três dimensões: partida a frio, fluência e velocidade de carregamento.


Estratégia de classificação de máquinas de baixo custo
Antes de introduzir a otimização, vamos dar uma olhada nos padrões das máquinas de baixo custo. O julgamento das máquinas de baixo custo geralmente é baseado em fatores como modelo do dispositivo, tamanho da memória e versão do sistema. O iQiyi APP possui sua própria estratégia de classificação de máquinas de baixo custo, que pode configurar estratégias de otimização por cenário (inicialização, fluência, etc.) e níveis (memória, modelo, sistema, etc.) no contexto da política para garantir a melhor experiência em diferentes cenários.

02

   Iniciar otimização

O lançamento é a primeira porta que um APP abre para os usuários. Seu tempo demorado afeta diretamente a experiência de visualização e retenção subsequente do usuário e tem um impacto significativo nos indicadores de negócios. Portanto, a otimização de startups é um conteúdo de trabalho fundamental na direção da otimização técnica.

Introdução relacionada

O ponto inicial e o ponto final da fase de inicialização: o iQiyi APP usa Application.attachBaseContext como ponto de partida; os dados da página inicial exibem o ponto final. A duração desta fase é considerada o tempo normal de inicialização a frio online. Isso passa principalmente pelo estágio de criação do aplicativo, estágio de criação e exibição de MainActivity, publicidade, carregamento e renderização de dados de navegação superior e inferior da página inicial, carregamento e renderização de dados da página inicial.
Nesse processo, é necessário resolver qual trabalho a camada de negócio realizou, avaliar a necessidade e o tempo de sua execução, e a racionalidade do thread de agendamento é necessário monitorar o status do thread principal para verificar se ele está funcionando; caiu no sono de longo prazo; o monitoramento e gerenciamento de mensagens de fundo/mensagem principal, se alguma tarefa que não atende às expectativas é acionada, se os recursos do sistema são totalmente utilizados, se as oportunidades ociosas são totalmente utilizadas para pré-carregamento, etc.
Atomização de funções de negócios: para agendar tarefas na fase de inicialização de maneira ordenada e alocar recursos de maneira razoável, um conjunto de estrutura de gerenciamento de tarefas TaskManager foi desenvolvido e a implementação da função de negócios foi empacotada em tarefas personalizadas, dividida em detalhes suficientes e projetado Determine as dependências de execução entre tarefas, os threads que devem ser agendados para execução, o tempo de execução, etc. e, em seguida, entregue-os ao TaskManager para processamento unificado. Esta camada de gerenciamento de tarefas é a base para nossa implementação de otimização de inicialização.


Prática de otimização

Mesclagem da página inicial da tela aberta

No início, o iQiyi APP tinha duas atividades: a tela de abertura e a página inicial. As duas atividades trouxeram alguns problemas de experiência do usuário: a máquina de baixo custo obviamente atrasa quando a tela é aberta e a página inicial é acessada. não é exibido imediatamente, e o usuário pode ver os dados da página inicial e as imagens têm um processo de carregamento do zero.
A maioria das cenas na fase de abertura de tela tem anúncios de abertura de tela. Mesclar a abertura de tela e a página inicial em uma atividade. Use a fase de publicidade de abertura de tela para carregar a página inicial abaixo da página de abertura de tela e separar os dados da página inicial e a interface do usuário. exibição para processamento paralelo. Ao maximizar esse estágio, a página inicial pode ser exibida imediatamente no final da tela de inicialização e os atrasos em máquinas de baixo custo são significativamente melhorados .
A renderização da página inicial também tem certo impacto na abertura da tela publicitária. A exibição da contagem regressiva do anúncio é instável e os efeitos de alguns tipos de anúncio não são suaves. O carregamento da página inicial é dividido em várias etapas para resolver o problema de acionamento do retorno de chamada do anúncio. A exibição da contagem regressiva utiliza a renderização do SurfaceView para garantir sua estabilidade.


Otimização do agendamento de tarefas

Com base no tipo de inicialização, organize a sequência de execução da tarefa na fase de inicialização para avançar, atrasar ou não executar, para que os usuários possam ver a página de destino o mais cedo possível. A seguir estão os ajustes feitos pelo iQiyi nas tarefas no caminho normal de inicialização de máquinas de baixo custo.


Resolver contenção de bloqueio

Competição de bloqueio de carregamento da biblioteca nativa: O carregamento da biblioteca da camada C está bloqueado. A camada Java abre vários threads para carregar a biblioteca Lib. Depois de atingir a camada C, o carregamento ainda será executado em sequência, o que fará com que o thread da camada Java seja bloqueado. e espere. iQIYI precisa carregar a biblioteca Lib no estágio Application e precisa chamar o método JNI relevante depois que o thread principal aguardar a conclusão de seu carregamento e ao encontrar a situação em que o módulo de reprodução abre a página de reprodução para fins externos; é necessário pré-carregar a reprodução. A biblioteca Lib relacionada é necessária, o que fará com que o thread principal entre em estado de espera. Ao identificar a página inicial de destino durante a fase de inicialização, você pode decidir se deseja realizar o pré-carregamento da biblioteca Lib relacionada à reprodução, evitando assim o atraso da maioria dos usuários que normalmente acessam a página inicial. (Máquina de teste Redmi K40, sistema Android12)

Concorrência de bloqueio de recursos: antes que a página inicial do iQiyi seja exibida, outros módulos pré-carregam arquivos de layout em subthreads, resultando em uma competição acirrada por bloqueios de camada LayoutInfalter / ResourceManager / AssertsManager. Agende a tarefa de pré-carregamento do layout para ser executada após a exibição da página inicial e restrinja o layout pré-carregado para ser executado no mesmo subthread. Você pode ver que o número de conflitos de bloqueio é bastante reduzido após a melhoria, o que permite a melhoria. página inicial para ser exibida mais rapidamente.


Perfis de linha de base

Perfis de linha de base: o Google lançará perfis de linha de base em 2022, permitindo que os desenvolvedores criem perfis de linha de base de código de ponto de acesso personalizados em apk. Durante a instalação do APP, o sistema pré-compila códigos de hotspot antecipadamente por meio de arquivos de configuração. Você pode pular as etapas de interpretação e compilação just-in-time dos caminhos de código incluídos no tempo de execução para melhorar a velocidade da primeira execução do código de inicialização.
Perfis de inicialização: os perfis de inicialização são um subconjunto dos perfis de linha de base mencionados acima. O uso de perfis de inicialização pode melhorar o layout do código no arquivo DEX do APK, otimizando ainda mais as classes e métodos incluídos. O iQiyi APP cria o código da fase de inicialização no mesmo arquivo DEX por meio do arquivo de configuração de inicialização. Usando as duas estratégias acima, a primeira velocidade de lançamento do iQiyi APP em alguns modelos é aumentada em cerca de 10%.



Otimização de lançamento de link externo

Obter links externos também é uma forma importante de começar. Geralmente é iniciado por H5, compartilhamento, APP de terceiros, etc. A diferença da inicialização a frio normal é que os links externos geralmente não são a página inicial, mas um alvo específico. página. O cenário mais comum para iQiyi é abrir a página de reprodução. Se identificarmos a página de destino com antecedência (estágio do aplicativo), podemos ajustar a prioridade da tarefa para a página de destino. Quando o link externo abrir a página de reprodução, podemos. identificar a página de jogo com antecedência e associar o jogador a ela. A tarefa é inicializada com antecedência. Através desta estratégia, links externos integrados de baixo custo podem acelerar a transmissão em cerca de 1,5 segundos.


03

   Otimização de fluência

Introdução relacionada
A maioria das páginas do iQiyi APP são desenvolvidas com base na estrutura de cartão autodesenvolvida. A estrutura do cartão é uma estrutura de UI altamente reutilizável com base no uso de código nativo para implementar o layout básico da UI e a lógica de negócios, o estilo básico do contêiner é controlado por meio do controle CSS emitido pelo back-end para obter a reutilização geral do bloco de página. ajuste fino de estilos de conteúdo. É uma solução para conseguirmos a reutilização geral da página e o ajuste fino local em ambas as extremidades (Android e IOS). Com base neste framework, a suavidade das páginas do APP é otimizada. O framework Card possui as seguintes funcionalidades:
  • Alta capacidade de reutilização: os blocos de conteúdo (blocos) são compostos por controles, as linhas são compostas por vários blocos; A menor unidade de negócio reutilizável é o Block.
  • Altamente dinâmico: Suporta configuração de arquivos CSS em segundo plano e modificação dinâmica do estilo de uma determinada UI (tamanho do texto, cor, cantos arredondados, etc.).

Prática de otimização

Estilo Nativo

A dinâmica e a reutilização da página do Cartão levam à complexidade do layout da UI. Um tipo de bloco precisa ser compatível com vários estilos. Por exemplo, os quatro cantos de uma imagem precisam ser incorporados com vários tipos de lógica de subscrito. Os tipos de subscrito incluem imagens puras, texto simples, imagens + texto e opcional Selecione o. forma média. A implementação de vários estilos resultará em um grande número de visualizações e níveis profundos de aninhamento, fazendo com que algumas páginas não sejam suaves o suficiente para deslizar em máquinas de baixo custo.
Para otimizar esta situação, foram selecionados alguns Cartões com formas comerciais estáveis, os estilos desses Cartões foram solidificados e o layout foi bastante simplificado. Isso provoca um aumento significativo na taxa de quadros ao deslizar para cima e para baixo. Por exemplo, no cartão de fluxo em cascata, reduzimos o número de visualizações implementadas de 40+ para 17 e reduzimos o nível de layout de 6 para 2 camadas em diferentes máquinas de baixo custo , o que trouxe cerca de 10% a 20% de deslizamento do quadro; taxa aumentou .

Ver desenho de mesclagem
O efeito de melhoria trazido pela estratégia de simplificação de layout acima é óbvio, mas devido à diversificação das formas de negócios, algumas visões necessárias não podem ser excluídas. Para reduzir ainda mais o número e o nível de visualizações, várias visualizações em layouts de bloco comumente usados ​​são mescladas em uma visualização personalizada, e a tela da visualização é usada para desenhar texto, imagens, botões e outras informações de estilo. Este método pode efetivamente reduzir o número de visualizações e níveis de aninhamento, mas ainda precisa lidar com o evento de clique e o efeito de pressionamento de cada elemento. Em máquinas de baixo custo , essa estratégia pode provocar um aumento deslizante na taxa de quadros de cerca de 1~2fps .


Pré-criação e carregamento assíncrono

Pré-criação de layout: Dentre os três estilos de Cards apresentados na imagem acima, é utilizado o mesmo tipo de bloco (foto acima e abaixo). Pré-carregamos esses layouts de bloco comumente usados ​​e altamente reutilizáveis ​​no pool de cache durante a fase de inicialização, para que os layouts pré-criados possam ser usados ​​diretamente no deslizamento da lista, reduzindo assim o tempo de inflação no desenho da IU.
Criação assíncrona de layout : a pré-criação tem um bom efeito em layouts comumente usados, mas layouts incomuns ainda são responsáveis ​​pela maioria. Este tipo de layout usa AsyncLayoutInflater para criar de forma assíncrona o layout que aparecerá durante o processo de rolagem, reduzindo o tempo de criação do. layout de rolagem no thread da UI Ao mesmo tempo, também pode melhorar a eficiência da pré-busca do RecyclerView.
Pré-busca do RecyclerView: muitas páginas do APP iQiyi usam o RecyclerView aninhado para criar formulários de produtos de rolagem horizontal. A maioria dos cartões neste formulário exibirá de 3 a 5 itens em uma tela. Diferentes configurações de pré-busca são definidas de acordo com diferentes formulários. pode reduzir o atraso quando este tipo de cartão é exposto.
O thread principal reduz a execução de tarefas não UI : Leva tempo para detectar o thread principal durante o processo de rolagem. Verifica-se que algumas tarefas não relacionadas ao desenho são executadas no thread principal. , etc. e os coloca em tarefas assíncronas para execução.


Agendamento de mensagens da IU de inicialização a frio

Durante o processo de inicialização a frio de máquinas de baixo custo, o consumo de recursos atingirá gradualmente um estado de pico, há um grande número de mensagens de UI (que precisam ser executadas no thread de UI) e outras tarefas em segundo plano que precisam ser executadas; Por meio de interceptação e análise de pontos ocultos, mais de 4.000 mensagens (dentro de 15 segundos) precisam ser executadas no thread da UI neste estágio. O tempo de execução dessas mensagens varia de 1ms a 150ms em máquinas de baixo custo. Quando essas mensagens são executadas, as mensagens de renderização da IU do sistema serão atrasadas. Em máquinas de baixo custo, os usuários enfrentam problemas como atraso de deslizamento e resposta lenta ao clique quando o APP é iniciado pela primeira vez.
Para resolver esse problema, nossa solução é interceptar todas as mensagens enviadas para o thread da UI e adicioná-las a uma fila de mensagens customizada, em seguida, monitorar se a fila de mensagens da UI do sistema está ociosa e, quando ociosa, retirar mensagens da fila customizada e redirecionar; além disso, um mecanismo de lista de permissões é adicionado para liberar algumas mensagens de alta qualidade; Existe um mecanismo de fallback para lidar com exceções.
Ao agendar mensagens de UI, o atraso das máquinas de baixo custo durante a fase de inicialização a frio foi significativamente melhorado por meio do monitoramento on-line de big data, o número de quadros congelados e perdidos foi significativamente reduzido; Durante a fase de inicialização a frio , a taxa de quadros aumenta em cerca de 8 fps .


Estratégia de degradação de desempenho

Em máquinas de baixo custo, o downgrade de alguns efeitos pode efetivamente reduzir o atraso em cenários específicos. O iQiyi APP implementou a seguinte estratégia de downgrade.
Downgrade de efeitos de movimento: efeitos de movimento de navegação superior e inferior rebaixados para imagens estáticas, efeitos de movimento de controle de reprodução desativados, efeitos de movimento simplificados para algumas funções do produto, etc.
Downgrade de reprodução: estratégias como rolar a reprodução atrasada e não iniciar algumas cenas.
Downgrade de pré-carregamento do ViewPager: desativa o pré-carregamento das guias esquerda e direita, reduzindo o tempo de desenho da visualização e a sobrecarga de memória.
Downgrade de imagem: algumas animações de página não são reproduzidas e as imagens usam o formato de 565 pixels.


04

   Otimização da velocidade de carregamento

Introdução relacionada
Além da otimização inicial mencionada, também nos concentramos na otimização de algumas páginas importantes, pois essas páginas são visitadas com muita frequência pelos usuários e sua otimização pode melhorar significativamente a experiência do usuário. Por exemplo, a pesquisa é uma das funções frequentemente utilizadas pelos usuários, por isso dissecamos cuidadosamente o comportamento da pesquisa e otimizamos cada etapa da pesquisa.

Prática de otimização

pré-solicitação

Normalmente, o processo de renderização da página geralmente começa a partir do método onCreate da Activity. Em seguida, faça uma solicitação de rede para obter os dados necessários. Após obter os dados específicos, a página é renderizada. Também seguimos esse processo no cenário de pesquisa anterior.
É possível obter os dados necessários com antecedência?
Na verdade, quando o usuário clica na caixa de pesquisa da página inicial, ele já possui os parâmetros necessários para a solicitação de rede. Então você pode iniciar uma solicitação de rede antecipadamente ao clicar. A solicitação de rede e o salto de página serão executados simultaneamente, o que encurta o tempo de solicitação de rede. Se o desempenho da máquina for pior, mais tempo levará para a página clicar no método onCreate e mais tempo levará para otimizar. O tempo de verificação em máquinas de baixo custo é reduzido em cerca de 200 ms.


Emitido em lotes

Quando o usuário entra na página, apenas os dados da primeira tela serão exibidos, enquanto os dados da parte inferior da página não podem ser exibidos até que o usuário execute uma operação deslizante. Portanto, damos prioridade à garantia da exibição dos dados na primeira tela. Ao reduzir o tamanho da primeira entrega de dados, reduzimos o tempo necessário para aquisição, transmissão e análise de dados. Após a conclusão da renderização dos dados da primeira tela, iniciaremos uma solicitação de interface novamente para garantir que os dados subsequentes possam ser apresentados imediatamente quando o usuário realizar uma operação de deslizamento. Esta solução é usada para otimização em muitas páginas importantes, como página inicial, página half-play e pesquisa. Por exemplo, ao usar esta solução no cenário de pesquisa, o tempo de verificação é reduzido em cerca de 200 ms.


pré-criado

Pré-criação de layout: quando a página intermediária de pesquisa está ociosa, criamos layouts altamente reutilizáveis ​​​​no cache com antecedência. Quando a página é realmente renderizada, o layout pré-criado é usado diretamente para evitar o tempo de inflação da visualização.
Pré-criação de fragmentos: Quando a página intermediária de pesquisa está ociosa, o contêiner de fragmentos da página de resultados é criado antecipadamente. Não há necessidade de criar o contêiner correspondente quando a página de resultados é exibida, reduzindo o tempo necessário para criar o contêiner.



Otimização do thread principal

Quando a página é carregada, espera-se que as principais tarefas do thread relacionadas à página sejam executadas primeiro, tanto quanto possível. Se o agendamento de tarefas importantes for interrompido, o efeito de renderização da página será afetado. Por meio de nossa ferramenta Tracepeed interna desenvolvida por nós mesmos, que assume Looper.loop() do thread principal, podemos descobrir as tarefas demoradas no thread principal. Se você achar que as tarefas de baixa prioridade que demoram muito são executadas primeiro, você pode ajustar o agendamento de tarefas para que as tarefas importantes sejam executadas primeiro.
Por exemplo, durante o processo de carregamento da página de resultados de pesquisa, o carregamento da imagem é uma tarefa importante. No entanto, em máquinas de baixo custo, verifica-se que, em alguns casos, outra tarefa irá antecipar o thread principal, fazendo com que o tempo de carregamento da imagem às vezes demore até 1 segundo. Para este cenário, ajuste o agendamento da tarefa para que a tarefa de carregamento de imagem seja executada primeiro e o consumo de tempo se estabilize em mais de 100 ms.

Otimização da lógica de negócios

Para diferentes negócios, também analisamos a lógica de negócios específica e otimizamos a lógica relevante:
  • Otimização de imagem vazia: Quando a seleção é carregada, em alguns cenários, o backend entregará uma imagem vazia, e essa imagem vazia também será carregada, o que aumentará o tempo de carregamento da página. Portanto, limitamos o carregamento de imagens vazias.
  • Otimização lógica de alta frequência: Ao otimizar, os métodos de alta frequência são um ponto que precisa ser focado. Ao otimizar alguns métodos de alta frequência comumente usados, o consumo de tempo de cada página pode ser otimizado. Por exemplo: na inicialização de controles básicos, evita a execução de métodos inúteis e reduz o tempo gasto nesses métodos de alta frequência.
  • Execução assíncrona de métodos demorados: Durante o processo de carregamento da página, também haverá alguma lógica de negócios com baixa prioridade. Quando essas lógicas são descobertas, elas podem ser executadas por meio da estrutura assíncrona, reduzindo assim o tempo de carregamento da página.


Anti-deterioração

Após otimização contínua, o tempo de carregamento da página atingiu um nível estável. No entanto, durante as iterações de desenvolvimento em curso, notamos alguns aumentos no consumo de tempo. Como prevenir eficazmente que este tipo de deterioração aconteça?
Ao incorporar métodos-chave no código, as tarefas do pipeline são executadas regularmente todos os dias e o valor médio é calculado após múltiplas execuções. Use métodos visuais para detectar flutuações no carregamento da página. Se houver deterioração, você pode encontrar intuitivamente a diferença no consumo de tempo entre as duas tarefas por meio da comparação de tarefas e analisar e otimizar a diferença no consumo de tempo.


05

  Resumo e Perspectiva

A otimização de máquinas de baixo custo inclui muitos aspectos. Alguns dos métodos de otimização apresentados acima em vários cenários de negócios principais priorizam os principais problemas de desempenho e melhoram efetivamente o desempenho operacional de máquinas de baixo custo. Entre eles, estão a análise de ferramentas, o monitoramento on-line e os padrões de medição. obrigatórios Não mencionados aqui, essas também são ferramentas importantes para otimização de desempenho. O Android está seriamente fragmentado e há um longo caminho a percorrer para otimizar os telefones de baixo custo. No futuro, continuaremos a refinar e encontrar novos pontos inovadores para otimização, usar a inovação tecnológica para fornecer aos usuários uma experiência de usuário estável e tranquila e promover o crescimento de alta qualidade.


Este artigo é compartilhado pela conta pública do WeChat - iQIYI Technology Product Team (iQIYI-TP).
Se houver alguma violação, entre em contato com [email protected] para exclusão.
Este artigo participa do “ Plano de Criação da Fonte OSC ”. Você que está lendo é bem-vindo para participar e compartilhar juntos.

Companheiro de frango, deepin-IDE de "código aberto" e finalmente conseguiu a inicialização! Bom cara, a Tencent realmente transformou o Switch em uma "máquina de aprendizagem pensante" Revisão de falhas e explicação da situação da Tencent Cloud em 8 de abril Reconstrução de inicialização de desktop remoto RustDesk Cliente Web Banco de dados de terminal de código aberto do WeChat baseado em SQLite WCDB inaugurou uma grande atualização Lista de abril TIOBE: PHP caiu para o nível mais baixo, Fabrice Bellard, o pai do FFmpeg, lançou a ferramenta de compressão de áudio TSAC , o Google lançou um grande modelo de código, CodeGemma , isso vai te matar? É tão bom que é de código aberto - ferramenta de edição de imagens e pôsteres de código aberto
{{o.nome}}
{{m.nome}}

Acho que você gosta

Origin my.oschina.net/u/4484233/blog/11052737
Recomendado
Clasificación