Search Unity

  1. Welcome to the Unity Forums! Please take the time to read our Code of Conduct to familiarize yourself with the forum rules and how to post constructively.
  2. Dismiss Notice

App startup time optimizations

Discussion in 'iOS and tvOS' started by Johannski, Nov 12, 2017.

  1. Johannski

    Johannski

    Joined:
    Jan 25, 2014
    Posts:
    815
    I've just played a bit of South Park -Phone Destroyer and I was really impressed by its startup time, especially when not loaded for the first time, but killed and then loaded again.
    I did a recording on my phone (which i restarted right before recording it):


    I'm wondering how they manage to show a screen so fast and also the first sounds loads with that screen (Sorry, I missed to include the sound).

    Is this achieveable with just a small first scene and the usage of asset bundles or are there other techniques they are using? By the way I checked the android version, it is Unity3D with Wwise.

    I'm noticing some really bad startup times (about 13 seconds) for the first start. Second start is between 3 and four seconds. I have a very small first scene, but within that I'm loading the other scenes synchronically (which I guess is part of the problem). I'm also preloading a shader bundle and didn't strip anything away. So I guess there is is space for performance. I'm still really curious what your techniques are or how you think redlynx/ubisoft pulled off those quick loading times.

    Cheers
    Johannes
     
  2. hippocoder

    hippocoder

    Digital Ape Moderator

    Joined:
    Apr 11, 2010
    Posts:
    29,723
    Yeah people have done this since earliest unity versions - you just load basically, the smallest scene in the world right at the start (normally), and this triggers async loads as soon as it is loaded - as it's showing, and so on.
     
  3. Johannski

    Johannski

    Joined:
    Jan 25, 2014
    Posts:
    815
    Hi Hippocoder,

    Thanks for your answer. I changed my setup to load scenes async and it brought me a 3-4 second speedup. I found the real problem of my loading time as well: Shader preloading. I preloaded every shader I recorded and loaded those on start. This really slowed down my appstart. Now that I have removed it my splash screen time is down to ~3.5 seconds for the first start and a little bit below one second for a normal start.
     
  4. hippocoder

    hippocoder

    Digital Ape Moderator

    Joined:
    Apr 11, 2010
    Posts:
    29,723
    Oh nice! thanks for sharing your findings as well.
     
  5. davitsedrakian

    davitsedrakian

    Joined:
    Jun 23, 2018
    Posts:
    30
    How do you preloaad and record shaders, can you help me ?
     
  6. Johannski

    Johannski

    Joined:
    Jan 25, 2014
    Posts:
    815
    You can record the used shaders in the Graphics Tab of the Project Settings. There you get a Shader Variant Collection by clicking on the "Save to asset" button. The Shader Variant Collection can then be used to warm it up (preload it): https://docs.unity3d.com/ScriptReference/ShaderVariantCollection.WarmUp.html.

    upload_2020-5-8_18-26-4.png

    You can start by first clearing the tracked shaders and then playing your game. This way you will not have old shaders in there :)

    ShaderVariantCollections are a cool thing, but Unity does not work so much on them. Might have problems or inconsistent behavior on some platforms. Always profile the results.
     
    protopop likes this.
  7. NileshKuril

    NileshKuril

    Joined:
    Jun 10, 2020
    Posts:
    4
    how can i add loading screen instead of black screen when shaders are preloading.
     
  8. Johannski

    Johannski

    Joined:
    Jan 25, 2014
    Posts:
    815
    By preloading them in your loading scene with a script, as mentioned before: https://docs.unity3d.com/ScriptReference/ShaderVariantCollection.WarmUp.html

    So my suggestion: Have a very small simple loading scene in which you show an image and progress bar, and there warm up the variant collection or, if you have problems with the variant collection, have a second camera rendering to a very small render texture which renders objects that have your shaders.
     
    NileshKuril likes this.
  9. NileshKuril

    NileshKuril

    Joined:
    Jun 10, 2020
    Posts:
    4
    Sir, thank you for your fast reply but am new in unity can you please tell me how to call or use ShaderVariantCollection.WarmUp this function using c#.
    i want to preload my all shaders in scene no.3
     
  10. Johannski

    Johannski

    Joined:
    Jan 25, 2014
    Posts:
    815
    Okay, I made you a very simple script:

    Code (CSharp):
    1. using UnityEngine;
    2.  
    3. public class ShaderVariantPreloader : MonoBehaviour
    4. {
    5.     [SerializeField] private ShaderVariantCollection target = null;
    6.  
    7.     [SerializeField] private bool warmupOnStart = true;
    8.  
    9.     private void Start()
    10.     {
    11.         if (warmupOnStart)
    12.         {
    13.             WarmupShaderVariantCollection();
    14.         }
    15.     }
    16.  
    17.     private void WarmupShaderVariantCollection()
    18.     {
    19.         target.WarmUp();
    20.     }
    21. }
    22.  
    Just add a gameobject to your loading scene with that script attached. To generate the shader variant collection (that needs to be set in the Target field), take a look at my previous post. This will stall the complete render thread, so you won't be able to refresh the screen at that point. If you want more flexibility, you will need to split the collections or work with a second hidden camera, but that's a lot of extra work to set it up.

    upload_2020-9-10_18-14-56.png
     
    won-gyu, Elapotp and NileshKuril like this.
  11. NileshKuril

    NileshKuril

    Joined:
    Jun 10, 2020
    Posts:
    4
    I really appreciate it. thank you sir
     
  12. won-gyu

    won-gyu

    Joined:
    Mar 23, 2018
    Posts:
    24
    What do you mean by "I have removed it"?
    Does it mean you removed all "Always Included Shaders"?
    Thanks anyway for sharing your experience!!
     
  13. Johannski

    Johannski

    Joined:
    Jan 25, 2014
    Posts:
    815
    Ah, no there is a difference with Always included shaders and the setting Preloaded Shaders. My problem was that I had a big ShaderVariant Collection set in Preloaded Shaders, that's the one I removed.
    upload_2023-3-9_20-22-10.png

    Of course it makes sense to also trim the list of Always included shaders to not include any shaders that you don't need, but I think this list does no shader warmup, but just makes sure that those shaders are not stripped out of your build (even if the build can't find any references to them, e.g. because you reference the shaders through Shaders.Find().

    As mentioned we still went ahead and preloaded the shader variant collection, but in a controlled way at normal runtime, where we can decide what happens simultaneously.
     
    won-gyu likes this.