Ruby on Rails | Screencasts | Download | Documentation | Weblog | Community | Source

Ticket #4729 (closed defect: wontfix)

Opened 3 years ago

Last modified 3 years ago

[PATCH] Make Prototype js-packer compatible

Reported by: daniel@jagszent.de Assigned to: sam
Priority: normal Milestone:
Component: Prototype Version:
Severity: normal Keywords:
Cc:

Description

Prototype is cool but it's a little bit big. I tried to compress it with e.g. Dean Edwards Javascript Packer, but unfortunally there are some missing semicolons in the code. E.g. if you compress the following code with just removing unnecssary whitespaces and newlines

var x = function () {
  doX();
}
var y;

following will come out

var x=function(){doX;}var y;

As you can see, we are missing a semicolon after the function declaration. Normally that does not matter because an ECMA interpreter automatically adds those semicolons if it expects a semicolon and finds a newline.

To cut a long story short, the attached diff adds those missing semicolons to Prototype 1.5.0_rc0 so that you can squeeze it to 1/4 of its original size.

Attachments

added-missing-semicolons.diff (17.4 kB) - added by daniel@jagszent.de on 04/14/06 01:20:39.

Change History

04/14/06 01:20:39 changed by daniel@jagszent.de

  • attachment added-missing-semicolons.diff added.

04/14/06 04:22:46 changed by devslashnull@gmail.com

  • status changed from new to closed.
  • resolution set to wontfix.

It has been suggested before that something like this should be done (see #4191). Thomas' argument against it in that ticket was that it adds complexity and makes the code harder to debug should the need arise. I agree with this assessment, especially considering that [4096] added gzip compression to the default lighttpd.conf file (which you're doing in Apache or whatever too, right?).

Doing gzip compression cuts down prototype_1.5.0_rc0 from 55,237 bytes to 12,516, or about 22.6% of its original size. The advantage here is that it's automated, there is no chance of malformed javascript, and the code is easier to read on the client side (for when you need to debug it).

I personally don't think this is such a big deal as to warrant the problems that will occur when patches that are not packer-friendly are committed, as they inevitably will. But that's just me. Feel free to reopen if you can prove me wrong.

04/14/06 08:40:56 changed by Martin Bialasinski

Packing additionally to gzipping makes a difference (if one does not mind the "harder to debug" drawback), and the submitter does not want prototype to be packed by default. He just wants the Prototype code to be in a state that it can be packed if one wants to.

The problem arises with Dean's packer, because it works with the script source text.

I for one use jscompact, which accesses the parse tree by embedding the Mozilla script engine and therefore does not care about the missing (optional) semicolons. Maybe the submitter can use jscompact as well?

My results:

61571 prototype.js
14199 prototype.js.gz -> 23% of original size

47684 prototype.packed.js -> 77% of original size
10794 prototype.packed.js.gz -> 17% of original size, 76% of prototype.js.gz

04/14/06 16:45:03 changed by daniel@jagszent.de

The files are pre-gziped, content expiration settings are in place and several JavaScript files (Prototype, Behaviour and script.aculo.us) are combined to one big one. I just want the JS libraries to be as small as possible to minimize the initial loading time.

Thanks Martin for pointing me to jscompact. It doesn't really work with the

var func = function(arguments){var local;};

style of Prototype (doesn't compact the arguments and the local variables) but what it does is adding those optional semicolons automatically :) .

So after a

jscompact -pnal < prototype.js > prototype-semi-packed.js

Prototype doesn't look pretty anymore but is compact-able with a JS Packer like the one I mentioned above.

I'm totally fine with leaving this ticket closed wontfix. Thanks to Martin and jscompact I have now an easy way to squeeze Prototype, Behaviour and script.aculo.us from combined 170 KB to 26 KB.

To make the code better debugable, I use something like this:

if (window.location.search == "?debug")
{
	document.write('<script type="text/javascript" src="/js/prototype.js.gz"></script>');
	document.write('<script type="text/javascript" src="/js/behaviour.js.gz"></script>');
	document.write('<script type="text/javascript" src="/js/scriptaculous.js.gz"></script>');
} else {
	/* packed version of prototype.js and behaviour.js and all scriptaculous scripts */
	eval(function(p,a,c,k,e,d){/*...*/});
}

PS: I do have to change Prototype to make it 100% compatible with with Dean Edwards JS Packer - but that's probably a defect of this packer:

change

HTMLElement.prototype = document.createElement('div').__proto__;

to

eval('HTMLElement.prototype=document.createElement("div").__proto__;');