Skip to main content

Bug Tracker

Side navigation

#13759 closed feature (fixed)

Opened April 10, 2013 12:42AM UTC

Closed April 15, 2013 04:49PM UTC

Last modified April 15, 2013 05:04PM UTC

Better undefined gzip compression

Reported by: m_gol Owned by: m_gol
Priority: low Milestone: None
Component: build Version: 2.0.0-beta3
Keywords: Cc:
Blocked by: Blocking:
Description

We can compress better if we tell uglifyjs to not mangle undefined, as suggested by dcherman.

----- ORIGINAL TEXT -----

According to ES5.1, undefined is immutable. All supported in 2.0 browsers besides Android <4.1 (including iOS 5.1 and VERY old Safari) adhere to that.

Removing undefined from the main IIFE parameters saves 62 bytes in the gzipped minified file.

I'm putting it here for a discussion. If we decided to go for that, we also have to decide what to do about 1.x

Attachments (0)
Change History (14)

Changed April 10, 2013 03:18AM UTC by rwaldron comment:1

+1

Changed April 10, 2013 02:49PM UTC by timmywil comment:2

component: unfiledbuild
priority: undecidedlow
status: newopen

Even Android?

Changed April 10, 2013 03:03PM UTC by m_gol comment:3

@timmywil, please read my report again, I covered Android.

Changed April 10, 2013 03:08PM UTC by timmywil comment:4

Oh, sorry. I don't even know which Android browsers we want to support.

Changed April 10, 2013 03:31PM UTC by m_gol comment:5

I guess >= 2.3 currently, unfortunately. :( Anyway, I doubt anyone writes sites only for Android <4.1 so relying on the ability to redefine undefined wouldn't work.

Changed April 10, 2013 03:58PM UTC by m_gol comment:6

_comment0: IE seems to have mutable undefined, after all. I used kangax tables for desktop browsers:[[BR]] \ http://kangax.github.io/es5-compat-table/ [[BR]] \ but they seem to be wrong about IE9. \ \ Anyway, the spec must be more complicated than what I anticipaded. The following code provides the same results in Chrome, Firefox, Opera & IE10 (IE9 results in [0, 1, ..., 7]): \ {{{ \ var results = []; \ \ var undefined = 0; \ results.push((function () { \ return undefined; \ })()); // => undefined \ \ var undefined = 1; \ results.push((function () { \ 'use strict'; \ return undefined; \ })()); // => undefined \ \ results.push((function ( undefined ) { \ return undefined; \ })( 2 )); // => 2 \ \ results.push((function ( undefined ) { \ 'use strict'; \ return undefined; \ })( 3 )); // => 3 \ \ results.push((function () { \ var undefined = 4; \ return undefined; \ })()); // => 4 \ \ results.push((function () { \ 'use strict'; \ var undefined = 5; \ return undefined; \ })()); // => 5 \ \ results.push((function () { \ undefined = 6; \ return undefined; \ })()); // => 6 \ \ results.push((function () { \ 'use strict'; \ try { \ undefined = 7; \ return undefined; \ } catch (e) { \ return e; \ } \ })()); // => TypeError \ \ results; // [undefined, undefined, 2, 3, 4, 5, undefined, TypeError] \ }}} \ 1365610172997718
_comment1: IE seems to have mutable undefined, after all. I used kangax tables for desktop browsers:[[BR]] \ http://kangax.github.io/es5-compat-table/ [[BR]] \ but they seem to be wrong about IE9. \ \ Anyway, the spec must be more complicated than what I anticipaded. The following code provides the same results in Chrome, Firefox, Opera & IE10 (IE9 results in [0, 1, ..., 7]): \ {{{ \ (function ( undefined ) { \ console.log('0: ' + undefined); \ })( 0 ); // => 0 \ \ (function ( undefined ) { \ 'use strict'; \ console.log('1: ' + undefined); \ })( 1 ); // => 1 \ \ (function () { \ undefined = 2; \ console.log('2: ' + undefined); \ })(); // => 2 \ \ (function () { \ 'use strict'; \ try { \ undefined = 3; \ console.log('3: ' + undefined); \ } catch (e) { \ console.log('3: ' + e); \ } \ })(); // => TypeError \ \ (function () { \ var undefined = 4; \ console.log('4: ' + undefined); \ })(); // => 4 \ \ (function () { \ 'use strict'; \ var undefined = 5; \ console.log('5: ' + undefined); \ })(); // => 5 \ \ var undefined = 6; \ (function () { \ console.log('6: ' + undefined); \ })(); // => undefined \ \ var undefined = 7; \ (function () { \ 'use strict'; \ console.log('7: ' + undefined); \ })(); // => undefined \ }}} \ 1365610228649899

IE seems to have mutable undefined, after all. I used kangax tables for desktop browsers:

http://kangax.github.io/es5-compat-table/

but they seem to be wrong about IE9.

Anyway, the spec must be more complicated than what I anticipaded. The following code provides the same results in Chrome, Firefox, Opera & IE10 (IE9 results in [0, 1, ..., 7]):

(function ( undefined ) {
	console.log( '0: ' + undefined );
})( 0 ); // => 0

(function ( undefined ) {
	'use strict';
	console.log( '1: ' + undefined );
})( 1 ); // => 1

(function () {
	undefined = 2;
	console.log( '2: ' + undefined );
})(); // => 2

(function () {
	'use strict';
	try {
		undefined = 3;
		console.log( '3: ' + undefined );
	} catch (e) {
		console.log( '3: ' + e );
	}
})(); // => TypeError

(function () {
	var undefined = 4;
	console.log( '4: ' + undefined );
})(); // => 4

(function () {
	'use strict';
	var undefined = 5;
	console.log( '5: ' + undefined );
})(); // => 5

var undefined = 6;
(function () {
	console.log( '6: ' + undefined );
})(); // => undefined

var undefined = 7;
(function () {
	'use strict';
	console.log( '7: ' + undefined );
})(); // => undefined

Changed April 10, 2013 04:13PM UTC by m_gol comment:7

On jsFiddle every browser behaves like IE9, though...

http://jsfiddle.net/m_gol/3KrZW/2/

Changed April 10, 2013 04:16PM UTC by dmethvin comment:8

On IRC, dcherman suggested just telling uglify to not compress undefined, which he says saves 40-something bytes. Not quite as much saved, but no downside.

Changed April 10, 2013 04:19PM UTC by m_gol comment:9

Yeah... I didn't suspect ES5's meaning of undefined is that you can't do undefined = 'a' but you can do var undefined = 'a'. Sooo helpful...

Changed April 10, 2013 06:45PM UTC by m_gol comment:10

description: According to ES5.1, `undefined` is immutable. All supported in 2.0 browsers besides Android <4.1 (including iOS 5.1 and VERY old Safari) adhere to that. \ \ Removing `undefined` from the main IIFE parameters saves 62 bytes in the gzipped minified file. \ \ I'm putting it here for a discussion. If we decided to go for that, we also have to decide what to do about 1.xWe can compress better if we tell uglifyjs to not mangle undefined, as suggested by dcherman. \ \ '''----- ORIGINAL TEXT -----''' \ According to ES5.1, `undefined` is immutable. All supported in 2.0 browsers besides Android <4.1 (including iOS 5.1 and VERY old Safari) adhere to that. \ \ Removing `undefined` from the main IIFE parameters saves 62 bytes in the gzipped minified file. \ \ I'm putting it here for a discussion. If we decided to go for that, we also have to decide what to do about 1.x
summary: Remove undefined from the main IIFE parametersBetter undefined gzip compression

Changed April 10, 2013 06:49PM UTC by m_gol comment:11

owner: → m_gol
status: openassigned

Changed April 14, 2013 10:44PM UTC by m_gol comment:12

description: We can compress better if we tell uglifyjs to not mangle undefined, as suggested by dcherman. \ \ '''----- ORIGINAL TEXT -----''' \ According to ES5.1, `undefined` is immutable. All supported in 2.0 browsers besides Android <4.1 (including iOS 5.1 and VERY old Safari) adhere to that. \ \ Removing `undefined` from the main IIFE parameters saves 62 bytes in the gzipped minified file. \ \ I'm putting it here for a discussion. If we decided to go for that, we also have to decide what to do about 1.xWe can compress better if we tell uglifyjs to not mangle undefined, as suggested by dcherman. \ \ '''----- ORIGINAL TEXT -----'''[[BR]] \ According to ES5.1, `undefined` is immutable. All supported in 2.0 browsers besides Android <4.1 (including iOS 5.1 and VERY old Safari) adhere to that. \ \ Removing `undefined` from the main IIFE parameters saves 62 bytes in the gzipped minified file. \ \ I'm putting it here for a discussion. If we decided to go for that, we also have to decide what to do about 1.x

Changed April 15, 2013 04:49PM UTC by Michał Gołębiowski comment:13

resolution: → fixed
status: assignedclosed

Tell uglifyjs to not mangle undefined; saves 44 bytes. Fixes #13759. Close gh-1239.

Changeset: 8576e24bfe3fce886bcb63ebc24ee16b3fa1a6a1

Changed April 15, 2013 05:04PM UTC by m_gol comment:14

BTW, orkel was right, this change actually increases the gzipped 1.x-master size so it makes sense only on master.