Choose a version:
53% The original file has 908205 bytes (886.9k) and is available from the project website.
There you can find the official minified version, too, which brings down the size to 477150 bytes (466.0k, 53%).

After GZIP compression these minified files vary in size:
Boot
  135082 bytes (131.9k)
CDN
cdnjs
  111946 bytes (109.3k)
CDN
unpkg
  111503 bytes (108.9k)
CDN
Google
  110836 bytes (108.2k)
CDN
gzip -6 (default)
  110736 bytes (108.1k)
local copy
jsdelivr
  110356 bytes (107.8k)
CDN
gzip -9
  110301 bytes (107.7k)
local copy
libdeflate -12
  106525 bytes (104.0k)
local copy
zultra
  106468 bytes (104.0k)
local copy
7zip -mx=9 -tgzip
  106369 bytes (103.9k)
local copy
pigz -11 -n
  106193 bytes (103.7k)
local copy
kzip -s0 -rn -b0
  106105 bytes (103.6k)
local copy
Zopfli
  106081 bytes (103.6k)
local copy
Zopfli (defluff)
  106076 bytes (103.6k)
local copy

perma-link to the smallest file on my server:
http://minime.stephan-brumme.com/files/threejs/three-r74.min.js (or via HTTPS)

You will automatically get the smallest ThreeJS 74 file, ETag caching is available and
if your browser doesn't support GZIP decompression then the uncompressed version will be sent.

Currently best Zopfli settings

Save 4275 bytes by using my ThreeJS 74 Zopfli version instead of the best available CDN (4.03% smaller than jsdelivr, 106081 vs. 110356 bytes):
You can use my super-compressed files for whatever purpose you like as long as you respect the library's original license agreement.
There are no restrictions from my side - but please avoid hot-linking if you run a high-traffic website.

These command-line settings yielded the best compression ratio so far (Linux version of zopfli-krzymod):
zopfli --i1000000 --mb8 --mls16384 --bsr20 --lazy --ohh

(found February 11, 2016)
Description Value Parameter
iterations 1000000  --i1000000
maximum blocks 8  --mb8
maximum length score 16384  --mls16384
block splitting recursion 20  --bsr20
lazy matching in LZ77 yes  --lazy
optimized Huffman headers yes  --ohh
initial random W for iterations 1  --rw1
initial random Z for iterations 2  --rz2

Even Smaller Files Thanks To Defluff

Zopfli's output can be further optimized by the defluff tool.
In this particular case, defluff saves 5 more bytes (106076 bytes).

Verify file integrity

After decompression, my uncompressed files are identical to the original ones:

MD5:
curl --silent --compressed https://raw.githubusercontent.com/mrdoob/three.js/r74/build/three.min.js --location | md5sum
a2716893ae1194c330ddf186776d7a9e  -
curl --silent --compressed https://minime.stephan-brumme.com/files/threejs/three-r74.min.zopfli.js.gz | md5sum
a2716893ae1194c330ddf186776d7a9e  -

SHA1:
curl --silent --compressed https://raw.githubusercontent.com/mrdoob/three.js/r74/build/three.min.js --location | sha1sum
5dac18f2b6863b26bac50b7f2e68c45a0e7ef14a  -
curl --silent --compressed https://minime.stephan-brumme.com/files/threejs/three-r74.min.zopfli.js.gz | sha1sum
5dac18f2b6863b26bac50b7f2e68c45a0e7ef14a  -

CDN Size (compressed) MD5 (uncompressed) Comment / Diff Timestamp
Boot 135082 bytes 79b54ccd62d65822dc5b42bffda318ad < THREE.Box3.prototype={constructor:THREE.Box3,set:function( [...]
< setFromCenterAndSize:function(){var a=new THREE.Vector3;re [...]
< copy:function(a){this.min.copy(a.min);this.max.copy(a.max) [...]
< this.max.max(a);return this},expandByVector:function(a){th [...]
< b){return(b||new THREE.Vector3).set((a.x-this.min.x)/(this [...]
< c;0<a.normal.x?(b=a.normal.x*this.min.x,c=a.normal.x*this. [...]
< new THREE.Vector3;return function(b){return a.copy(b).clam [...]
< new THREE.Vector3,new THREE.Vector3,new THREE.Vector3,new [...]
< a[7].set(this.max.x,this.max.y,this.max.z).applyMatrix4(b) [...]
> THREE.Box3.prototype={constructor:THREE.Box3,set:function( [...]
[...]
February 9, 2016 @ 10:40
cdnjs 111946 bytes 79b54ccd62d65822dc5b42bffda318ad < THREE.Box3.prototype={constructor:THREE.Box3,set:function( [...]
< setFromCenterAndSize:function(){var a=new THREE.Vector3;re [...]
< copy:function(a){this.min.copy(a.min);this.max.copy(a.max) [...]
< this.max.max(a);return this},expandByVector:function(a){th [...]
< b){return(b||new THREE.Vector3).set((a.x-this.min.x)/(this [...]
< c;0<a.normal.x?(b=a.normal.x*this.min.x,c=a.normal.x*this. [...]
< new THREE.Vector3;return function(b){return a.copy(b).clam [...]
< new THREE.Vector3,new THREE.Vector3,new THREE.Vector3,new [...]
< a[7].set(this.max.x,this.max.y,this.max.z).applyMatrix4(b) [...]
> THREE.Box3.prototype={constructor:THREE.Box3,set:function( [...]
[...]
(invalid)
unpkg 111503 bytes 1390beeaeff43f6ecce0cf0f6c9225fb < // threejs.org/license
> var self = self || {};// threejs.org/license
>
> // Export the THREE object for **Node.js**, with
> // backwards-compatibility for the old `require()` API. If [...]
> // the browser, add `_` as a global object via a string id [...]
> // for Closure Compiler "advanced" mode.
> if (typeof exports !== 'undefined') {
> if (typeof module !== 'undefined' && module.exports) {
> exports = module.exports = THREE;
[...]
July 11, 2016 @ 15:49
Google 110836 bytes f264ef22889c6876ab4ca2b8fc4c467a < void 0===Object.assign&&Object.defineProperty(Object,"assi [...]
> void 0===Object.assign&&Object.defineProperty(Object,"assi [...]
< b){var c=b/2,d=Math.sin(c);this._x=a.x*d;this._y=a.y*d;thi [...]
> b){var c=b/2,d=Math.sin(c);this._x=a.x*d;this._y=a.y*d;thi [...]
< multiply:function(a,b){return void 0!==b?(console.warn("TH [...]
> multiply:function(a,b){return void 0!==b?(console.warn("TH [...]
< Object.assign(THREE.Quaternion,{slerp:function(a,b,c,d){re [...]
> Object.assign(THREE.Quaternion,{slerp:function(a,b,c,d){re [...]
< f=a.y,g=a.z;a=a.w;var h=a*b+f*d-g*c,k=a*c+g*b-e*d,m=a*d+e* [...]
> f=a.y,g=a.z;a=a.w;var h=a*b+f*d-g*c,k=a*c+g*b-e*d,l=a*d+e* [...]
[...]
May 13, 2016 @ 20:29
jsdelivr 110356 bytes 79b54ccd62d65822dc5b42bffda318ad < THREE.Box3.prototype={constructor:THREE.Box3,set:function( [...]
< setFromCenterAndSize:function(){var a=new THREE.Vector3;re [...]
< copy:function(a){this.min.copy(a.min);this.max.copy(a.max) [...]
< this.max.max(a);return this},expandByVector:function(a){th [...]
< b){return(b||new THREE.Vector3).set((a.x-this.min.x)/(this [...]
< c;0<a.normal.x?(b=a.normal.x*this.min.x,c=a.normal.x*this. [...]
< new THREE.Vector3;return function(b){return a.copy(b).clam [...]
< new THREE.Vector3,new THREE.Vector3,new THREE.Vector3,new [...]
< a[7].set(this.max.x,this.max.y,this.max.z).applyMatrix4(b) [...]
> THREE.Box3.prototype={constructor:THREE.Box3,set:function( [...]
[...]
(invalid)

Note: only the MD5 hashes are shown to keep things simple.

Other Versions

Available ThreeJS versions at minime.stephan-brumme.com:

148, 147, 146, 145, 144, 143, 142, 141, 140, 139, 138, 137, 136, 135, 134, 133, 132, 131, 130, 129, 128, 127, 126, 125, 124, 123, 122, 121, 120, 119, 118, 117, 116, 115, 114, 113, 112, 111, 110, 109, 108, 107, 106, 105, 104, 103, 102, 101, 100, 99, 98, 97, 96, 95, 94, 93, 92, 91, 90, 89, 88, 87, 86, 85, 84, 83, 82, 81, 80, 79, 78, 77, 76, 75, 74, 73, 72, 71, 70, 69, 68, 67, 66, 65, 64, 63, 62, 61, 60, 59, 58, 57, 56, 55, 54, 53, 52, 51, 50

The project site contains an overview how well these versions were compressed.
Other interesting projects are AngularJS, BackboneJS, Bootstrap, D3, Dojo, Ember, jQuery, Knockout, lodash, React, Socket.IO, UnderscoreJS and Vue.

Changelog

Best Zopfli parameters so far:
Size Improvement Parameters Found
106081 bytes -5 bytes zopfli --i1000000 --mls16384 --bsr20 --lazy --ohh February 11, 2016 @ 05:06
106086 bytes -4 bytes zopfli --i100000 --mls16384 --bsr20 --lazy --ohh February 8, 2016 @ 19:33
106090 bytes -11 bytes zopfli --i10000 --mls16384 --bsr20 --lazy --ohh February 8, 2016 @ 13:55
106101 bytes -24 bytes zopfli --i1000 --mls16384 --bsr20 --lazy --ohh February 8, 2016 @ 13:20
106125 bytes zopfli --i100 --mls16384 --bsr20 --lazy --ohh February 8, 2016 @ 11:58

If there are multiple parameter sets yielding the same compressed size, only the first one found is shown.

Most recent activity on July 20, 2020 @ 12:52.

Heatmaps

This Zopfli heatmap visualizes how compression changes when modifying the --bsr and --mls parameter.
Cell's contents is the best filesize achieved (in bytes, hover with mouse over cells to see number of iterations).

Good parameters are green, bad are red. The best and worst are bold as well.
The brightness of the blue background color indicates how many iterations were processed:
10,000, 100,000 or 1,000,000.
bsr \ mls
2 4 8 16 32 64 128 256 512 1024 2048 4096 8192 16384 32768
bsr \ mls
2 4 8 16 32 64 128 256 512 1024 2048 4096 8192 16384 32768
106207 106202 106206 106206 106230 106225 106196 106149 106168 106252 106217 106183 106152 106170 106254
106157 106133 106144 106129 106151 106180 106240 106159 106144 106156 106139 106129 106157 106167 106151
106116 106115 106127 106231 106237 106231 106238 106141 106142 106117 106131 106130 106124 106146 106225
106120 106118 106122 106127 106145 106137 106125 106147 106130 106102 106119 106107 106132 106110 106202
106136 106138 106128 106115 106115 106123 106235 106127 106147 106130 106131 106128 106151 106116 106194
106135 106129 106118 106136 106241 106129 106235 106250 106244 106147 106134 106131 106227 106116 106180
106140 106138 106111 106109 106238 106128 106233 106133 106144 106115 106132 106125 106134 106131 106188
106141 106119 106139 106126 106161 106163 106116 106131 106112 106164 106126 106125 106120 106115 106127
106131 106132 106127 106121 106125 106133 106125 106106 106130 106110 106109 106195 106134 106097 106113
106119 106129 106108 106128 106119 106138 106107 106130 106111 106107 106133 106124 106105 106124 106152
106115 106124 106123 106115 106126 106122 106123 106116 106116 106114 106132 106098 106119 106119 106149
106124 106129 106146 106127 106145 106142 106144 106101 106143 106102 106102 106123 106118 106100 106190
106122 106129 106122 106111 106126 106114 106117 106137 106138 106160 106108 106111 106136 106132 106126
106134 106129 106120 106114 106115 106127 106123 106101 106099 106121 106101 106110 106137 106097 106200
106129 106122 106123 106111 106116 106122 106148 106140 106138 106162 106101 106118 106121 106100 106173
106123 106232 106231 106242 106238 106251 106235 106111 106140 106100 106113 106128 106132 106087 106191
106149 106119 106237 106242 106223 106231 106229 106253 106216 106149 106102 106107 106132 106081 106176
106129 106122 106232 106242 106243 106228 106223 106131 106110 106220 106101 106107 106135 106098 106187
106124 106168 106119 106114 106120 106247 106210 106130 106137 106222 106108 106125 106136 106101 106192
106166 106124 106108 106103 106116 106137 106121 106104 106109 106115 106103 106127 106115 106117 106126
106108 106113 106109 106119 106122 106135 106133 106101 106133 106099 106105 106129 106100 106103 106185
106112 106130 106120 106152 106116 106147 106098 106097 106138 106129 106101 106108 106136 106106 106187
106110 106115 106113 106116 106116 106131 106128 106115 106139 106112 106100 106127 106136 106102 106146

Due to the Monte Carlo design of my search algorithm, not all parameters have reached the same number of iterations yet:
Iterations Min. Bytes Reduction Coverage
100 106125 bytes 100%
1,000 106101 bytes -24 bytes 100%
10,000 106090 bytes -11 bytes 100%
100,000 106086 bytes -4 bytes 0.58%
1,000,000 106081 bytes -5 bytes 0.29%
10,000,000

KZIP has far less options available for tuning/optimization. I only played around with the number of blocks (parameter -n):
Blocks Min. Bytes Compared To Best Zopfli Compared To Best KZIP
106105 bytes +24 bytes (+0.02%)
106641 bytes +560 bytes (+0.53%) +536 bytes
106652 bytes +571 bytes (+0.54%) +547 bytes
106534 bytes +453 bytes (+0.43%) +429 bytes
106433 bytes +352 bytes (+0.33%) +328 bytes
106364 bytes +283 bytes (+0.27%) +259 bytes
106323 bytes +242 bytes (+0.23%) +218 bytes
106305 bytes +224 bytes (+0.21%) +200 bytes
106156 bytes +75 bytes (+0.07%) +51 bytes

Non-DEFLATE Algorithms

Archivers based on completely different compression algorithms often produce superior results.
Unfortunately, browsers only support gzip compression at the moment.
However, support for Brotli is constantly growing - but your browser doesn't support it.
Algorithm Program Parameters Size Compared To Best Zopfli
ZPAQ (Wikipedia) zpaq zpaq -method 69 72106 bytes -33975 bytes (-32.03%)
RAR (proprietary) RAR rar a -m5 -md64m -mc63:128t -mt1 82871 bytes -23210 bytes (-21.88%)
PPMd (Wikipedia) 7zip 7za a -mx=9 -m0=ppmd 88092 bytes -17989 bytes (-16.96%)
Brotli (Wikipedia) brotli brotli -q 11 92218 bytes -13863 bytes (-13.07%)
LZMA2 (Wikipedia) xz xz -9 93000 bytes -13081 bytes (-12.33%)
Burrows-Wheeler transform (Wikipedia) bzip2 bzip2 -9 96217 bytes -9864 bytes (-9.30%)
Zstandard (Wikipedia) zstd zstd -19 98233 bytes -7848 bytes (-7.40%)

Detailled Analysis

I wrote a DEFLATE decoder in Javascript. Click the button below to start a client-side analysis of the smallest gzipped files (may take a second):


Notes: pigz is a fast open source multi-threaded implementation of gzip written by one of the original authors of gzip.
However, when using compression level 11, pigz actually switches to the slower Zopfli algorithm and isn't multi-threaded anymore.
KrzyMOD's extensions to Zopfli offer the highest level of configuration and is therefore used for my brute-force search.
Ken Silverman wrote the closed-source KZIP compression program and Jonathon Fowler ported it to Linux.
Defluff was created by Joachim Henke; DeflOpt is a tool by Ben Jos Walbeehm.

website made by Stephan Brumme in 2015 and still improving in 2024.
all timestamps are displayed in central european time. see my changelog.
no flash, not even images or external css files - and everything squeezed into a single html file.
which was handsomely compressed before releasing it into the wild internet - obviously.

please visit my homepage and my blog, too.
email: minime (at) stephan-brumme.com

All trademarks are property of their respective owners. You know, the boring legal stuff.