Page MenuHomePhabricator

Investigate ways to reduce app start time
Closed, ResolvedPublicSpike

Description

After iOS 10 app container changes our start-up time on a cold start increased dramatically. This is likely related to the work we did then undid from the summer w/r/t how we package frameworks.

On a 6S running iOS 10.1 beta 4 the app takes 10-15 seconds to start. There is some pretty strong published evidence that 5 seconds is the max start time before you begin to get users abandoning the app (http://ux.stackexchange.com/questions/34738/activity-response-startup-times, http://blog.nimbledroid.com/2016/02/17/cold-start-times-of-top-apps.html?top?=25&category=MUSIC_STREAMING)

This ticket is for a couple day spike to determine:

  • Can the start time be reduced?
  • If this is an OS issue, can we file a ticket with specific request for Apple? Would tech support be helpful?
  • If this is due to large number of imported frameworks, can we reduce our use of frameworks without regressing the feature set or user experience?
  • How long would any potential solutions take to investigate/implement?

See also this WWDC session on optimizing app start times: https://developer.apple.com/videos/play/wwdc2016/406/

Event Timeline

5.3.1:

Total pre-main time: 3.1 seconds (100.0%)
         dylib loading time: 2.2 seconds (71.7%)
        rebase/binding time: 106.55 milliseconds (3.4%)
            ObjC setup time: 301.93 milliseconds (9.6%)
           initializer time: 476.77 milliseconds (15.2%)
           slowest intializers :
             libSystem.B.dylib :  18.15 milliseconds (0.5%)
                      WMFModel : 388.83 milliseconds (12.4%)
               Wikipedia Debug : 167.18 milliseconds (5.3%)

Total pre-main time: 2.9 seconds (100.0%)
         dylib loading time: 2.2 seconds (76.4%)
        rebase/binding time: 107.67 milliseconds (3.6%)
            ObjC setup time: 309.62 milliseconds (10.4%)
           initializer time: 278.36 milliseconds (9.4%)
           slowest intializers :
             libSystem.B.dylib :  18.15 milliseconds (0.6%)
                      WMFModel : 136.44 milliseconds (4.6%)
               Wikipedia Debug : 116.95 milliseconds (3.9%)

Total pre-main time: 2.9 seconds (100.0%)
         dylib loading time: 2.2 seconds (75.8%)
        rebase/binding time:  95.42 milliseconds (3.1%)
            ObjC setup time: 312.12 milliseconds (10.4%)
           initializer time: 313.85 milliseconds (10.4%)
           slowest intializers :
             libSystem.B.dylib :  36.63 milliseconds (1.2%)
                      WMFModel : 136.75 milliseconds (4.5%)
               Wikipedia Debug : 117.59 milliseconds (3.9%)

5.3.3:

Total pre-main time: 2.5 seconds (100.0%)
         dylib loading time: 1.9 seconds (76.5%)
        rebase/binding time:  84.41 milliseconds (3.3%)
            ObjC setup time:  86.99 milliseconds (3.4%)
           initializer time: 417.80 milliseconds (16.5%)
           slowest intializers :
             libSystem.B.dylib :  19.35 milliseconds (0.7%)
                      WMFModel : 167.51 milliseconds (6.6%)
               Wikipedia Debug : 107.75 milliseconds (4.2%)

Total pre-main time: 2.4 seconds (100.0%)
         dylib loading time: 1.9 seconds (81.5%)
        rebase/binding time:  81.93 milliseconds (3.3%)
            ObjC setup time:  87.55 milliseconds (3.6%)
           initializer time: 276.25 milliseconds (11.4%)
           slowest intializers :
             libSystem.B.dylib :  20.45 milliseconds (0.8%)
                      WMFModel :  65.56 milliseconds (2.7%)
               Wikipedia Debug :  70.65 milliseconds (2.9%)
			   
Total pre-main time: 2.3 seconds (100.0%)
         dylib loading time: 1.9 seconds (81.5%)
        rebase/binding time:  81.48 milliseconds (3.4%)
            ObjC setup time:  85.70 milliseconds (3.5%)
           initializer time: 272.87 milliseconds (11.4%)
           slowest intializers :
             libSystem.B.dylib :  19.35 milliseconds (0.8%)
                      WMFModel :  68.44 milliseconds (2.8%)
               Wikipedia Debug :  67.07 milliseconds (2.8%)

5.3.3 with WMFUtilities, WMFModel, and WMFUI combined into one framework:

Total pre-main time: 2.3 seconds (100.0%)
         dylib loading time: 1.8 seconds (76.5%)
        rebase/binding time:  82.91 milliseconds (3.4%)
            ObjC setup time:  85.79 milliseconds (3.5%)
           initializer time: 392.84 milliseconds (16.3%)
           slowest intializers :
             libSystem.B.dylib :  23.26 milliseconds (0.9%)
                  AFNetworking :  48.33 milliseconds (2.0%)
                      WMFModel : 161.18 milliseconds (6.7%)
               Wikipedia Debug :  71.55 milliseconds (2.9%)

Total pre-main time: 2.3 seconds (100.0%)
         dylib loading time: 1.8 seconds (79.4%)
        rebase/binding time:  82.19 milliseconds (3.5%)
            ObjC setup time:  86.83 milliseconds (3.7%)
           initializer time: 310.81 milliseconds (13.2%)
           slowest intializers :
             libSystem.B.dylib :  20.65 milliseconds (0.8%)
                  AFNetworking :  48.43 milliseconds (2.0%)
                      WMFModel :  67.82 milliseconds (2.9%)
               Wikipedia Debug :  72.64 milliseconds (3.1%)
			   
Total pre-main time: 2.2 seconds (100.0%)
         dylib loading time: 1.8 seconds (79.4%)
        rebase/binding time:  81.77 milliseconds (3.5%)
            ObjC setup time:  82.16 milliseconds (3.5%)
           initializer time: 307.11 milliseconds (13.3%)
           slowest intializers :
             libSystem.B.dylib :  20.51 milliseconds (0.8%)
                  AFNetworking :  57.06 milliseconds (2.4%)
                      WMFModel :  68.45 milliseconds (2.9%)
               Wikipedia Debug :  74.11 milliseconds (3.2%)

Should be noted that these times are on an older iPad MD510LL/A running 10.2

5.3.3 with KVO controller removed:

Total pre-main time: 2.4 seconds (100.0%)
         dylib loading time: 1.8 seconds (75.7%)
        rebase/binding time:  79.79 milliseconds (3.2%)
            ObjC setup time:  89.05 milliseconds (3.5%)
           initializer time: 431.25 milliseconds (17.3%)
           slowest intializers :
             libSystem.B.dylib :  22.76 milliseconds (0.9%)
                      WMFModel : 206.08 milliseconds (8.3%)
               Wikipedia Debug :  70.31 milliseconds (2.8%)
			   		   
Total pre-main time: 2.3 seconds (100.0%)
         dylib loading time: 1.8 seconds (80.5%)
        rebase/binding time:  82.13 milliseconds (3.4%)
            ObjC setup time:  86.11 milliseconds (3.6%)
           initializer time: 289.92 milliseconds (12.3%)
           slowest intializers :
             libSystem.B.dylib :  23.13 milliseconds (0.9%)
                      WMFModel :  68.99 milliseconds (2.9%)
               Wikipedia Debug :  69.86 milliseconds (2.9%)
			   
Total pre-main time: 2.3 seconds (100.0%)
         dylib loading time: 1.8 seconds (80.1%)
        rebase/binding time:  84.49 milliseconds (3.5%)
            ObjC setup time:  82.48 milliseconds (3.5%)
           initializer time: 300.66 milliseconds (12.7%)
           slowest intializers :
             libSystem.B.dylib :  22.57 milliseconds (0.9%)
                      WMFModel :  78.40 milliseconds (3.3%)
               Wikipedia Debug :  69.44 milliseconds (2.9%)

Per our meeting, lets merge our libraries into a single framework and call this task complete.

Libraries are merged.

For future reference, it seems the best way to improve our app launch time is to limit the number of third party frameworks we have bundled with the app. On the iPad used for the times above, about 0.1 seconds gained per framework removed.

This talk has a lot of useful information:
https://developer.apple.com/videos/play/wwdc2016/406/

Re-ran with 5.4.1 (1124) on iOS 10.2, same iPad MD510LL/A:

Total pre-main time: 1.6 seconds (100.0%)
         dylib loading time: 1.3 seconds (81.5%)
        rebase/binding time:  77.43 milliseconds (4.6%)
            ObjC setup time:  63.12 milliseconds (3.7%)
           initializer time: 166.07 milliseconds (9.9%)
           slowest intializers :
             libSystem.B.dylib :  23.23 milliseconds (1.3%)
                  AFNetworking :  41.27 milliseconds (2.4%)
                     Wikipedia :  53.93 milliseconds (3.2%)

Total pre-main time: 1.6 seconds (100.0%)
         dylib loading time: 1.3 seconds (81.1%)
        rebase/binding time:  78.78 milliseconds (4.6%)
            ObjC setup time:  70.41 milliseconds (4.1%)
           initializer time: 167.22 milliseconds (9.9%)
           slowest intializers :
             libSystem.B.dylib :  23.05 milliseconds (1.3%)
                  AFNetworking :  42.80 milliseconds (2.5%)
                     Wikipedia :  55.00 milliseconds (3.2%)

Total pre-main time: 1.7 seconds (100.0%)
         dylib loading time: 1.3 seconds (79.7%)
        rebase/binding time:  77.49 milliseconds (4.5%)
            ObjC setup time:  65.91 milliseconds (3.8%)
           initializer time: 200.74 milliseconds (11.7%)
           slowest intializers :
             libSystem.B.dylib :  20.96 milliseconds (1.2%)
                  AFNetworking :  40.56 milliseconds (2.3%)
                     Wikipedia :  82.62 milliseconds (4.8%)

Launch time reduced by 45% compared to the initial test

iPhone 6S, 10.3.1, 5.4.1 (1124):

Total pre-main time: 648.08 milliseconds (100.0%)
         dylib loading time: 475.84 milliseconds (73.4%)
        rebase/binding time:  46.70 milliseconds (7.2%)
            ObjC setup time:  49.40 milliseconds (7.6%)
           initializer time:  75.99 milliseconds (11.7%)
           slowest intializers :
             libSystem.B.dylib :   8.88 milliseconds (1.3%)
   libBacktraceRecording.dylib :  14.35 milliseconds (2.2%)
                     Wikipedia :  22.65 milliseconds (3.4%)

Total pre-main time: 617.60 milliseconds (100.0%)
         dylib loading time: 456.87 milliseconds (73.9%)
        rebase/binding time:  62.12 milliseconds (10.0%)
            ObjC setup time:  27.31 milliseconds (4.4%)
           initializer time:  71.16 milliseconds (11.5%)
           slowest intializers :
             libSystem.B.dylib :   7.63 milliseconds (1.2%)
   libBacktraceRecording.dylib :  14.23 milliseconds (2.3%)
                  AFNetworking :  12.83 milliseconds (2.0%)
                     Wikipedia :  20.08 milliseconds (3.2%)

Total pre-main time: 607.22 milliseconds (100.0%)
         dylib loading time: 448.88 milliseconds (73.9%)
        rebase/binding time:  60.10 milliseconds (9.8%)
            ObjC setup time:  30.00 milliseconds (4.9%)
           initializer time:  68.10 milliseconds (11.2%)
           slowest intializers :
             libSystem.B.dylib :   7.47 milliseconds (1.2%)
   libBacktraceRecording.dylib :  14.33 milliseconds (2.3%)
                  AFNetworking :  12.38 milliseconds (2.0%)
                     Wikipedia :  18.42 milliseconds (3.0%)

iPhone 7+, 10.3.1, 5.4.1 (1124):

Total pre-main time: 382.99 milliseconds (100.0%)
         dylib loading time: 307.82 milliseconds (80.3%)
        rebase/binding time:  19.28 milliseconds (5.0%)
            ObjC setup time:  18.68 milliseconds (4.8%)
           initializer time:  37.13 milliseconds (9.6%)
           slowest intializers :
             libSystem.B.dylib :   4.17 milliseconds (1.0%)
                  AFNetworking :   7.69 milliseconds (2.0%)
                     Wikipedia :  12.17 milliseconds (3.1%)

Total pre-main time: 383.19 milliseconds (100.0%)
         dylib loading time: 308.27 milliseconds (80.4%)
        rebase/binding time:  18.41 milliseconds (4.8%)
            ObjC setup time:  18.69 milliseconds (4.8%)
           initializer time:  37.73 milliseconds (9.8%)
           slowest intializers :
             libSystem.B.dylib :   4.31 milliseconds (1.1%)
                  AFNetworking :   7.78 milliseconds (2.0%)
                     Wikipedia :  12.81 milliseconds (3.3%)

Total pre-main time: 385.42 milliseconds (100.0%)
         dylib loading time: 307.53 milliseconds (79.7%)
        rebase/binding time:  19.16 milliseconds (4.9%)
            ObjC setup time:  19.71 milliseconds (5.1%)
           initializer time:  38.93 milliseconds (10.1%)
           slowest intializers :
             libSystem.B.dylib :   4.89 milliseconds (1.2%)
                     Wikipedia :  12.94 milliseconds (3.3%)

iPhone SE, 10.3.1, 5.4.1 (1124):

Total pre-main time: 258.67 milliseconds (100.0%)
         dylib loading time: 193.69 milliseconds (74.8%)
        rebase/binding time:   8.71 milliseconds (3.3%)
            ObjC setup time:  18.73 milliseconds (7.2%)
           initializer time:  37.44 milliseconds (14.4%)
           slowest intializers :
             libSystem.B.dylib :   3.55 milliseconds (1.3%)
                  AFNetworking :   7.49 milliseconds (2.8%)
                     Wikipedia :  13.18 milliseconds (5.0%)

Total pre-main time: 258.66 milliseconds (100.0%)
         dylib loading time: 188.41 milliseconds (72.8%)
        rebase/binding time:  14.33 milliseconds (5.5%)
            ObjC setup time:  19.08 milliseconds (7.3%)
           initializer time:  36.74 milliseconds (14.2%)
           slowest intializers :
             libSystem.B.dylib :   3.52 milliseconds (1.3%)
                  AFNetworking :   7.97 milliseconds (3.0%)
                     Wikipedia :  12.00 milliseconds (4.6%)

Total pre-main time: 253.20 milliseconds (100.0%)
         dylib loading time: 184.49 milliseconds (72.8%)
        rebase/binding time:  13.29 milliseconds (5.2%)
            ObjC setup time:  19.06 milliseconds (7.5%)
           initializer time:  36.27 milliseconds (14.3%)
           slowest intializers :
             libSystem.B.dylib :   3.49 milliseconds (1.3%)
                  AFNetworking :   7.44 milliseconds (2.9%)
                     Wikipedia :  11.93 milliseconds (4.7%)

Checking in with numbers from iPhone 6S, 12.1.4, 6.2.1 (1590):

Total pre-main time: 438.79 milliseconds (100.0%)
         dylib loading time: 374.38 milliseconds (85.3%)
        rebase/binding time:  13.62 milliseconds (3.1%)
            ObjC setup time:  19.29 milliseconds (4.3%)
           initializer time:  31.37 milliseconds (7.1%)
           slowest intializers :
             libSystem.B.dylib :   4.14 milliseconds (0.9%)
                     Wikipedia :  20.33 milliseconds (4.6%)

Total pre-main time: 271.86 milliseconds (100.0%)
         dylib loading time: 199.40 milliseconds (73.3%)
        rebase/binding time:  17.63 milliseconds (6.4%)
            ObjC setup time:  21.23 milliseconds (7.8%)
           initializer time:  33.48 milliseconds (12.3%)
           slowest intializers :
             libSystem.B.dylib :   4.33 milliseconds (1.5%)
                     Wikipedia :  22.82 milliseconds (8.3%)

Total pre-main time: 419.73 milliseconds (100.0%)
         dylib loading time: 344.15 milliseconds (81.9%)
        rebase/binding time:  20.30 milliseconds (4.8%)
            ObjC setup time:  21.46 milliseconds (5.1%)
           initializer time:  33.68 milliseconds (8.0%)
           slowest intializers :
             libSystem.B.dylib :   4.39 milliseconds (1.0%)
                     Wikipedia :  22.18 milliseconds (5.2%)

Total pre-main time: 168.07 milliseconds (100.0%)
         dylib loading time: 105.39 milliseconds (62.7%)
        rebase/binding time:  10.65 milliseconds (6.3%)
            ObjC setup time:  17.85 milliseconds (10.6%)
           initializer time:  34.05 milliseconds (20.2%)
           slowest intializers :
             libSystem.B.dylib :   5.14 milliseconds (3.0%)
                     Wikipedia :  22.68 milliseconds (13.4%)

Total pre-main time: 350.84 milliseconds (100.0%)
         dylib loading time: 287.01 milliseconds (81.8%)
        rebase/binding time:  12.46 milliseconds (3.5%)
            ObjC setup time:  18.47 milliseconds (5.2%)
           initializer time:  32.78 milliseconds (9.3%)
           slowest intializers :
             libSystem.B.dylib :   4.59 milliseconds (1.3%)
                     Wikipedia :  21.80 milliseconds (6.2%)

Not sure of the reason for the variance - using DYLD_PRINT_STATISTICS target which sets the environment variable, is release build, debugger not attached.

Numbers from version 6.3.0 sha 6fff2cfef7e0871ecff5c1587b1ee3e9129ca3ff.
iPhone 7 iOS 12.3.1:

Logged in, small percentage of 1000 saved articles synced

Total pre-main time: 164.08 milliseconds (100.0%)
         dylib loading time: 101.47 milliseconds (61.8%)
         rebase/binding time:  12.45 milliseconds (7.5%)
         ObjC setup time:  26.26 milliseconds (16.0%)
         initializer time:  23.81 milliseconds (14.5%)
slowest intializers :
         libSystem.B.dylib :   3.23 milliseconds (1.9%)
         libViewDebuggerSupport.dylib :   5.18 milliseconds (3.1%)
         Wikipedia :  12.40 milliseconds (7.5%)

Not logged in

Total pre-main time: 166.63 milliseconds (100.0%)
         dylib loading time: 102.04 milliseconds (61.2%)
         rebase/binding time:  15.64 milliseconds (9.3%)
         ObjC setup time:  23.83 milliseconds (14.3%)
         initializer time:  25.03 milliseconds (15.0%)
slowest intializers :
         libSystem.B.dylib :   3.49 milliseconds (2.0%)
         libViewDebuggerSupport.dylib :   4.96 milliseconds (2.9%)
         Wikipedia :  13.25 milliseconds (7.9%)

After updating from 6.2.3, logged in with small percentage of 1000 saved articles synced

Total pre-main time: 190.08 milliseconds (100.0%)
         dylib loading time: 121.76 milliseconds (64.0%)
         rebase/binding time:  15.81 milliseconds (8.3%)
         ObjC setup time:  24.91 milliseconds (13.1%)
initializer time:  27.52 milliseconds (14.4%)
         slowest intializers :
         libSystem.B.dylib :   3.31 milliseconds (1.7%)
         libViewDebuggerSupport.dylib :   5.25 milliseconds (2.7%)
         Wikipedia :  15.32 milliseconds (8.0%)

Logged in, 1000 synced articles

Total pre-main time: 184.22 milliseconds (100.0%)
         dylib loading time: 116.55 milliseconds (63.2%)
         rebase/binding time:  16.56 milliseconds (8.9%)
         ObjC setup time:  25.36 milliseconds (13.7%)
         initializer time:  25.65 milliseconds (13.9%)
slowest intializers :
         libSystem.B.dylib :   3.37 milliseconds (1.8%)
         libViewDebuggerSupport.dylib :   5.51 milliseconds (2.9%)
         Wikipedia :  13.61 milliseconds (7.3%)
Restricted Application changed the subtype of this task from "Task" to "Spike". · View Herald TranscriptJul 1 2019, 3:52 PM