Search Unity

AssetBundles webGL slow post-download initialize

Discussion in 'Asset Bundles' started by AlexHell, Nov 29, 2017.

  1. AlexHell

    AlexHell

    Joined:
    Oct 2, 2014
    Posts:
    167
    Hello! My project in Unity 5.6.3p2 (64-bit) (bundles builded, and project too). WebGL.

    I have 300 ABs, every of 103kb in compressed size, LZ4.
    604kb is incompressed size, but for this test mostly unusable.
    Every AB contains single binary file.

    I download 300 ABs from my server by code like this
    Code (CSharp):
    1. private const int AssetBundlesCount = 300;
    2. private long _loadAllAssetBundlesTimeStart;
    3. private int _assetBundlesLoadedCount;
    4. readonly AssetBundle[] _loadedAssetBundles = new AssetBundle[AssetBundlesCount];
    5.  
    6. public void LoadAllAssetBundles()
    7. {
    8.     LoadAllABsButton.gameObject.SetActive(false);
    9.     TextTiming.text = "loading..";
    10.     _loadAllAssetBundlesTimeStart = DateTime.Now.Ticks;
    11.     _assetBundlesLoadedCount = 0;
    12.     for (int i = 0; i < AssetBundlesCount; i++)
    13.     {
    14.         string numStr = (i + 1).ToString();
    15.         StartCoroutine(
    16.             LoadAssetBundle(
    17.                 GetAssetBundlesUrlByPlatform() + "/ab" + numStr,
    18.                 5,
    19.                 i)
    20.         );
    21.     }
    22. }
    23.  
    24. private static string GetAssetBundlesUrlByPlatform()
    25. {
    26.     return "MY SERVER";
    27. }
    28.  
    29. private IEnumerator LoadAssetBundle(string downloadPath, uint version, int index)
    30. {
    31.     while (!Caching.ready) yield return null;
    32.  
    33.     const uint crc = 0; // not used
    34.     using (UnityWebRequest www = UnityWebRequest.GetAssetBundle(downloadPath, version, crc))
    35.     {
    36.         yield return www.Send();
    37.  
    38.         if (www.isError)
    39.         {
    40.             Debug.LogError("AB load error: " + www.error);
    41.         }
    42.         else
    43.         {
    44.             AssetBundle bundle = DownloadHandlerAssetBundle.GetContent(www);
    45.             _loadedAssetBundles[index] = bundle;
    46.             if (bundle == null) Debug.LogError("bundle == null");
    47.  
    48.             _assetBundlesLoadedCount++;
    49.             //Debug.Log("AB loaded count = " + _assetBundlesLoadedCount);
    50.             if (_assetBundlesLoadedCount == AssetBundlesCount)
    51.             {
    52.                 TextTiming.text = "timing1: " + new TimeSpan(DateTime.Now.Ticks - _loadAllAssetBundlesTimeStart).TotalMilliseconds;
    53.                 Debug.Log("ALL ABs LOADED");
    54.                 LoadConcreteButton.gameObject.SetActive(true);
    55.             }
    56.         }
    57.     }
    58. }
    * LoadConcreteButton and some variables (AssetsCountForConcreteLoad, _loadedAssetBundles) is for NOT-INCLUDED-IN-THIS-TEST LoadAsset from loaded ABs. This test is only for measuring UnityWebRequest.GetAssetBundle and DownloadHandlerAssetBundle.

    When I press my 1st button, which invoke LoadAllAssetBundles(), I monitor to Firefox and Chrome Network tab, I see what:
    -- All 300 ABs are downloaded in 25-27 sec (iftop on webserver is confirms this)
    -- Text TextTiming.text = "timing1: " .. is updated later
    * after another 3-20 sec in chrome (for example 25 sec for download and 20 sec for magic stall)
    * everytime in Firefox = after 60-100 sec

    Some screenshots:
    chrome 25 sec download, and 25 sec final measured - https://prnt.sc/hgu9f0
    chrome 25 sec download, and 30 sec final measured - https://prnt.sc/hgu8pb
    chrome 24 sec download, and 43 sec final measured - https://prnt.sc/hgu9xq
    firefox 23 sec download, and 188 sec final measured - https://prnt.sc/hgu93b

    Tested on browsers:
    -- chrome portable 62.0.3202.75
    -- firefox 57.0 latest

    Tested on webservers for files:
    -- Apache/2.4.29 (codeit) OpenSSL/1.1.0g: on http 1.1, https 1.1, https 2.0
    -- nginx 1.13.7: on http 1.1, https 1.1, https 2.0

    What is the work, on which a browser is stalled? I have monitored win 7 disk performance, and not see many reads/writes on disks. ABs is LZ4 compressed and after download, a browser don't decompress it.

    **
    also, why https 2.0 is mostly (80% tests) slower than https 1.1? Is it due to browser incorrect implementations or web-server implementations, or UnityWebRequest?
     
    Last edited: Nov 29, 2017
  2. Aurimas-Cernius

    Aurimas-Cernius

    Unity Technologies

    Joined:
    Jul 31, 2013
    Posts:
    3,732
    I'm not an expert in all of this, but WebGL is single-threaded, it can be that AB is downloaded first and load happens at the point where you try to get it out of DonwloadHandler. You can confirm that by using DownloadHandler buffer and manual AssetBundle load from memory, the performance should be around the same on WebGL.
    On other platforms AssetBundle load is happening on other thread and UnityWebRequest feeds the downloaded bits of data immediately, the load happens on the fly.
     
  3. AlexHell

    AlexHell

    Joined:
    Oct 2, 2014
    Posts:
    167
    I have re-test this: it freeze due to developer console in browser when webgl block not in focus, and after click in center of screen - all resources finish downloading; and this "bug" doesn't exist when console is closed