编程知识 cdmana.com

Optimisation des performances iOS · optimisation de la vitesse de démarrage de l'application

Jeter des briques pour attirer le jade

  • Démarrage oui App Première impression pour l'utilisateur , Plus le démarrage est lent, plus la probabilité de perte d'utilisateurs est élevée. ,Une bonne vitesse de démarrage est un élément indispensable de l'expérience utilisateur.
  • Apple est une entreprise qui met particulièrement l'accent sur l'expérience utilisateur, Optimisé ces dernières années App Heure de début de, Surtout l'année dernière. WWDC 2019 keynote [1] Mentionné ci - dessus ,L'année dernière, l'équipe de développement d'Apple a augmenté le temps de démarrage 200%;
  • Même si c'est une promotion. 200%, Mais certaines questions restent sans réponse ,Par exemple,:
    • Pourquoi optimiser autant de temps ?
    • Nous en tant que développeurs ,Quelles autres optimisations pouvons - nous faire pour la vitesse de démarrage?
    • C'est pourquoi nous nous réunissons aujourd'hui WWDC2019 - 423 - Optimizing App Launch [2] Parler de quelque chose à propos du démarrage .

Introduction du concept

Un.、Mach-O
  • Mach-O - Oui. iOS Les types de fichiers des exécutables à différentes périodes d'exécution du système sont collectivement appelés. Il est principalement divisé en trois catégories: :
    • Executable :Fichier exécutable,- Oui. App Principaux binaires en ;
    • Dylib :Bibliothèque dynamique, Sur d'autres plateformes DSO Ou DLL;
    • Bundle : Types spécifiques à la plateforme Apple , Ne peut pas être connecté Dylib. Ne peut passer qu'au moment de l'exécution dlopen() Chargement.
  • Mach-O La structure de base est la suivante: ,Divisé en trois parties:

Insérer la description de l'image ici

  • Analyse structurelle:
    • Header: Inclus Mach-O Informations de base sur le fichier,Par exemple: CPU Architecture,Type de fichier, Nombre d'instructions de chargement, etc. ;
    • Load Commands: C'est ça. Header Zone de commande de chargement arrière ,Structure organisationnelle contenant les fichiers et leur mise en page en mémoire virtuelle,Savoir comment configurer et charger les données binaires au moment de l'appel;
    • Data:Contient Load Commands Chaque élément requis dans Segment Données;
  • La grande majorité Mach-O Les documents sont les suivants: Segment:
    • __TEXT :Extrait de code, Inclure les fichiers d'en - tête 、 Codes et constantes ,Lire seulement non modifiable.
    • __DATA :Section des données, Inclure des variables globales , Variables statiques, etc,Lisible et lisible.
    • __LINKEDIT : Comment charger un programme , Métadonnées contenant des méthodes et des variables(Emplacement,Offset),Et des informations telles que la signature du Code,Lire seulement non modifiable.
2.、Image
  • Ça veut dire Executable,Dylib Ou Bundle Une sorte de.
Trois、Framework
  • Beaucoup de choses s'appellent Framework,Mais dans cet article,Framework Se réfère à un dylib,Il est entouré d'une structure de répertoire spéciale pour enregistrer dylib Documents requis.
  • En général Root Controller De viewDidApper Comme point final du rendu ,Mais en fait, le premier cadre est rendu depuis un certain temps,Apple In MetricsKit La définition du paramètre de démarrage est la première CA::Transaction::commit().
  • Qu'est - ce que CATransaction Et alors?? Regardons d'abord le flux approximatif du rendu :

Insérer la description de l'image ici

  • iOS Le rendu est effectué en un seul processus RenderServer C'est fait,App Il va Render Tree Code emballé pour RenderServer,RenderServer Rappeler le cadre de rendu (Metal/OpenGL ES)Pour générer bitmap, Dans le tampon de cadre ,Le matériel lit le contenu du Framebuffer à partir du signal d'horloge, Rafraîchir l'écran terminé .CATransaction C'est un groupe UI Modifications apportées à, Fusionner en une seule transaction ,Adoption commit Soumettre.
  • Le rendu peut être divisé en quatre étapes :
    • Layout(Mise en page), La source est Root Layer Appelez[CALayer layoutSubLayers],À ce moment - là. UIViewController De viewDidLoad Et LayoutSubViews Appelle,autolayout C'est là que ça marche. ;
    • Display(Dessiner), La source est Root Layer Appelez[CALayer display],Si View C'est fait. drawRect Méthodes, Sera appelé à ce stade ;
    • Prepare(Préparez - vous.), Ce processus complète le décodage de l'image ;
    • Commit(Soumettre),Emballez Render Tree Adoption XPC Envoyé par Render Server.

Insérer la description de l'image ici

Quatre、Mémoire virtuelle(Virtual Memory)
  • La mémoire virtuelle est une couche intermédiaire construite entre la mémoire physique et les processus. Est un espace d'adresse logique continu ,Et l'adresse logique peut ne pas avoir d'adresse de mémoire physique correspondante,Vous pouvez également avoir plusieurs adresses logiques correspondant à une adresse de mémoire physique.
  • La mémoire peut être divisée en mémoire virtuelle et en mémoire physique,Où la mémoire physique est la mémoire réellement utilisée,La mémoire virtuelle est une couche d'adresses logiques établies sur la mémoire physique,Assurer un accès sécurisé à la mémoire tout en fournissant un espace d'adresse continu pour l'application.
  • La mémoire physique et la mémoire virtuelle sont cartographiées en pages,Mais cette relation cartographique ne correspond pas une par une:Une page de mémoire physique peut correspondre à plusieurs pages de mémoire virtuelle;Une page de mémoire virtuelle peut également ne pas consommer de mémoire physique.

Insérer la description de l'image ici

  • iPhone 6s C'est parti.,Mémoire physique Page La taille est 16K,6 Et les appareils précédents sont 4K,C'est iPhone 6 Comparé à 6s L'une des raisons de la chute de la falaise de vitesse de démarrage .
Cinq、Page Fault
  • Lorsque le processus accède à une adresse logique sans adresse physique correspondante,Ça va arriver Page Fault.
Six、Lazy Reading
  • Une page que vous voulez lire est déclenchée sans mémoire Page Fault, Système par appel mmap() Fonction lire la page spécifiée ,Ce processus s'appelle Lazy Reading.
Sept、COW(Copy-On-Write)
  • Lorsque le processus doit modifier le contenu d'une page,Le noyau copie d'abord la partie à modifier,Et puis modifier,Et re - mapper les adresses logiques dans la nouvelle mémoire physique,Ce processus s'appelle Copy-On-Write.
Huit、Dirty Page & Clean Page
  • Image Après le chargement, Contenu modifié Page Appelé Dirty Page, Contient des informations spécifiques au processus .
  • L'opposé s'appelle Clean Page, Peut être régénéré à partir du disque .
Neuf、Mémoire partagée(Share RAM)
  • Quand plusieurs Mach-O Tous dépendent du même Dylib(eg. UIKit)Heure, Le système fera en sorte que ces Mach-O Appel de Dylib Les adresses logiques de tous pointent vers la même zone de mémoire physique, Pour partager la mémoire .
  • Dirty Page Unique au processus ,Ne peut pas être partagé.
Dix、Randomisation de la disposition de l'espace d'adresse(ASLR)
  • Quand Image Lors du chargement dans l'espace d'adresse logique , Le système utilisera ASLR Technique,De faire Image L'adresse de départ est toujours aléatoire , Pour éviter que les hackers ne passent par l'adresse de départ + Offset trouve l'adresse de la fonction .
  • Lorsque le système utilise ASLR Après avoir attribué une adresse aléatoire ,De 0 Toute la section à cette adresse sera marquée comme inaccessible, Signifie illisible ,C'est écrit., Non exécutable .Cette zone est __PAGEZERO Paragraphes, Sa taille est 32 Le système bit est 4KB+,Et 64 Le système bit est 4GB+
Onze、Signature du Code(Code Sign)
  • La signature du Code permet iOS Le système veille à ce que Image Sécurité,Avec Code Sign Lors de la configuration de la signature ,Le contenu de chaque page génère une valeur de hachage chiffrée distincte,Et les stocker dans __LINKEDIT À mi - chemin,Le système vérifie le contenu de chaque page lors du chargement pour s'assurer qu'il n'a pas été altéré.
Douze、dyld(dynamic loader)
  • dyld - Oui. iOS Chargeur binaire sur ,Pour charger Image.Beaucoup pensent dyld Responsable uniquement du chargement de toutes les bibliothèques de liens dynamiques dont dépend l'application, C'est mal compris. .dyld Le processus de travail spécifique est le suivant: :

Insérer la description de l'image ici

XIII.、Load dylibs
  • dyld Chargement Mach-O Sera résolu avant Header Et Load Commands, Et c'est ce qu'on sait. Mach-O Dépendances dylibs,Et ainsi de suite., Pour obtenir tout ce dont vous avez besoin de façon récursive dylib Chargez tout. .
  • En général,Un App Dépendances dylib In 100 - 400 Gauche et droite, La plupart d'entre eux sont systématiques dylib, En raison de la mise en cache et du partage , Vitesse de lecture élevée .
XIV.、Fix-ups
  • Parce que ASLR Et Code Sign Raisons, Il vient d'être chargé. dylib Sont dans un état relativement indépendant , Pour les lier , Doit passer par un Fix-ups Processus.
  • Fix-ups Il existe deux types principaux :Rebase Et Bind.
Quinze.、PIC(Position Independent Code)
  • Raison de la signature du Code ,dyld Impossible de modifier directement la commande , Mais pour ce faire, au moment de l'exécution, Fix-ups,In code gen Heure,Par la dynamique PIC(Position Independent Code)Technique,Code qui ne peut pas être modifié autrement en raison de la restriction de signature du Code, Peut être chargé sur une adresse indirecte .
  • Lorsqu'une méthode est appelée ,D'abord. __DATA Créer un pointeur dans le segment pour pointer vers cette méthode , Ensuite, l'appel indirect est réalisé par ce pointeur .
16.、Rebase
  • Rebase: Réparer le pointeur interne .C'est parce que Mach-O In mmap En mémoire virtuelle , L'adresse de départ aura un décalage aléatoire slide, Vous devez pointer vers l'intérieur et ajouter ceci slide.
  • Rebase Oui.“Parce que ASLR Cause Mach-O C'est une première adresse aléatoire chargée en mémoire”Ce problème est un processus de correction des données.Ajoute un décalage à toutes les adresses de pointeur internes, L'offset est calculé comme suit: :
   Slide = actual_address - preferred_address
  • Tous les besoins Rebase Les informations du pointeur pour ont été encodées à __LINKEDIT - Oui.. Et puis il y a la répétition __DATA Besoins moyens Rebase Plus ce décalage . Ce processus peut se poursuivre Page Fault Et COW,Et donc I/0 Problèmes de perte de performance ,Mais parce que Rebase Adresse continue traitée , Donc le noyau lit les données à l'avance ,Diminution I/O Consommation.
XVII.、Binding
  • Binding: Réparer le pointeur externe .C'est mieux compris.,Parce que c'est comme printf Fonctions externes égales ,L'adresse n'est connue qu'au moment de l'exécution,Binding Est de pointer vers cette adresse .
  • Binding C'est le processus de liaison des symboles externes appelés. Par exemple, nous allons utiliser UITableView, C'est - à - dire le symbole OBJC_CLASS$_UITableView, Mais ce symbole n'est pas là. Mach-O Moyenne,Besoin de UIKit.framework Accès moyen,D'où la nécessité d'adopter Binding Lier cette correspondance ensemble .
  • Au moment de l'exécution,dyld L'implémentation correspondant au nom du symbole doit être trouvée . Et ça demande beaucoup de calculs. , Y compris aller à la table des symboles . Une fois trouvé, la valeur correspondante est enregistrée à __DATA Dans le pointeur .Binding Bien que la quantité calculée de Rebasing Plus,Mais ce qui est vraiment nécessaire I/O Peu d'opérations ,Parce qu'avant Rebasing C'est déjà fait. .
  • Par exemple,:Un Objective C String@“1234”,La compilation au dernier binaire est stockée dans deux section À l'intérieur.:
    • __TEXT,__cstring, Stocker la chaîne réelle "1234"
    • __DATA,__cfstring,Stockage Objective C Métadonnées de la chaîne , Occupation par métadonnées 32Byte, Il y a deux pointeurs dedans. : Pointeur interne ,Pointage__TEXT,__cstring Emplacement de la chaîne dans ; Pointeur externe isa, Pointer vers l'objet de classe , C'est pour ça qu'on peut avoir raison. Objective C Raison du message littéral .
  • Comme le montre la figure ci - dessous:,Au moment de la compilation,String 1234 In__cstringDe 0x10 Division,Alors... DATA Pointeur vers le segment 0x10.Mais mmap Il y a ensuite un décalage slide=0x1000,L'adresse de la chaîne au moment de l'exécution est 0x1010,Alors DATA Le pointeur du segment ne pointe pas correctement .Rebase Le processus consiste à déplacer le pointeur 0x10,Plus slide Devenir 0x1010. L'adresse de l'objet de classe d'exécution est déjà connue ,bind C'est ça. isa Pointer vers l'adresse mémoire réelle .
    Insérer la description de l'image ici
Dix - huit.、dyld2 & dyld3
  • In iOS 13 Avant, Tous les tiers App Tout est passé. dyld 2 Pour démarrer App De,Les principaux processus sont les suivants::
    • Analyse Mach-O De Header Et Load Commands,Trouver la Bibliothèque dont il dépend, Et trouver Récursivement toutes les bibliothèques dépendantes
    • Chargement Mach-O Documentation
    • Recherche de symboles
    • Liaison et modification de base
    • Lancer l'initialisateur
  • Tous les processus ci - dessus se produisent App Au démarrage, Contient beaucoup de calculs et I/O,Donc l'équipe de développement d'Apple pour accélérer le démarrage,In WWDC2017 - 413 - App Startup Time: Past, Present, and Future [4] C'est officiel. dyld3.
  • dyld2 & dyld3 La comparaison est la suivante::

Insérer la description de l'image ici

  • dyld3 Divisé en trois composants :
    • Hors processus MachO Analyseur

      • Tous les effets possibles sur la vitesse de démarrage ont été pré - traités search path、@rpaths Et variables d'environnement
      • Et analyser Mach-O De Header Et la dépendance, Et a terminé la recherche de tous les symboles
      • Enfin, ces résultats sont créés comme une fermeture de démarrage
      • C'est normal. daemon Processus, Vous pouvez utiliser le schéma de test habituel
    • Un moteur en cours de processus , Utilisé pour exécuter la fermeture de démarrage

      • Cette partie est traitée dans le processus
      • Vérifier la sécurité de la fermeture de démarrage , Et ensuite cartographier dylib Au milieu.,Encore un saut vers main Fonctions
      • Pas besoin de résolution Mach-O De Header Et la dépendance, Pas besoin de recherche de symboles .
    • Un service de cache de fermeture de démarrage

      • Système App La fermeture de démarrage de Shared Cache Moyenne, Nous n'avons même pas besoin d'ouvrir un fichier séparé
      • Pour les tiers App,On sera là. App Construire cette fermeture de démarrage lors de l'installation ou de la mise à jour.
      • In iOS、tvOS、watchOSMoyenne, C'est tout. App Terminé avant le démarrage .In macOS Allez.,Parce qu'il y a Side Load App,Le moteur en cours de processus démarre un daemon Processus,Après cela, vous pouvez utiliser la fermeture de démarrage pour démarrer.
  • dyld 3 Il faut beaucoup de temps pour trouver、Calcul et I/O Tout a été réglé à l'avance. , Cela augmente considérablement la vitesse de démarrage .
XIX.、mmap
  • mmap Son nom complet est memory map, Est une technique de cartographie de mémoire ,Vous pouvez cartographier les fichiers dans l'espace d'adresse de la mémoire virtuelle,De cette façon, vous pouvez lire et écrire des fichiers comme vous le feriez en manipulant directement la mémoire. Lors de la lecture de la mémoire virtuelle ,Lorsque le contenu du fichier correspondant n'existe pas en mémoire physique,Déclenche un événement:File Backed Page In, Lire le contenu du fichier correspondant dans la mémoire physique .
  • Au démarrage,Mach-O C'est par mmap Mappé en mémoire virtuelle (Comme le montre la figure ci - dessous:). Certaines pages de l'image suivante sont marquées comme suit: zero fill,Parce que les valeurs initiales des variables globales sont souvent 0,Alors, ça. 0 Pas besoin d'être stocké dans le binaire , Augmenter la taille du fichier . Ces pages sont reconnues par le système d'exploitation ,In Page In Ensuite, réglez - le à 0, Ce comportement s'appelle zero fill.
    Insérer la description de l'image ici
Vingt.、Page In
  • Le chemin de démarrage est déclenché plusieurs fois Page In, C'est plus facile à comprendre. ,Parce que le démarrage lit et écrit beaucoup de choses dans le binaire.Page In Une grande partie du temps de démarrage , Voyons un seul. Page In Processus:
    Insérer la description de l'image ici
  • L'analyse est la suivante::
    • MMU Trouver une page de mémoire physique libre ;
    • Disque de déclenchement IO, Lire les données dans la mémoire physique ;
    • Si oui TEXT Page du paragraphe , Pour décrypter ;
    • Page décryptée , Vérification de la signature ;
  • Où le décryptage est la grande tête ,IO Deuxièmement,. Pourquoi décrypter? ?Parce que iTunes Connect Sera téléchargé Mach-O De TEXT Chiffrement des segments ,Prévention IPA Télécharger et voir le Code directement .C'est pour ça qu'il y a un concept dans le sens inverse appelé“ Casser la coquille ”, C'est ce qui a frappé. TEXT Chiffrement des segments .iOS 13 Ce processus a été optimisé ,Page In Pas besoin de décrypter. .
Vingt et un.、Réarrangement binaire
  • Puisque Page In Ça prend du temps, Y a - t - il un moyen d'optimiser ?
  • Démarrer avec des caractéristiques locales ,C'est - à - dire que seules quelques fonctions sont utilisées au démarrage,La distribution de ces fonctions dans le binaire est fragmentée,Alors... Page In L'utilisation des données lues n'est pas élevée .Si nous pouvions organiser les fonctions de démarrage en intervalles binaires consécutifs, Donc ça réduit Page In Nombre de fois, Pour optimiser le temps de démarrage :
  • Voici un exemple:,Méthodes 1 Et méthodes 3 Est utilisé au démarrage , Pour exécuter le code correspondant , Deux fois. Page In. Si nous mettons la méthode 1 Et 3 Arrangez - vous. ,Alors, juste une fois Page In, Pour augmenter la vitesse de démarrage .
    Insérer la description de l'image ici
  • Linker ld Il y a un paramètre-order_file Prise en charge de l'Organisation des binaires par symbole .Il y a plusieurs façons d'obtenir les symboles utilisés au démarrage, Pas d'explication ici. .

IPA Construire

  • Maintenant que vous construisez ,Il doit donc y avoir des endroits pour définir comment construire,Correspondant à Xcode Deux éléments de configuration dans :
    • Build Phase:Par Target Le processus de construction est défini pour la dimension .Ça pourrait être dans Build Phase Insérer un script dans, Pour faire des constructions personnalisées ,Par exemple, CocoaPod Les ressources de copie sont complétées par des scripts.
    • Build Settings: Configurer les paramètres liés à la compilation et au lien . En particulier, other link flags Et other c flags, Parce qu'il y a beaucoup d'arguments pour compiler et lier , Certains doivent être configurés manuellement ici . Pour de nombreux projets CocoaPod Faire des composants , À ce stade, les options de compilation sont .xcconfig Dans le dossier.
  • Single Target Par exemple, Regardez le processus de construction :
    Insérer la description de l'image ici
  • Description du processus:
    • Fichier source(.m/.c/.swift Attendez.) Est compilé séparément , Exporter le fichier cible correspondant (.o)
    • Fichiers cibles et bibliothèques statiques / Bibliothèque dynamique ensemble , Lien vers le dernier Mach-O
    • Mach-O Sera taillé , Supprimer les informations inutiles
    • Fichiers de ressources tels que storyboard,asset Sera également compilé , Charge plus rapide après Compilation
    • Mach-O Avec les fichiers de ressources , Emballez le dernier. .app
    • C'est exact..app Signature,Inviolable

Compiler

  • Le compilateur peut être divisé en deux parties :Avant et arrière, Les deux IR(Code intermédiaire)En tant que média. De cette façon, les extrémités avant et arrière se séparent ,Afin que les extrémités avant et arrière puissent varier indépendamment,Aucune influence mutuelle.C Le Front de la famille linguistique est clang,swift L'avant de swiftc, L'arrière - plan des deux llvm.
    • Le Front End est responsable du prétraitement , Analyse grammaticale lexicale ,Générer IR;
    • L'arrière - plan est basé sur IR Optimiser,Générer un code machine;

Insérer la description de l'image ici

  • Comment utiliser la compilation pour optimiser la vitesse de démarrage?
    Le nombre de codes affecte la vitesse de démarrage , Pour augmenter la vitesse de démarrage , On peut faire tomber du Code inutile. . Comment calculer quels codes ne sont pas utilisés? ?Peut être utilisé LLVM Insérer des pieux pour réaliser .LLVM Le processus d'optimisation du Code pour Pass,Parce que LLVM Open Source, Nous pouvons ajouter un Pass, Insère du Code dans l'en - tête de la fonction ,Ces codes enregistrent que cette fonction a été appelée, Et télécharger les statistiques pour analyse ,Pour savoir quel Code est inutilisable .
  • Facebook Voilà. LLVM Je l'ai dit. order_file[2]De feature C'est la réalisation d'un pieu similaire .

Liens

  • Après Compilation, Nous avons beaucoup de fichiers cibles , Ensuite, ces fichiers cibles et les bibliothèques statiques , Bibliothèque dynamique ensemble , Lien vers un Mach-O. Le processus lié ne produit pas de nouveau Code , Seulement quelques mouvements et correctifs .

Insérer la description de l'image ici

  • tbd Son nom complet est text-based stub library,C'est parce que le processus de liaison n'a besoin que de symboles,Alors... Xcode 6 C'est parti.,Comme UIKit La Bibliothèque système n'est pas complète Mach-O,Il s'agit plutôt de fournir une information qui ne contient que des symboles, etc tbd Documentation.
  • Début de l'explication Page In Quand,Nous avons mentionné TEXT Le déchiffrement de page d'un segment prend du temps ,Y a - t - il un moyen d'optimiser?Peut passer ld De-rename_section,Prends ça. TEXT Contenu du paragraphe, Comme le déplacement d'une chaîne vers un autre segment ( Il y a beaucoup de chaînes à lire sur le chemin de démarrage ), Pour éviter le temps de déchiffrement .
    Insérer la description de l'image ici

App Démarrage

Un.、 Définition de démarrage
  • Il y a deux définitions pour le démarrage :
    • Généralités: Cliquez sur l'icône pour charger les données de la page d'accueil. ;
    • Au sens étroit: Cliquez sur l'icône pour Launch Image Effacer complètement le premier cadre ;
  • La forme d'entreprise des différents produits est différente , Pour les vibrations ,L'achèvement du chargement des données sur la page d'accueil est la première lecture de la vidéo; Les autres pages d'accueil sont statiques App Dis,Launch Image Disparaître signifie que les données de la page d'accueil sont chargées . Parce que les normes sont difficiles à aligner ,Nous utilisons donc généralement une définition étroite du démarrage:C'est - à - dire:Le point final de démarrage est le premier cadre où le graphique de démarrage disparaît complètement.
  • Le meilleur moment pour commencer est 400ms À l'intérieur,Parce que la durée de démarrage de l'animation est 400ms.
  • Ceci est lancé à partir de la définition de la dimension perçue par l'utilisateur , Comment définir le démarrage dans le code? ?Apple In MetricKit Les calculs officiels sont donnés dans :
    • Point de départ: Temps de création du processus ;
    • Point final:Le premierCA::Transaction::commit();
  • CATransaction - Oui. Core Animation Un mécanisme de transaction fourni , Un groupe UI Modifier l'emballage sur , Envoyé ensemble Render Server Rendre.
2.、App Pourquoi le démarrage est - il si important? ?
  • App Le démarrage est le premier processus interactif avec l'utilisateur , Donc essayez de raccourcir le processus , Donner aux utilisateurs une bonne première impression ;
  • Le démarrage représente la performance globale de votre code , Si les performances de démarrage ne sont pas bonnes ,D'autres parties peuvent ne pas être très performantes
    Le démarrage prendra CPU Et la mémoire, Cela affecte les performances du système et la batterie ;
  • Donc nous devons optimiser le temps de démarrage .
Trois、Type de démarrage

App Les types de démarrage sont divisés en trois catégories

  • Cold Launch C'est - à - dire démarrage à froid ,C'est - à - dire qu'il n'y a pas d'informations mises en cache sur un processus dans le système,En général, il démarre directement après le redémarrage du téléphone App. Les conditions suivantes doivent être remplies pour le démarrage à froid: :
    • Après redémarrage
    • App Pas en mémoire
    • Aucun processus connexe n'existe
  • Warm Launch C'est le démarrage à chaud. , C'est - à - dire si App Le processus a tué,Puis redémarrez immédiatement,Ce démarrage est un démarrage à chaud,Parce que le cache de processus est toujours. Les conditions suivantes doivent être remplies pour le démarrage à chaud: :
    • App Il vient d'être mis fin.
    • App N'a pas été complètement retiré de la mémoire
    • Aucun processus connexe n'existe
  • Resume Launch Ça veut dire suspendu. App Poursuite du processus , La plupart du temps, il n'est pas défini comme un démarrage ,Parce que maintenant App Toujours en vie., Juste dans suspended Statut. Les conditions suivantes doivent être remplies: :
    • App Suspendu
    • App Tout est en mémoire.
    • Il existe des processus connexes
Quatre、App Phase de démarrage
  • App Le démarrage est divisé en trois phases :
    • Initialisation App Travaux préparatoires;
    • Dessiner le premier cadre App Préparation et dessin (La première image ici n'est pas la première image après avoir obtenu les données, Peut être une vue d'occupation ), L'utilisateur et App C'est déjà interactif. ,Par exemple, tabbar Basculer;
    • Dessinez la première page image complète après avoir obtenu toutes les données de la page.
  • Dans cet endroit, Apple a encore souligné ,Suggestion「 L'utilisateur clique depuis App Icône pour interagir à nouveau , C'est la fin de la phase 2. 」 Le meilleur moment pour 400ms À l'intérieur.Pour le moment.,La plupart App N'ont pas atteint cet objectif .
  • En bas, Nous avons divisé les trois étapes ci - dessus en trois étapes ci - dessous. 6 Sections,Décrivez ce qui a été fait pendant ces étapes et ce qui pourrait être optimisé.

Insérer la description de l'image ici

Cinq、Optimisation de démarrage

System Interface

  • Initialisation App Travaux préparatoires, Le système a fait deux choses principales :Load dylibs Et libSystem init;
  • In 2017 Apple a présenté dyld3 Pour le système App Combien d'optimisations ont été apportées ,Cette année dyld3 Développement formel pour les développeurs ,Cela signifie iOS Le système dépend du temps d'exécution du démarrage à chaud mis en cache, Pour réduire le temps de démarrage , C'est l'Ascension. 200% Une des raisons.
  • En plus de ça,,In Load dylibs Phase, Les développeurs peuvent également faire les optimisations suivantes :
    • Évitez les liens inutiles frameworks,In Xcode Dans le projet 「Linked Frameworks and Librares」 Y a - t - il des liens inutiles dans la Section .
    • Évitez de charger des bibliothèques dynamiques au démarrage ,Projet Pods Emballé comme compilé statiquement ,En particulier Swift Projets, La perte de temps ici est énorme. .
    • Lier vos dépendances , Optimisation du cache ici .
  • Peut - être que quelqu'un se demande si c'est utilisé. dyld3 C'est, On n'a pas besoin de faire ça. Static Link C'est, J'en ai encore besoin. ,Si ça vous intéresse, regardez. Static linking vs dyld3 [5] Cet article, Il y a une comparaison détaillée des données .
  • libSystem init Section,Il s'agit principalement de charger certains composants du système moins prioritaires, Cette partie du temps est un coût fixe , Donc nous développeurs n'avons pas besoin de nous soucier .

Static Runtime Initializaiton

  • Cette phase est principalement Objective-C Et Swift Runtime Initialisation de, Tout sera appelé +load Méthodes, Enregistrer les informations de la classe à runtime Moyenne.
  • À ce stade,En principe, il n'est pas recommandé aux développeurs de faire quoi que ce soit,Pour éviter une perte de temps de démarrage, Vous pouvez faire les choses suivantes :
    • In framework Au moment du développement, Initialisation propriétaire publique API;
    • Réduction de la +load Ce que nous faisons ;
    • Utiliser initialize Initialisation paresseuse ;

UIKit Initializaiton

  • Deux choses principales ont été faites à ce stade :
    • Instanciation UIApplication Et UIApplicationDelegate;
    • Démarrer le traitement des événements et l'intégration du système .
  • Donc l'optimisation à ce stade est assez simple , Il y a deux choses à faire. :
    • Réduction maximale UIApplication Travail lors de l'initialisation des sous - classes , Et même non classifié UIApplication;
    • Diminution UIApplicationDelegate Initialisation de.

Application Initializaiton

  • Cette phase est principalement un rappel de l'approche du cycle de vie,Et c'est la partie la plus familière de nos développeurs.
  • Appelez UIApplicationDelegate De App Approche du cycle de vie:
	application:willFinishLaunchingWithOptions: 
    application:didFinishLaunchingWithOptions:
  • UIApplicationDelegate De UI Approche du cycle de vie:
	applicationDidBecomeActive:
  • En même temps,iOS 13 Pour UISceneDelegate Nouveau rappel ajouté :
	scene:willConnectToSession:options:
    sceneWillEnterForeground:
    sceneDidBecomeActive:
  • Est également appelé à ce stade .Si vous êtes intéressé, vous pouvez regarder Getting the Most out of Multitasking C'est Session, Aucune ressource vidéo disponible pour le moment , Je pense que c'est une démonstration en direct. , Donc il n'y a pas de vidéo disponible .
  • À ce stade, Les optimisations que nous pouvons faire :
    • Report de travaux non liés au démarrage
    • Senens Partage des ressources entre

Fisrt Frame Render

  • Cette phase a été principalement consacrée à la création 、 Travaux de mise en page et de dessin des vues ,Et soumettre le premier cadre préparé au rendu de couche. Les fonctions suivantes sont fréquemment appelées :
	loadView
    viewDidLoad 
    layoutSubviews
  • À ce stade, Optimisation que les développeurs peuvent faire :
    • Réduire le niveau de vue , Paresseux pour charger des vues indésirables ;
    • Optimiser la disposition, Réduire les contraintes .
  • Plus de détails sont disponibles à partir de WWDC2018 - 220 - High Performance Auto Layout [6] Middle Understanding .

Extend

  • La plupart App Les données sont acquises de façon asynchrone , Et le rendre à l'utilisateur . Nous appelons cette partie Extend.
  • Parce que cette partie de chaque App Ils se comportent tous différemment. , Apple recommande donc aux développeurs os_signpost Mesurer et analyser lentement et optimiser lentement .

load Exemples

  • Si+load La méthode est simple. , Ça affecte l'heure de début? ?Comme celui - ci+load Méthodes?
	+ (void)load {
     
		printf("1234"); 
	}
  • Après Compilation , Cette fonction sera en binaire TEXT Deux segments existent :__text Fonction mémoire binaire ,cstring Chaîne de stockage 1234. Pour exécuter une fonction , Première visite __textDéclenche une fois Page In Lire dans la mémoire physique , Pour imprimer une chaîne ,À visiter__cstring, Encore une fois. Page In.
  • Pour exécuter cette fonction simple , Le système doit payer deux fois de plus Page In Coût,Alors... load Plus de fonctions ,page in Devient un goulot d'étranglement dans les performances de démarrage .
    Insérer la description de l'image ici
  • static initializer Conditions de production : D'où vient l'initialisation statique? ?Les codes suivants provoquent une initialisation statique
    • attribute((constructor))
    • static class object
    • static object in global namespace
  • Attention!,Ce n'est pas tout static Les variables produisent une initialisation statique , Le compilateur est intelligent ,Les variables qui peuvent être déterminées au cours de la compilation sont directement inline.
	//  Initialisation statique 
	class Demo{
     
	static const std::string var_1; 
	};
	const std::string var_2 = "1234"; 
	static Logger logger;
	//  Aucune initialisation statique n'est générée 
	static const int var_3 = 4; 
	static const char * var_4 = "1234";
  • std::string Synthétisera static initializer Parce que le constructeur doit être exécuté lors de l'initialisation, Le compilateur ne sait pas quoi faire. , Ne peut être reporté qu'à l'exécution .
  • +load Et static initializer Après l'exécution,dyld Le processus de démarrage sera confié à App,Début de la mise en œuvre main Fonctions.main La chose la plus importante à faire dans une fonction est d'initialiser UIKit.UIKit Il y a deux initialisations majeures :
    • Initialisation UIApplication;
    • Démarrer le thread principal Runloop;
  • Parce que le thread principal dispatch_async Est basé sur runloop De,Donc, dans+load Si vous appelez dispatch_async Sera exécuté à ce stade .
  • Le thread sort après l'exécution du Code , Il est évident que le fil principal ne peut pas sortir , Il faut un mécanisme. : Exécuter la tâche lorsque l'événement arrive , Sinon, laissez le fil dormir ,Runloop C'est ce qui fait ça. .
  • Runloop Est essentiellement unWhile Cycle, Dans la partie orange de l'image mach_msg_trap Est de déclencher un appel système ,Laisser les fils dormir, Attendre que l'événement arrive ,Réveillez - vous. Runloop, Continuez avec ça. whileCycle.
  • Runloop Plusieurs tâches principales :Source0,Source1,Timer,GCD MainQueue,Block. Au bon moment du cycle ,Oui. Observer Pour informer l'extérieur de l'exécution .
    Insérer la description de l'image ici
  • Alors,Runloop Quel rapport avec le démarrage? ?
    • App De LifeCycle La méthode est basée sur Runloop De Source0 De;
    • Le rendu du premier cadre est basé sur Runloop Block De.
      Insérer la description de l'image ici
  • Runloop Il y a plusieurs applications principales au démarrage :
    • Statistiques précises sur l'heure de début ;
    • Trouver un moment , Effectuer des tâches d'échauffement à la fin du démarrage ;
    • Utilisation Runloop Éliminer les tâches de préchauffage de démarrage longues .

Mesure App Heure de début

  • Pour trouver un problème pendant le démarrage , Plusieurs mesures doivent être effectuées et comparées avant et après . Mais si la variable n'est pas bien contrôlée , Cela peut entraîner des erreurs .
  • Donc, pour s'assurer que les données mesurées reflètent vraiment le problème, Nous devons réduire l'instabilité ,S'assurer que les mesures sont effectuées dans un environnement contrôlé et proche, Enfin, utilisez des résultats cohérents pour analyser .
  • ① Cohérence conditionnelle
    • Pour assurer un environnement cohérent , On peut faire les choses suivantes. :
      • Redémarrer le téléphone,Et attendre 2-3 Minutes
      • Activer le mode de vol ou utiliser un réseau analogique
      • Non utilisé ou non modifié iCloud Compte
      • Utiliser release Mode d'exécution build
      • Mesure du temps de démarrage à chaud
      • iColud Le changement de compte affecte le rendement , Ne changez pas de compte ou ne l'ouvrez pas. iCloud.
  • ② Points de mesure
    • Dans la mesure du possible, les essais sont effectués à l'aide de données représentatives;
    • Si des données représentatives ne sont pas utilisées pour les essais, Il y a une déviation. ;
    • Tester avec différents équipements anciens et nouveaux ;
    • Enfin, vous pouvez utiliser XCTest Pour tester, Plusieurs fois de plus , Moyenne des résultats .
  • ③ À propos de l'utilisation XCTest Informations sur l'heure de début de l'essai ,Regarde ça. WWDC2019 - 417 - Improving Battery Life and Performance [7], Mais je l'ai testé. , Il semble qu'il y en ait encore une partie. API Pas encore ouvert ,Pas encore disponible.

Utiliser Instruments Analyse et optimisation App Processus de démarrage

Un.、Minimize Work
  • Retarder le travail indépendant du premier cadre
  • Supprimer le travail de blocage du fil principal
  • Réduire l'utilisation de la mémoire
2.、Prioritize Work
  • Définir les priorités des tâches
  • Profitez - en. GCD Pour optimiser votre vitesse de démarrage
  • Garder les choses importantes prioritaires
Trois、Optimize Work
  • Simplification des travaux existants , Par exemple, ne demander que les données nécessaires
  • Algorithme d'optimisation et structure des données
  • Mise en cache des ressources et des calculs
Quatre、Utiliser Instruments Analyse App Processus de démarrage
  • Quand vous savez comment optimiser ,Nous devons analyser notre processus de démarrage.Xcode 11 De Instruments Un nouveau App launch Modèle, Permettre aux développeurs de mieux s'analyser App Vitesse de démarrage.

Insérer la description de l'image ici

  • Après l'exécution, vous pouvez voir le temps spécifique pour chaque phase, Optimiser à partir des données , Vous pouvez également voir des appels de fonctions qui prennent du temps .

Optimisation du système

  • Apple a fait beaucoup d'optimisation ,Les points saillants suivants sont les optimisations liées à la vitesse de démarrage:

Insérer la description de l'image ici

  • Mais je ne sais pas si c'est le temps. ,In session Il y a très peu d'explications à ce sujet. ,C'est difficile à comprendre 200% Ce qui s'est passé.
  • Mais Craig Federighi In The Talk Show Live From WWDC 2019, With Craig Federighi and Greg Joswiak[9] Pourquoi optimisé 200% J'ai dit quelque chose comme ça. :

Isn’t that crazy that was quite a discovery for us. No it turns out that over times as in terms of the way the apps were encrypted and the way fair play worked and so forth. The encryption became part of the critical path actually of launching the apps. I mean the processors are capable or up and through the thing that actually it was a problem. And then there are other optimizations that based on what was visible to system at certain things. And so it actually cut out optimization opportunities and so when we really identified that opportunity we said okay. We can actually come up with better format that’s gonna eliminate that being on the critical path, It’s going to enable all these pre-binding things. And then we did a whole bunch of other work to optimize the objective-c runtime to optimize the linker the dynamic linker a bunch of other things and you put it all together. And yeah that I mean a cold launch this is we’ve never had a win like this to launch time in a single release.

  • De ce passage, ,Sauf que dyld3 Au - delà du mérite ,La réduction du chiffrement des signatures de code est également une des optimisations.

Surveiller les utilisateurs en ligne App Démarrage

  • Xcode 11 In Xcode Organizer Ajout d'un nouveau panneau de surveillance ,Ce panneau permet de visualiser les données de l'utilisateur dans plusieurs dimensions, Cela comprend également le temps moyen de démarrage .
  • Quand tu passes Instruments Analysez votre processus de démarrage , Et après beaucoup d'optimisation, , Vous pouvez passer Xcode Organizer Pour analyser exactement comment vous optimisez cette fois.
  • Bien sûr, vous pouvez passer par le nouveau MetricKit [10] Obtenir des données personnalisées ,Référence spécifique WWDC2019 - 417 -Improving Battery Life and Performance [11].

Références

版权声明
本文为[ForeverWJ]所创,转载请带上原文链接,感谢
https://cdmana.com/2021/10/20211013211741744Q.html

Scroll to Top