Search Unity

  1. Curious about what's going to be in 2021.1? Have a look at the 2021.1 beta blog post.
    Dismiss Notice

Bug Uncaught ReferenceError: unityFramework is not defined at HTMLScriptElement.script.onload (WebGL)

Discussion in '2020.1 Beta' started by hippocoder, Jan 5, 2020.

  1. jukka_j


    Unity Technologies

    May 4, 2018
    Starting from Unity 2020.1, Unity WebGL projects no longer enable the Software Decompression Fallback of gzip and brotli by default. The software decompression fallback was added there because a lot of web servers are misconfigured and they do not properly advertise compressed content to the browser clients.

    When a web server properly declares compressed content to the browser, the browser can decompress the content already while it downloads the file (streamed decompression). This effectively means that decompression comes "for free" since download times generally dominate on the web.

    In the absence of properly declared compression, the software decompression fallback would manually run a decompressor after all the content has already been received by the browser. This is much slower than the pipelined approach that the browser is able to do, and a disservice of sorts to users, who would not be able to observe that they are not getting the best performance out of their Unity WebGL build startup times.

    To fix the issue, the primary approach is to usher people to set up proper web hosting configuration. If this is not possible (e.g. cannot access the web server configuration since you are not the web admin), the software compression fallback still exists in Unity in 2020.1, but now just needs to be enabled manually.

    Here is the server configuration block I would recommend to be used for nginx. It enables Brotli and gzip pre-compressed file compression support, WebAssembly streaming, and on-demand gzip compression if Unity builds did not have compression enabled when the project was built.

    Code (JavaScript):
    1.         # Enable on-the-fly gzip compression of uncompressed files
    2.         # See
    3.         # See also
    4.         #
    5.         # For a more advanced installation, one can try brotli-compressing the files on demand.
    6.         # See
    7.         #
    8.         # Brotli is not enabled by default here however, because the support is not included in
    9.         # nginx by default but one must install Brotli support from source. Replace the gzip
    10.         # directives with their commented out Brotli counterparts if you would like to enable on-demand
    11.         # Brotli compression. (remember to add "load_module modules/;"
    12.         # directive to top level of nginx.conf)
    13.         gzip on;
    14.         #brotli on;
    16.         # N.b. there also exists a feature "gzip_static" in nginx,
    17.         #,
    18.         # however that feature can be ignored, as Unity generates precompressed content
    19.         # from WebGL Build Settings menu out of the box.
    21.         # Unfortunately nginx does not support caching compressed files to avoid
    22.         # needing to recompress each time, so use a low compression level to keep
    23.         # things fast. (this is already the default, but shown here for posterity)
    24.         gzip_comp_level 1;
    25.         # brotli_comp_level 0; # (defaults to 6)
    27.         # Send the HTTP Response header "Vary: Accept-Encoding" as part of compressed
    28.         # requests. If an intermediate caching web proxy is used in-between, this
    29.         # will enable the proxy to properly cache compressed vs noncompressed files.
    30.         gzip_vary on;
    32.         # The following file types should be compressed on demand (.html, .js, .data, .wasm and .symbols.json).
    33.         # To ensure that .data files and .symbols.json files are compressed on demand,
    34.         # we define a custom MIME type application/octet-stream-compressible (not a registered IANA type)
    35.         # that we associate with these file suffixes so that they will be compressed on demand.
    36.         # This way we will be careful not to sloppily enable compression for *all* application/octet-stream
    37.         # files on the whole server, which might be undesirable for performance.
    38.         gzip_types application/wasm application/javascript application/octet-stream-compressible;
    39.         # brotli_types application/wasm application/javascript application/octet-stream-compressible;
    41.         # Nginx has two limitations to keep in mind:
    42.         # 1. While the file mime.types can be used to configure MIME types for file suffixes, that file
    43.         #    does not support describing files that have multiple suffixes (e.g. .symbols.json or .data.gz)
    44.         #    Therefore we use the location directives here to configure the MIME types for all file suffixes.
    45.         # 2. For each request, only one location specifier is used to match and serve a file. Therefore
    46.         #    the following code has a little bit of repetition in order to cover each unique suffix.
    48.         # Our custom octet-stream-compressible MIME type for data files that compress well.
    49.         location ~ .+\.(data|symbols\.json)$ {
    50.             default_type application/octet-stream-compressible;
    51.         }
    53.         # Register default MIME type for .wasm files (this could also be done in mime.types but since
    54.         # we need to define MIME types for files that have multiple suffixes, do it all here to be
    55.         # coherent)
    56.         # Alternatively you can add a line
    57.         #    application/wasm                                 wasm;
    58.         # to mime.types
    59.         location ~ .+\.wasm$ {
    60.             # Enable streaming WebAssembly compilation by specifying the correct MIME type for
    61.             # Wasm files.
    62.             default_type application/wasm;
    63.         }
    65.         # On-disk Brotli-precompressed data files should be served with compression enabled:
    66.         location ~ .+\.(data|symbols\.json)\.br$ {
    67.             # Because this file is already pre-compressed on disk, disable the on-demand compression on it.
    68.             # Otherwise nginx would attempt double compression.
    69.             gzip off;
    70.             #brotli off;
    71.             add_header Content-Encoding br;
    72.             # No special MIME type need to be declared here (can add application/octet-stream
    73.             # for .data and application/json for .symbols/json if one desires, but that does
    74.             # not get used for anything, so keep the configuration simple by omitting them)
    75.         }
    77.         # On-disk Brotli-precompressed JavaScript code files:
    78.         location ~ .+\.js\.br$ {
    79.             gzip off; # Do not attempt dynamic gzip compression on an already compressed file
    80.             #brotli off;
    81.             add_header Content-Encoding br;
    82.             default_type application/javascript;
    83.         }
    85.         # On-disk Brotli-precompressed WebAssembly files:
    86.         location ~ .+\.wasm\.br$ {
    87.             gzip off; # Do not attempt dynamic gzip compression on an already compressed file
    88.             #brotli off;
    89.             add_header Content-Encoding br;
    90.             # Enable streaming WebAssembly compilation by specifying the correct MIME type for
    91.             # Wasm files.
    92.             default_type application/wasm;
    93.         }
    95.         # On-disk gzip-precompressed data files should be served with compression enabled:
    96.         location ~ .+\.(data|symbols\.json)\.gz$ {
    97.             gzip off; # Do not attempt dynamic gzip compression on an already compressed file
    98.             #brotli off;
    99.             add_header Content-Encoding gzip;
    100.         }
    102.         # On-disk gzip-precompressed JavaScript code files:
    103.         location ~ .+\.js\.gz$ {
    104.             gzip off; # Do not attempt dynamic gzip compression on an already compressed file
    105.             #brotli off;
    106.             add_header Content-Encoding gzip;
    107.             default_type application/javascript;
    108.         }
    110.         # On-disk gzip-precompressed WebAssembly files:
    111.         location ~ .+\.wasm\.gz$ {
    112.             gzip off; # Do not attempt dynamic gzip compression on an already compressed file
    113.             #brotli off;
    114.             add_header Content-Encoding gzip;
    115.             # Enable streaming WebAssembly compilation by specifying the correct MIME type for
    116.             # Wasm files.
    117.             default_type application/wasm;
    118.         }
    Reading the above comments, there are some nginx configuration files that use

    Code (CSharp):
    1. add_header Content-Type application/javascript;
    directive to set up a MIME type. That unfortunately does not set a MIME type, but just appends a new header. The result will be that nginx will actually send two instances of the Content-Type header in the HTTP responses. Instead check out the "default_type" directive to set the header instead of appending, to avoid this duplication.
  2. UltimateGamer84


    Dec 9, 2017
    Thank you so much! It took me ages to try to debug this thing, all solutions I found said to disable compression, which is not a real solution in my case.
  3. adambielecki


    Mar 28, 2014
    It does not seems to be working on any 2020 version I tried so far with compression enabled.
    I sometimes wondering if there are any regression tests in the place as recently updating project to later version of unity is extremely dangerous task, it's ok if you are using unity for hobby, but not acceptable in professional environment.
    Dirrogate likes this.
  4. PaulRdy


    Jun 26, 2015
  5. Triplefun-Damian


    Jun 16, 2020
    For anyone having issues with this, you can also select "Decompression Fallback" in your Publishing Settings, rather than building a Development Build or disabling compression altogether.

    That said, the optimal solution is to fix your headers on the server side so that each file has the proper Content-Type and Content-Encoding - once set, your browser will handle the rest:

    "Decompression Fallback" is useful, though, if you're testing locally (for example, I use it while running live-server in VSC). It basically pushes the decompression to pure js

    I'm on 2020.1.8f1 for what it's worth
  6. Zaimatsu


    Mar 9, 2013
  7. mr-andersons


    Oct 16, 2020
    This Decompression Fallback seems to have fixed this for me. Am I losing any compression when using this?
  8. Triplefun-Damian


    Jun 16, 2020
    No, you're just off-loading the decompression to the client-side once the download has completed, which will make the start up slower (and your final payload a bit heavier as it now has a bunch of JS decompression code)

    When you get the correct headings set on the server, the decompression is done for "free" by the browser itself as it's downloading.
    Dirrogate likes this.
  9. Master_Eisa


    Jun 4, 2020
    Hello everybody,

    I have set all metadata regarding content type and content encoding as described. Unfortunately it doesn't work for me. Decompressing data and wasm file seem to work but. Build.framework.js.(Gz) or (br) I've tried both compressions. I still get the following error.
    Code (JavaScript):
    1. Uncaught ReferenceError: unityFramework is not defined
    I am currently providing my game uncompressed. It would be really nice if that would work, because I already deploy the game without texture compression, as it is currently not supported by unity on mobile devices.
    What am I doing wrong? or is it still an existing bug?

    Best regards Björn
  10. mmuller


    Nov 23, 2010
    Just to add 2021.1.0b1725 with GZIP compression returns:

    Code (javscript):
    1. abort("both async and sync fetching of the wasm failed") at jsStackTrace@
    Using this .htaccess file:

    Code (htaccess):
    2. # This configuration file should be uploaded to the server as "<Application Folder>/Build/.htaccess"
    3. # This configuration has been tested with Unity 2020.1 builds, hosted on Apache/2.4
    4. # NOTE: "mod_mime" Apache module must be enabled for this configuration to work.
    5. <IfModule mod_mime.c>
    7. # The following lines are required for builds without decompression fallback, compressed with gzip
    8. RemoveType .gz
    9. AddEncoding gzip .gz
    10. AddType application/octet-stream .data.gz
    11. AddType application/wasm .wasm.gz
    12. AddType application/javascript .js.gz
    13. AddType application/octet-stream .symbols.json.gz
    15. # The following lines are required for builds without decompression fallback, compressed with Brotli
    16. RemoveType .br
    17. RemoveLanguage .br
    18. AddEncoding br .br
    19. AddType application/octet-stream
    20. AddType application/wasm
    21. AddType application/javascript
    22. AddType application/octet-stream
    24. # The following line improves loading performance for uncompressed builds
    25. AddType application/wasm .wasm
    27. # Uncomment the following line to improve loading performance for gzip-compressed builds with decompression fallback
    28. # AddEncoding gzip .unityweb
    30. # Uncomment the following line to improve loading performance for brotli-compressed builds with decompression fallback
    31. # AddEncoding br .unityweb
  11. zezba9000


    Sep 28, 2010
    Same issue on Unity 2020.2.2
    Have to turn off gzip compression or enabled fallback
    Last edited: Jan 23, 2021
    AngryMuppet likes this.
  12. Munkey


    Oct 26, 2013
    What do you mean? Turn off gzip compression where? where is enable fallback?
  13. zezba9000


    Sep 28, 2010
  14. Munkey


    Oct 26, 2013
  15. ronshalev3d


    Apr 30, 2019
  16. zezba9000


    Sep 28, 2010
    No release build works fine
  17. wechat_os_Qy0zi83TzMbgvXiL3uYvsdqhQ


    Feb 5, 2021
    This issue still exist in 2020.2.3f1
  18. epicoro


    Jun 11, 2013
    It is not a bug! Your server configuration is wrong. Follow this example. Make sure you refresh the page with Shift+F5. This should resolve your issuess and you can use compression as usual.
    Last edited: Feb 8, 2021
  19. grimunk


    Oct 3, 2014
    If you use S3/cloudflare you can gzip your .unityweb files but omit the extension. You can add metadata to them on S3 to bind the content-encoding: gzip header. It's a bit less work going this route than running/maintaining your own server, probably cheaper too.
  20. Bshsf_9527


    Sep 6, 2017
    Try to change those files which endwith ".br.gz" 's MIME Type to "application/octet-stream".
    for example
    commond "AddType application/javascript .js.gz" should be "AddType application/octet-stream .js.gz"
    and so on.

    because I think .js.gz is a binary file rather than a js file.

    I test and found .wasm.gz file still use application/wasm but not application/octet-stream

    After update web configuration ,you need clear the webbrowser caching ,then you can run webgl application.
    Last edited: Feb 27, 2021
  21. Bshsf_9527


    Sep 6, 2017
    I use unity 2020.2.6 and IIS webserver and with gzip compression, I also face this issue even I use the "web.config" in this example , and I find out that those web configuration maybe have some mistake ,because when I change ".js.gz" 's MIME Type From "application/javascript" to "application/octet-stream" and clear webbrowser caching and run webgl application again, it worked correctly without stunking any more.
    As I am not a Server backend developer, I cannot tall the diffrent why this worked and donot know wheth if any other mistake in the web configuration that your team have had supported .
    At least, I think ,maybe files endwith "" is also belong to "octet-stream" MIME Type.
    Last edited: Feb 27, 2021