{"id":5346,"date":"2021-04-07T14:16:34","date_gmt":"2021-04-07T11:16:34","guid":{"rendered":"https:\/\/unitycoder.com\/blog\/?p=5346"},"modified":"2021-04-07T14:16:34","modified_gmt":"2021-04-07T11:16:34","slug":"compress-webgl-build-manually-from-command-line-brotli","status":"publish","type":"post","link":"https:\/\/unitycoder.com\/blog\/2021\/04\/07\/compress-webgl-build-manually-from-command-line-brotli\/","title":{"rendered":"Compress WebGL build manually from command line (brotli)"},"content":{"rendered":"\n<p>Building brotli compressed webgl release can take hours (if you have large 3d models in the project..), and you cannot do anything with the project while unity is compressing it.<\/p>\n\n\n\n<p><strong>Solution:<\/strong><br>Make (really fast) uncompressed builds from unity,<br>then compress the webgl data files manually from commandline! <br>(note that the example script below uses absolute paths for Unity 2019.4 and project folder)<\/p>\n\n\n\n<figure class=\"wp-block-embed is-type-rich is-provider-embed-handler wp-block-embed-embed-handler\"><div class=\"wp-block-embed__wrapper\">\n<style>.gist table { margin-bottom: 0; }<\/style><div style=\"tab-size: 8\" id=\"gist108871027\" class=\"gist\">\n    <div class=\"gist-file\" translate=\"no\" data-color-mode=\"light\" data-light-theme=\"light\">\n      <div class=\"gist-data\">\n        \n<div class=\"js-gist-file-update-container js-task-list-container\">\n      <div id=\"file-webglcompress-bat\" class=\"file my-2\">\n    \n    <div itemprop=\"text\"\n      class=\"Box-body p-0 blob-wrapper data type-batchfile  \"\n      style=\"overflow: auto\" tabindex=\"0\" role=\"region\"\n      aria-label=\"webglcompress.bat content, created by unitycoder on 10:49AM on April 07, 2021.\"\n    >\n\n        \n<div class=\"js-check-hidden-unicode js-blob-code-container blob-code-content\">\n\n  <template class=\"js-file-alert-template\">\n  <div data-view-component=\"true\" class=\"flash flash-warn flash-full d-flex flex-items-center\">\n  <svg aria-hidden=\"true\" data-component=\"Octicon\" height=\"16\" viewBox=\"0 0 16 16\" version=\"1.1\" width=\"16\" data-view-component=\"true\" class=\"octicon octicon-alert\">\n    <path d=\"M6.457 1.047c.659-1.234 2.427-1.234 3.086 0l6.082 11.378A1.75 1.75 0 0 1 14.082 15H1.918a1.75 1.75 0 0 1-1.543-2.575Zm1.763.707a.25.25 0 0 0-.44 0L1.698 13.132a.25.25 0 0 0 .22.368h12.164a.25.25 0 0 0 .22-.368Zm.53 3.996v2.5a.75.75 0 0 1-1.5 0v-2.5a.75.75 0 0 1 1.5 0ZM9 11a1 1 0 1 1-2 0 1 1 0 0 1 2 0Z\"><\/path>\n<\/svg>\n    <span>\n      This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.\n      <a class=\"Link--inTextBlock\" href=\"https:\/\/github.co\/hiddenchars\" target=\"_blank\">Learn more about bidirectional Unicode characters<\/a>\n    <\/span>\n\n\n  <div data-view-component=\"true\" class=\"flash-action\">        <a href=\"{{ revealButtonHref }}\" data-view-component=\"true\" class=\"btn-sm btn\">    Show hidden characters\n<\/a>\n<\/div>\n<\/div><\/template>\n<template class=\"js-line-alert-template\">\n  <span aria-label=\"This line has hidden Unicode characters\" data-view-component=\"true\" class=\"line-alert tooltipped tooltipped-e\">\n    <svg aria-hidden=\"true\" data-component=\"Octicon\" height=\"16\" viewBox=\"0 0 16 16\" version=\"1.1\" width=\"16\" data-view-component=\"true\" class=\"octicon octicon-alert\">\n    <path d=\"M6.457 1.047c.659-1.234 2.427-1.234 3.086 0l6.082 11.378A1.75 1.75 0 0 1 14.082 15H1.918a1.75 1.75 0 0 1-1.543-2.575Zm1.763.707a.25.25 0 0 0-.44 0L1.698 13.132a.25.25 0 0 0 .22.368h12.164a.25.25 0 0 0 .22-.368Zm.53 3.996v2.5a.75.75 0 0 1-1.5 0v-2.5a.75.75 0 0 1 1.5 0ZM9 11a1 1 0 1 1-2 0 1 1 0 0 1 2 0Z\"><\/path>\n<\/svg>\n<\/span><\/template>\n\n  <table data-hpc class=\"highlight tab-size js-file-line-container\" data-tab-size=\"4\" data-paste-markdown-skip data-tagsearch-path=\"webglcompress.bat\">\n        <tr>\n          <td id=\"file-webglcompress-bat-L1\" class=\"blob-num js-line-number js-blob-rnum\" data-line-number=\"1\"><\/td>\n          <td id=\"file-webglcompress-bat-LC1\" class=\"blob-code blob-code-inner js-file-line\">echo off<\/td>\n        <\/tr>\n        <tr>\n          <td id=\"file-webglcompress-bat-L2\" class=\"blob-num js-line-number js-blob-rnum\" data-line-number=\"2\"><\/td>\n          <td id=\"file-webglcompress-bat-LC2\" class=\"blob-code blob-code-inner js-file-line\">REM add egg path<\/td>\n        <\/tr>\n        <tr>\n          <td id=\"file-webglcompress-bat-L3\" class=\"blob-num js-line-number js-blob-rnum\" data-line-number=\"3\"><\/td>\n          <td id=\"file-webglcompress-bat-LC3\" class=\"blob-code blob-code-inner js-file-line\">set PYTHONPATH=D:\/Program Files\/Unity2019_4\/Editor\/Data\/PlaybackEngines\/WebGLSupport\/BuildTools\/Brotli\/dist\/Brotli-0.4.0-py2.7-win-amd64.egg <\/td>\n        <\/tr>\n        <tr>\n          <td id=\"file-webglcompress-bat-L4\" class=\"blob-num js-line-number js-blob-rnum\" data-line-number=\"4\"><\/td>\n          <td id=\"file-webglcompress-bat-LC4\" class=\"blob-code blob-code-inner js-file-line\">\n<\/td>\n        <\/tr>\n        <tr>\n          <td id=\"file-webglcompress-bat-L5\" class=\"blob-num js-line-number js-blob-rnum\" data-line-number=\"5\"><\/td>\n          <td id=\"file-webglcompress-bat-LC5\" class=\"blob-code blob-code-inner js-file-line\">REM rename uncompressed data files (because brotli cannot overwrite same file that its packing)<\/td>\n        <\/tr>\n        <tr>\n          <td id=\"file-webglcompress-bat-L6\" class=\"blob-num js-line-number js-blob-rnum\" data-line-number=\"6\"><\/td>\n          <td id=\"file-webglcompress-bat-LC6\" class=\"blob-code blob-code-inner js-file-line\">move \/Y &quot;F:\\Your\\Project\\Build\\uncompressed.wasm.framework.unityweb&quot; &quot;F:\\Your\\Project\\Build\\uncompressed.wasm.framework.unityweb2&quot;<\/td>\n        <\/tr>\n        <tr>\n          <td id=\"file-webglcompress-bat-L7\" class=\"blob-num js-line-number js-blob-rnum\" data-line-number=\"7\"><\/td>\n          <td id=\"file-webglcompress-bat-LC7\" class=\"blob-code blob-code-inner js-file-line\">move \/Y &quot;F:\\Your\\Project\\Build\\uncompressed.wasm.code.unityweb&quot; &quot;F:\\Your\\Project\\Build\\uncompressed.wasm.code.unityweb2&quot;<\/td>\n        <\/tr>\n        <tr>\n          <td id=\"file-webglcompress-bat-L8\" class=\"blob-num js-line-number js-blob-rnum\" data-line-number=\"8\"><\/td>\n          <td id=\"file-webglcompress-bat-LC8\" class=\"blob-code blob-code-inner js-file-line\">move \/Y &quot;F:\\Your\\Project\\Build\\uncompressed.data.unityweb&quot; &quot;F:\\Your\\Project\\Build\\uncompressed.data.unityweb2&quot;<\/td>\n        <\/tr>\n        <tr>\n          <td id=\"file-webglcompress-bat-L9\" class=\"blob-num js-line-number js-blob-rnum\" data-line-number=\"9\"><\/td>\n          <td id=\"file-webglcompress-bat-LC9\" class=\"blob-code blob-code-inner js-file-line\">\n<\/td>\n        <\/tr>\n        <tr>\n          <td id=\"file-webglcompress-bat-L10\" class=\"blob-num js-line-number js-blob-rnum\" data-line-number=\"10\"><\/td>\n          <td id=\"file-webglcompress-bat-LC10\" class=\"blob-code blob-code-inner js-file-line\">REM compress<\/td>\n        <\/tr>\n        <tr>\n          <td id=\"file-webglcompress-bat-L11\" class=\"blob-num js-line-number js-blob-rnum\" data-line-number=\"11\"><\/td>\n          <td id=\"file-webglcompress-bat-LC11\" class=\"blob-code blob-code-inner js-file-line\">&quot;D:\/Program Files\/Unity2019_4\/Editor\/Data\/PlaybackEngines\/WebGLSupport\\BuildTools\\Emscripten_Win\\python\\2.7.5.3_64bit\\python.exe&quot; &quot;D:\/Program Files\/Unity2019_4\/Editor\/Data\/PlaybackEngines\/WebGLSupport\\BuildTools\\Brotli\\python\\bro.py&quot; -o &quot;F:\\Your\\Project\\Builds\\uncompressed\\Build\\uncompressed.wasm.framework.unityweb2&quot; -i &quot;F:\\Your\\Project\\Builds\\\\uncompressed\\Build\\uncompressed.wasm.framework.unityweb&quot; &#8211;comment &quot;UnityWeb Compressed Content (brotli)&quot;<\/td>\n        <\/tr>\n        <tr>\n          <td id=\"file-webglcompress-bat-L12\" class=\"blob-num js-line-number js-blob-rnum\" data-line-number=\"12\"><\/td>\n          <td id=\"file-webglcompress-bat-LC12\" class=\"blob-code blob-code-inner js-file-line\">&quot;D:\/Program Files\/Unity2019_4\/Editor\/Data\/PlaybackEngines\/WebGLSupport\\BuildTools\\Emscripten_Win\\python\\2.7.5.3_64bit\\python.exe&quot; &quot;D:\/Program Files\/Unity2019_4\/Editor\/Data\/PlaybackEngines\/WebGLSupport\\BuildTools\\Brotli\\python\\bro.py&quot; -o &quot;F:\\Your\\Project\\Builds\\\\uncompressed\\Build\\uncompressed.wasm.code.unityweb2&quot; -i &quot;F:\\Your\\Project\\Builds\\\\uncompressed\\Build\\uncompressed.wasm.code.unityweb&quot; &#8211;comment &quot;UnityWeb Compressed Content (brotli)&quot;<\/td>\n        <\/tr>\n        <tr>\n          <td id=\"file-webglcompress-bat-L13\" class=\"blob-num js-line-number js-blob-rnum\" data-line-number=\"13\"><\/td>\n          <td id=\"file-webglcompress-bat-LC13\" class=\"blob-code blob-code-inner js-file-line\">&quot;D:\/Program Files\/Unity2019_4\/Editor\/Data\/PlaybackEngines\/WebGLSupport\\BuildTools\\Emscripten_Win\\python\\2.7.5.3_64bit\\python.exe&quot; &quot;D:\/Program Files\/Unity2019_4\/Editor\/Data\/PlaybackEngines\/WebGLSupport\\BuildTools\\Brotli\\python\\bro.py&quot; -o &quot;F:\\Your\\Project\\Builds\\\\uncompressed\\Build\\uncompressed.data.unityweb2&quot; -i &quot;F:\\Your\\Project\\Builds\\\\uncompressed\\Build\\uncompressed.data.unityweb&quot; &#8211;comment &quot;UnityWeb Compressed Content (brotli)&quot;<\/td>\n        <\/tr>\n  <\/table>\n<\/div>\n\n\n    <\/div>\n\n  <\/div>\n\n<\/div>\n\n      <\/div>\n      <div class=\"gist-meta\">\n        <a href=\"https:\/\/gist.github.com\/unitycoder\/b4f6b38b4809df87006534392a239dd3\/raw\/64c0f016063e0377ebdbf661976c318ce682ed60\/webglcompress.bat\" style=\"float:right\" class=\"Link--inTextBlock\">view raw<\/a>\n        <a href=\"https:\/\/gist.github.com\/unitycoder\/b4f6b38b4809df87006534392a239dd3#file-webglcompress-bat\" class=\"Link--inTextBlock\">\n          webglcompress.bat\n        <\/a>\n        hosted with &#10084; by <a class=\"Link--inTextBlock\" href=\"https:\/\/github.com\">GitHub<\/a>\n      <\/div>\n    <\/div>\n<\/div>\n\n<\/div><\/figure>\n\n\n\n<figure class=\"wp-block-image size-large\"><a href=\"https:\/\/i0.wp.com\/unitycoder.com\/blog\/wp-content\/uploads\/2021\/04\/image.png?ssl=1\"><img data-recalc-dims=\"1\" loading=\"lazy\" decoding=\"async\" width=\"617\" height=\"188\" data-attachment-id=\"5348\" data-permalink=\"https:\/\/unitycoder.com\/blog\/2021\/04\/07\/compress-webgl-build-manually-from-command-line-brotli\/image-25\/\" data-orig-file=\"https:\/\/i0.wp.com\/unitycoder.com\/blog\/wp-content\/uploads\/2021\/04\/image.png?fit=617%2C188&amp;ssl=1\" data-orig-size=\"617,188\" data-comments-opened=\"1\" data-image-meta=\"{&quot;aperture&quot;:&quot;0&quot;,&quot;credit&quot;:&quot;&quot;,&quot;camera&quot;:&quot;&quot;,&quot;caption&quot;:&quot;&quot;,&quot;created_timestamp&quot;:&quot;0&quot;,&quot;copyright&quot;:&quot;&quot;,&quot;focal_length&quot;:&quot;0&quot;,&quot;iso&quot;:&quot;0&quot;,&quot;shutter_speed&quot;:&quot;0&quot;,&quot;title&quot;:&quot;&quot;,&quot;orientation&quot;:&quot;0&quot;}\" data-image-title=\"image\" data-image-description=\"\" data-image-caption=\"\" data-large-file=\"https:\/\/i0.wp.com\/unitycoder.com\/blog\/wp-content\/uploads\/2021\/04\/image.png?fit=617%2C188&amp;ssl=1\" src=\"https:\/\/i0.wp.com\/unitycoder.com\/blog\/wp-content\/uploads\/2021\/04\/image.png?resize=617%2C188&#038;ssl=1\" alt=\"\" class=\"wp-image-5348\" srcset=\"https:\/\/i0.wp.com\/unitycoder.com\/blog\/wp-content\/uploads\/2021\/04\/image.png?w=617&amp;ssl=1 617w, https:\/\/i0.wp.com\/unitycoder.com\/blog\/wp-content\/uploads\/2021\/04\/image.png?resize=300%2C91&amp;ssl=1 300w\" sizes=\"auto, (max-width: 617px) 100vw, 617px\" \/><\/a><\/figure>\n\n\n\n<p><strong>Some notes:<\/strong><br>&#8211; Script renames uncompressed data files first as *.unityweb2, because brotli cannot overwrite the same files that its compressing (optionally you could keep original file names, and create new compressed filenames, and modify the .json file to use new compressed files instead)<br>&#8211; need to add that brotli .egg path into pythonpath, otherwise bro.py cannot find it  (optionally you could modify .bro file to include that path directly, see image below, modified script header to include path:<\/p>\n\n\n\n<figure class=\"wp-block-image size-large\"><a href=\"https:\/\/i0.wp.com\/unitycoder.com\/blog\/wp-content\/uploads\/2021\/04\/image-1.png?ssl=1\"><img data-recalc-dims=\"1\" loading=\"lazy\" decoding=\"async\" width=\"1024\" height=\"212\" data-attachment-id=\"5349\" data-permalink=\"https:\/\/unitycoder.com\/blog\/2021\/04\/07\/compress-webgl-build-manually-from-command-line-brotli\/image-1-11\/\" data-orig-file=\"https:\/\/i0.wp.com\/unitycoder.com\/blog\/wp-content\/uploads\/2021\/04\/image-1.png?fit=1094%2C227&amp;ssl=1\" data-orig-size=\"1094,227\" data-comments-opened=\"1\" data-image-meta=\"{&quot;aperture&quot;:&quot;0&quot;,&quot;credit&quot;:&quot;&quot;,&quot;camera&quot;:&quot;&quot;,&quot;caption&quot;:&quot;&quot;,&quot;created_timestamp&quot;:&quot;0&quot;,&quot;copyright&quot;:&quot;&quot;,&quot;focal_length&quot;:&quot;0&quot;,&quot;iso&quot;:&quot;0&quot;,&quot;shutter_speed&quot;:&quot;0&quot;,&quot;title&quot;:&quot;&quot;,&quot;orientation&quot;:&quot;0&quot;}\" data-image-title=\"image-1\" data-image-description=\"\" data-image-caption=\"\" data-large-file=\"https:\/\/i0.wp.com\/unitycoder.com\/blog\/wp-content\/uploads\/2021\/04\/image-1.png?fit=1024%2C212&amp;ssl=1\" src=\"https:\/\/i0.wp.com\/unitycoder.com\/blog\/wp-content\/uploads\/2021\/04\/image-1.png?resize=1024%2C212&#038;ssl=1\" alt=\"\" class=\"wp-image-5349\" srcset=\"https:\/\/i0.wp.com\/unitycoder.com\/blog\/wp-content\/uploads\/2021\/04\/image-1.png?resize=1024%2C212&amp;ssl=1 1024w, https:\/\/i0.wp.com\/unitycoder.com\/blog\/wp-content\/uploads\/2021\/04\/image-1.png?resize=300%2C62&amp;ssl=1 300w, https:\/\/i0.wp.com\/unitycoder.com\/blog\/wp-content\/uploads\/2021\/04\/image-1.png?resize=768%2C159&amp;ssl=1 768w, https:\/\/i0.wp.com\/unitycoder.com\/blog\/wp-content\/uploads\/2021\/04\/image-1.png?w=1094&amp;ssl=1 1094w\" sizes=\"auto, (max-width: 1000px) 100vw, 1000px\" \/><\/a><\/figure>\n","protected":false},"excerpt":{"rendered":"<p>Building brotli compressed webgl release can take hours (if you have large 3d models in the project..), and you cannot do anything with the project while unity is compressing it. Solution:Make (really fast) uncompressed builds from unity,then compress the webgl data files manually from commandline! [&hellip;]<\/p>\n","protected":false},"author":1,"featured_media":5348,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"_jetpack_newsletter_access":"","_jetpack_dont_email_post_to_subs":false,"_jetpack_newsletter_tier_id":0,"_jetpack_memberships_contains_paywalled_content":false,"_jetpack_memberships_contains_paid_content":false,"footnotes":"","jetpack_publicize_message":"","jetpack_publicize_feature_enabled":true,"jetpack_social_post_already_shared":true,"jetpack_social_options":{"image_generator_settings":{"template":"highway","default_image_id":0,"font":"","enabled":false},"version":2},"jetpack_post_was_ever_published":false},"categories":[1056,1],"tags":[1203,1201,188,1202,320],"class_list":["post-5346","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-external-tools","category-uncategorized","tag-batch","tag-brotli","tag-build","tag-compress","tag-webgl"],"jetpack_publicize_connections":[],"jetpack_featured_media_url":"https:\/\/i0.wp.com\/unitycoder.com\/blog\/wp-content\/uploads\/2021\/04\/image.png?fit=617%2C188&ssl=1","jetpack_shortlink":"https:\/\/wp.me\/p1KTaT-1oe","jetpack_sharing_enabled":true,"_links":{"self":[{"href":"https:\/\/unitycoder.com\/blog\/wp-json\/wp\/v2\/posts\/5346","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/unitycoder.com\/blog\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/unitycoder.com\/blog\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/unitycoder.com\/blog\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/unitycoder.com\/blog\/wp-json\/wp\/v2\/comments?post=5346"}],"version-history":[{"count":3,"href":"https:\/\/unitycoder.com\/blog\/wp-json\/wp\/v2\/posts\/5346\/revisions"}],"predecessor-version":[{"id":5353,"href":"https:\/\/unitycoder.com\/blog\/wp-json\/wp\/v2\/posts\/5346\/revisions\/5353"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/unitycoder.com\/blog\/wp-json\/wp\/v2\/media\/5348"}],"wp:attachment":[{"href":"https:\/\/unitycoder.com\/blog\/wp-json\/wp\/v2\/media?parent=5346"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/unitycoder.com\/blog\/wp-json\/wp\/v2\/categories?post=5346"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/unitycoder.com\/blog\/wp-json\/wp\/v2\/tags?post=5346"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}