Compressed WebGL on IIS / Azure

Took me a while to find this thread: SOLVED: IIS - configuring it to serve out the new WebGL stack files - how? - Unity Engine - Unity Discussions. The original poster, TwoBob, has figured out how to upload a WebGL build to IIS. The solution needs just slight tweaking: renaming Data to Release and is now compatible with 5.2 and later. If you’re hosting a website (i.e. “WebApp”) on Microsoft Azure, simply upload this file named web.config to your /site/wwwroot/:

<?xml version="1.0" encoding="UTF-8"?>
<configuration>
  <system.webServer>
  <rewrite>
  <rules>
  <rule name="Rewrite .JS" enabled="true" stopProcessing="true">
  <match url="(.*)Release(.*)\.js" ignoreCase="true" />
  <conditions logicalGrouping="MatchAll">
  <add input="{HTTP_ACCEPT_ENCODING}" pattern="gzip" ignoreCase="true" />
  </conditions>
  <action type="Rewrite" url="{R:1}Compressed{R:2}.jsgz" />
  </rule>
  <rule name="Rewrite .Data" enabled="true" stopProcessing="true">
  <match url="(.*)Release(.*)\.data" ignoreCase="true" />
  <action type="Rewrite" url="{R:1}Compressed{R:2}.datagz" />
  <conditions>
  </conditions>
  </rule>
  <rule name="Rewrite .Mem" enabled="true" stopProcessing="true">
  <match url="(.*)Release(.*)\.mem" ignoreCase="true" />
  <action type="Rewrite" url="{R:1}Compressed{R:2}.memgz" />
  <conditions>
  </conditions>
  </rule>
  <rule name="Rewrite .Unity3d" enabled="true" stopProcessing="true">
  <match url="(.*)Release(.*)\.unity3d" ignoreCase="true" />
  <action type="Rewrite" url="{R:1}Compressed{R:2}.unity3dgz" />
  <conditions>
  </conditions>
  </rule>
  </rules>
  <outboundRules>
  <!-- FIRST SETUP THE SWITCHES FOR THE RESPONSE ENCODING //-->
  <rule name="Rewrite JSGZ header" preCondition="IsJSGZ" stopProcessing="false">
  <match serverVariable="RESPONSE_Content_Encoding" pattern=".*" />
  <action type="Rewrite" value="gzip" />
  </rule>
  <rule name="Rewrite MemGZ header" preCondition="IsMemGZ" stopProcessing="false">
  <match serverVariable="RESPONSE_Content_Encoding" pattern=".*" />
  <action type="Rewrite" value="gzip" />
  </rule>
  <rule name="Rewrite DataGZ header" preCondition="IsDataGZ" stopProcessing="false">
  <match serverVariable="RESPONSE_Content_Encoding" pattern=".*" />
  <action type="Rewrite" value="gzip" />
  </rule>
  <rule name="Rewrite Unity3DGZ header" preCondition="IsUnity3DGZ" stopProcessing="true">
  <match serverVariable="RESPONSE_Content_Encoding" pattern=".*" />
  <action type="Rewrite" value="gzip" />
  </rule>
  <!-- AND SETUP THE MATCHES FOR THE RESPONSE ENCODING SWITCHES //-->
  <preConditions>
  <preCondition name="IsJSGZ">
  <add input="{PATH_INFO}" pattern="\.jsgz$" />
  </preCondition>
  <preCondition name="IsMemGZ">
  <add input="{PATH_INFO}" pattern="\.memgz$" />
  </preCondition>
  <preCondition name="IsDataGZ">
  <add input="{PATH_INFO}" pattern="\.datagz$" />
  </preCondition>
  <preCondition name="IsUnity3DGZ">
  <add input="{PATH_INFO}" pattern="\.unity3dgz$" />
  </preCondition>
  </preConditions>
  </outboundRules>
  </rewrite>
  <staticContent>
  <mimeMap fileExtension=".mem" mimeType="application/octet-stream" />
  <mimeMap fileExtension=".data" mimeType="application/octet-stream" />
  <mimeMap fileExtension=".memgz" mimeType="application/octet-stream" />
  <mimeMap fileExtension=".datagz" mimeType="application/octet-stream" />
  <mimeMap fileExtension=".unity3dgz" mimeType="application/octet-stream" />
  <mimeMap fileExtension=".jsgz" mimeType="application/x-javascript; charset=UTF-8" />
  </staticContent>
  <urlCompression doStaticCompression="true" doDynamicCompression="false" />
  </system.webServer>
</configuration>

It would be great if Unity generated this file for us!

2 Likes

I don’t think we can maintain configuration files for all the different Web Servers there are. Instead, in Unity 5.3, we will fall back to decompressing files in JavaScript if the server is not set up correctly, so you will only experience a very minor delay for not having transfers compressed on the http protocol level.

1 Like

That seems like a really good idea. You could also potentially compress even better, using format-specific compression for each asset if you’re writing your own client-side decompression algorithms. Looking forward to 5.3!

@jonas-echterhoff_1 when do we expect version 5.3?

December 8th:

Pro license holders can also download the current beta today at:

Thanks man! This is what I needed! :slight_smile:

This very nearly worked for me. I’m using Unity 5.4b14 and had to modify the rules to remove the “Compressed” string and also had to create an exception to the Rewrite JS rule for UnityLoader.js.

Hi. Tried the original method and it didn work. Can you please share the modified web.config file. Thanks in advance

Well i have tried this solution and it works on Chrome.
@sathya You need to create a folder named “Compressed” and put the compressed data files from you’re Release folder in there. But for it only works in Chrome. Not in Firefox.

So i’m realy curious how @Chronovore did it.
I did renamed “Compressed” to “Release” and altered the Regex : “(.)Release(.).js” to
“(?!(.)Release(.)UnityLoader.js)(.)Release(.).js”. That should compress every js file except the UnityLoader.js. But that did not work for me.
@ I hope you can help us out here. Because it is difficult to setup. And i think there are a lot of people using Azure because it is free for startups.

Hello mmwizard.

You do not have to configure your server in any special way if you are using Unity 5.3 or above. Under default server configuration the Unity loader should fallback to JavaScript decompression and download the original build files from the Release folder directly. First try to make sure that the default configuration works well for you.

Optionally, you can also configure your server to serve the content of the build.jsgz, build.memgz and build.datagz files on the build.js, build.mem and build.data requests respectively, with the Content-Encoding: gzip response header set. This way the decompression will be performed by the browser, so the initial loading delay will be reduced a bit, still this is an option, not a requirement.

You can also provide the link to your content so that it would be possible to check on your server response and figure out what exactly is going wrong.

I am using azure. ( the app has only 1 button and nothing else)

Using the java script decompression it took 25 seconds to decompress, and as an added bonus the app looks like it’s doing nothing while this is happening - ie the page sits there like nothing is happening - which would make most users assume it’s broken/ didn’t work - which is what I thought until I hit F12 and saw it decompressing. I had other people test it and it took over a minute.

“Optionally, you can also configure your server to serve the content of the build.jsgz, build.memgz and build.datagz files on the build.js, build.mem and build.data requests respectively, with the Content-Encoding: gzip response header set.”

  • I have no idea how to do this ?

I’m using this Web.config

<system.webServer>














</system.webServer>

This is the address
http://aweswan.azurewebsites.net/
(I might break this as I test it)

Hello McSwan.

The Network profiler displays the download time of 25 sec and not the decompression time. The decompression time is explicitly displayed in the console in the following way: Decompressed Release/WebGLTest2.jsgz in 243ms. You can remove this delay if you configure your web server to host files using gzip compression. This means that if you configure your server to serve the content that can be decompressed by the browser, you will save just about 0.24 sec, which means that the decompression overhead in most cases is insignificant.

Still you may want to configure your server, as this should also make the loading progress bar update correctly, so the user will be able to see that the game is loading.

Upload a fresh release build to your IIS server without making any additional changes in the build files or in the server configuration on the levels which are parent to the build. Then add the following web.config file to the Release subfolder:

<?xml version="1.0" encoding="UTF-8"?>
<configuration>
    <system.webServer>
        <staticContent>
            <mimeMap fileExtension=".jsgz" mimeType="application/octet-stream" />
            <mimeMap fileExtension=".memgz" mimeType="application/octet-stream" />
            <mimeMap fileExtension=".datagz" mimeType="application/octet-stream" />
            <mimeMap fileExtension=".unity3dgz" mimeType="application/octet-stream" />
        </staticContent>
        <rewrite>
            <rules>
                <rule name="Append gz suffix to WebGL content requests">
                    <match url="(.*)\.(js|data|mem|unity3d)$" />
                    <conditions>
                        <add input="{HTTP_ACCEPT_ENCODING}" pattern="gzip" />
                        <add input="{REQUEST_FILENAME}" matchType="IsFile" negate="true" />
                    </conditions>
                    <action type="Rewrite" url="{R:1}.{R:2}gz" />
                </rule>
            </rules>
            <outboundRules>
                <rule name="Append gzip Content-Encoding header to rewritten responses">
                    <match serverVariable="RESPONSE_Content-Encoding" pattern=".*" />
                    <conditions>
                        <add input="{REQUEST_FILENAME}" pattern="\.(js|data|mem|unity3d)gz$" />
                    </conditions>
                    <action type="Rewrite" value="gzip" />
                </rule>
            </outboundRules>
        </rewrite>
    </system.webServer>
</configuration>

Note: when copying the configuration from the snippet above, make sure the web.config file starts immediately with <?xml without any preceding characters or newlines. You can also setup the same configuration using IIS Manager, by adding MIME types, and URL Rewrite inbound and outbound rules for your Release subfolder.

Let me know if this works for you.

1 Like

Hello alexsuvorov,

Aweswan work alexsuvorov! - That works much better - the loading bar comes up when it is downloading.

I have an example here:
http://aweswan.azurewebsites.net/test/

In chrome, I had some errors but they don’t seem to cause any issues? Didn’t get any errors in Firefox.

You can safely ignore those warnings, they should not affect the game functionality. They have been already taken care of and will non be displayed in the future releases.

HI Alex,

I am battling to setup my IIS on my web server (Windows Server 2012).

If I remove the web.config, (but I add the MIME types in IIS Manager, I get the following error)

UnityLoader.js:1 Invoking error handler due to
Uncaught SyntaxError: Invalid or unexpected token
blob:http://23.96.38.122/f7854598-5523-4bd2-9d81-0cff8551f5cc:1 Uncaught SyntaxError: Invalid or unexpected token

Please help, this is really frustrating…
I am using Unity 5.4.1

Hello Meltdown.

This one is easy. Your build does not load, because you modified the html file (manually adding “gz” to the links). Just use the originally generated build files and it should work well.

The mentioned web.config might not work for you if you don’t have URL Rewrite module installed (http://www.iis.net/downloads/microsoft/url-rewrite), in which case the server will return error 500 for any files inside the Release subfolder. Please check the following post for the updated guide https://forum.unity3d.com/threads/why-was-htaccess-removed-in-5-4.424025/#post-2744442

Thanks Alex, I had tried that before, but it seems the error in the browser telling me the .mem file could not be found threw me off.

It also turns out I wasn’t patient enough, because the Azure VM I am hosting the files on, were only being downloaded at a paltry 60kb/s which is no wonder the game never seemed to load.

Anyway, it works now, thanks for the help.

PS : Is there any update on when can we expect a decent loading screen/template for WebGL?
The current one is really bad.

The game start for me, but it take time.
I have checked by inspecting the element and the http://23.96.38.122/Release/Builds.datagz size is 133 MB and the download is a bit slow.

1 Like

Thanks for the feedback, which country are you in? I fired up a East US Azure VM, which probably isn’t the best location if I’m in New Zealand for speed. But I have prospective publishers looking at the game and they mostly in the US.

I’m French and http://23.96.38.122/Release/Builds.datagz run around 2mo/S for me.
133 MB is a bit big from the start, you must reduce it or use assetbundle to reduce the “waitting time”.