Mess am Start: Post-Mortem zur Startgeschwindigkeit einer iOS-Anwendung

Eine moderne Anwendung hat viele nicht-funktionale Anforderungen: Anwendungsgröße, verbrauchter Datenverkehr, Zugänglichkeit für Menschen mit Behinderungen, Stabilität, Startgeschwindigkeit und Betriebsgeschwindigkeit. Unsere Anwendung wurde sehr lange gestartet, einige zehn Sekunden. Heute wurde ein Update veröffentlicht, bei dem die iOS-Anwendung um ein Vielfaches schneller lief. Ich sage dir, wie es passiert ist und warum erst jetzt.



Es fängt schon lange an


Die Anwendung hat viel Code, viele Klassen und sie sind irgendwie miteinander verbunden. Um diese Beziehungen zu verwalten, verwendeten wir Dip (lesen Sie: Swinject oder ein anderes DI-Framework ohne Codegenerierung).

Das funktioniert so: Zu Beginn der Anwendung werden alle Abhängigkeiten in den "Container" gepackt, und dann wird die gewünschte Klasse daraus extrahiert, wobei alle Abhängigkeiten abgelegt werden. Es braucht Zeit, um zu starten, es braucht Zeit, um einen Bildschirm zu öffnen.

Aber die Bilder sind wunderschön


Lange Zeit hat es uns nicht einmal erschreckt: Wir haben nur schöne Bildschirmschoner mit neuer Pizza gezeichnet und nicht gedämpft. Die Pizza-Bildschirmschoner mussten entfernt werden, als wir in mehreren Ländern angefangen haben, da das Sortiment überall unterschiedlich ist. Das Bild ist nicht mehr so ​​interessant geworden, das Warten auf den Start ist langweiliger geworden, aber wir haben diesen Punkt verpasst.

Hier sind unsere Spritzer. Schön, aber versteckt ein Problem, das wir nicht einmal zu lösen versucht haben.



Nach der nächsten Veröffentlichung begannen wir, das Umdrehen der Karten im Page Controller zu verlangsamen. Der Zeitprofiler hat gezeigt, dass Abhängigkeiten für eine lange Zeit entfernt werden, wenn ein neuer Bildschirm angezeigt wird. Warum so? Es ist unmöglich zu verstehen. Das Debuggen von Dip ist aufgrund der gleichen abstrakten Aufrufe sehr schwierig. Wir haben versucht, einen gemeinsamen Container in viele kleine zu zerlegen, aber es wurde nur schlimmer. Infolgedessen haben wir die Spiegelkarten deaktiviert und die Neujahrsaktualisierungen fortgesetzt.

So sieht Dip im Profiler aus. Am Ende der Liste ist das Call-Stack-Limit erreicht. Es ist unmöglich, damit etwas Vernünftiges zu tun.



Fliegt zu 4S? Später reparieren


Zu diesem Zeitpunkt lag der Fehler „Release-Build auf 4S nicht gestartet“ im Rückstand, obwohl die Debug-Versionen gestartet wurden. Niemand bemerkte die Verbindung von Problemen, erhöhte die Mindestversion von iOS auf 10 und verschob auch die Änderungen. Es gibt nur wenige Benutzer auf 4S, richtig?

Wir haben Dip gesehen: nicht beim Start, sondern beim Kompilieren


Es wurde jedoch klar, dass Dip geschnitten werden musste. Und was soll man ändern? Sehr aktuell stießen wir auf den Artikel " Dependency Injection in Swift ".

Es funktioniert einfach: Wir schreiben eine Reihe von resolve() Funktionen mit einem anderen Typ (der Compiler wird es herausfinden). Die Kommunikation wird also zu Beginn nicht mehr berechnet, und der Compiler kann den Code sogar optimieren. Dies ist auch für die Entwicklung nützlich: Wenn Sie die Abhängigkeiten falsch beschrieben haben, erfahren Sie dies beim Start und nicht beim Öffnen des Bildschirms. Natürlich gibt es Probleme: Wenn die resolve() Funktion den Typ nicht versteht, wird bei einhundert Kandidaten ein so unnützer Fehler erzeugt:



Wir haben das schon im November gemacht. Es gab SEHR VIELE Änderungen, und in diesem Moment haben wir das neue Combo-Produkt auf den Markt gebracht und uns auf die neuesten Änderungen vor dem neuen Jahr vorbereitet. Der neue Code erschien im Projekt vor dem neuen Jahr, aber wir haben ihn erst im Januar veröffentlicht, da der Code vor den Feiertagen eingefroren war. Dafür haben wir das Programm drei Wochen lang im Testmodus verwendet, Probleme gefunden und behoben.

So sieht der Abhängigkeitscode jetzt aus. Dreckig aber arbeitend. 450 Plätze mit Registrierung und 1400 Plätze mit Extraktion.



Funktionell ist der Code derselbe, nur die Arbeitsweise unterscheidet sich. Der Geschwindigkeitsunterschied ist bei allen Modellen sichtbar. Auf XS - doppelt so schnell und auf SE sehen Sie selbst:


So haben wir nicht nur den Start beschleunigt, sondern auch das Öffnen der Bildschirme. Vor den Änderungen dauerte jeder Bildschirm nur je nach Abhängigkeit 0,3–1 Sekunden.

Neujahr ohne Pizza


Im Dezember begannen sie uns zu schreiben, dass die Anwendung beim Start abstürzt, nicht startet und nach dem Neustart eine Neuinstallation nicht hilft. Bisher gab es nur einen Grund dafür - Datenbankmigrationen, aber wir haben sie beseitigt und in Crashlytics keine neuen Abfahrten festgestellt. Was ist schief gelaufen?


Hypothese: Mit diesem iOS werden Anwendungen gelöscht, wenn sie über einen längeren Zeitraum ausgeführt werden. Die Version wurde durch die Tatsache bestätigt, dass alle Bewertungen von alten Geräten stammten: 5, 5S, 6. Die Anzahl solcher Bewertungen stieg signifikant an, da Pizza ein Feiertag ist, den die Leute oft für das neue Jahr bestellen. Das Team ist besorgt, das Produkt ist besorgt, aber wir rollen die neue Version erst im Januar.

Wir hatten Glück, dass die Lösung geschrieben wurde und nur getestet werden konnte. In einem anderen Szenario könnten Monate damit verbracht werden, nach Ursachen zu suchen und diese zu beheben.



Manchmal ist es schwierig, einem Unternehmen die Wichtigkeit einer technischen Aufgabe zu vermitteln: Es gibt keine Messdaten, die Wichtigkeit ist nicht klar, die Gefahr wird nicht vorhergesagt. Unternehmen können das Problem auf verschiedene Arten lösen: So haben wir schöne Bilder gemalt, anstatt die Anwendung zu beschleunigen. Die Leistung ist jedoch für jeden Benutzer wichtig. Es wirkt sich stark auf:

  • Warten. Wenn die Anwendung für eine lange Zeit gestartet wird, wie lange werden sie Pizza nehmen?
  • Das Vergnügen zu benutzen. Warum auf jedem Bildschirm dumm?
  • Und auch für die Stabilität. “Die Anwendung läuft nicht !!! Entwickler, testen Sie dort überhaupt? “(C).

Und umgehen Sie Dip, Swinject und andere Frameworks, die mit Containern in Echtzeit arbeiten, wenn Sie ein großes Projekt und viele Abhängigkeiten haben.
Um den nächsten Artikel nicht zu verpassen, abonnieren Sie den Dodo Pizza Mobile- Kanal .

Source: https://habr.com/ru/post/de485200/


All Articles