My JavaScript book is out! Don't miss the opportunity to upgrade your beginner or average dev skills.
Showing posts with label CSS. Show all posts
Showing posts with label CSS. Show all posts

Monday, November 21, 2011

Differential Background Scrolling

A quick one about this technique quite common in Flash sites but rarely seen on Web.
Have a look at the example first so you can understand what I am talking about ... got it ?

What Is This About

Let's say we have a background, a big massive graphic background surely not suitable for mobile phones, due data roaming, but maybe cool for desktop and fast ADSL.
The background-size CSS property is able to let us decide if the image used as background should fit the whole element or only a portion of it.
In this case the image should fit, by default, the whole height of the document with an auto width in order to let the browser adjust the scale.
A differential scrolling is visible the moment we scroll the page ... please resize the window into a smaller one if you are in an HD monitor and start scrolling the page.
At the very beginning, the default height of the image is 100%, as body background, and with some padding in order to let space for few important image parts such the header, with clouds and enough space for a H1 tag, and the bottom, with the stylish logo of this game from elderscrolls.com, the one which page inspired this little experiment. Bear in mind no code has been even read from that website ... I have seen the effect, I have used it many times ages ago via ActionScript, I decided to do something similar for most advanced browsers, and here is ...

The Code


(function (document) {
// (C) WebReflection - Mit Style Licence
var
ratio = .85, // 0 to 1 where 1 is 100%

// shortcuts
styleSheets = document.styleSheets,
documentElement = document.documentElement,
ceil = Math.ceil,
scroll = "scroll",
scrollHeight = scroll + "Height",
scrollTop = scroll + "Top",
body, sHeight, sTop, y, last
;
styleSheets = styleSheets[styleSheets.length - 1];
// redefine the rule for the height
styleSheets.insertRule(
"body{background-size:auto " + ceil(
ratio * 100
) + "%;}",
styleSheets.cssRules.length
);
// get the rest of the ratio
ratio = 1 - ratio;
// attach a scroll listener
addEventListener(scroll, function (e) {
if (body || (body = document.body)) {
sHeight = documentElement[scrollHeight] ||
body[scrollHeight];
sTop = documentElement[scrollTop] ||
body[scrollTop];
y = ceil(
ratio * sHeight * sTop / (sHeight - innerHeight)
);
// this avoid some redundant assignment
// hopefully creating less flicking effect
if (last != y) {
body.style.backgroundPosition = "center " + (last = y) + "px";
}
}
}, false);
// you may want to try this for Chrome Browsers
//documentElement.style.WebkitTransform = "translateZ(0)";
}(document));


The Problem

Many of them ... to start with the fact this technique does not scale as showed in this example since for mobile phones, or generally speaking smaller screens, it does not make sense to use such big image: use media queries for this.
Opera 12 is almost there but something goes terribly wrong during background reposition ... it's screwed up by N pixels even if the rest of the logic works and no error is shown on console.
Firefox Nightly goes quite well but it is still flicking a bit while Safari, and even better WebKit Nightly, are the smoothest in this Mac.
The disaster is Chrome Canary, which is not able to handle this background repositioning.
You can see the effect if you scroll fast in both inspiration site and my experiment and, as commented out in the code, the only way to make it better is to force HW acceleration in the whole document 'cause in the body only the background looks broken ... it's really cool to see how DOM is able to mess up with GPUs, isn't it?

As Summary

Nothing much to add to this post, it was just a quick example over a cool effect but as it is, since ever, in this Web field, almost everything went terribly wrong :D
Have fun with CSS and graceful JS enhancements!

Monday, September 21, 2009

CSS Position Fixed Solution

Who does not know CSS 2.1? ... silence (maybe) ...
Good, so who does not know the CSS 2.1 position property? ... silence (still maybe though) ...

Excellent! Finally, who would like to use in a lightweight, cross-browser, unobtrusive way, without JavaScript dependencies, the property fixed? ... silence again, but this time I can spot a different expression in your face ...


Common Browsers With position:fixed Support

  • Chrome
  • Firefox
  • Internet Explorer 7 and 8 but NOT in quirks mode
  • Opera
  • Safari


Common Browsers WithOut position:fixed Support

  • Internet Explorer 6
  • Internet Explorer 7 and 8 in quirks mode
  • WebKit for Android
  • WebKit for iPhone


To Quirks Or Not To Quirks

For backward compatibility reasons IE let developers choose between two box models ... Our loved bloody 64 years* old browser Internet Explorer 6 has never supported such property while both Internet Explorer 7 and 8 do nt support it if we are in quirks mode, a modality tendentiously dead thanks to new simple HTML 5 doctype declaration: <!DOCTYPE html>.
To solve this issue I have created a dedicated file to include via conditional comments which includes a set of "never before that useful" expressions.

Why Expressions

CSS expressions are compatible, so far, only with Microsoft IE browser and they are totally alien for both other browsers and developers. The reason I am saying that is because they are completely unpredictable: it is not possible to easily understand or to predict when expressions will be executed, where, and how!
Technically speaking, being expressions dedicated for CSS hacks, their executions will be performed at least every time the element is somehow involved, and to make it involved, we need to touch some property in order to make expression useful (in this solution case the property offsetHeight of the current node).

The Direct Example

Here we have two pages: the standard or strict mode and the quirks one.
As you can test via your favorite browsers, there are always 5 elements in that page, a top div, a center one, a bottom one, and two divs one left and one right, above and over the center one.

How Does It Work

It is very simple, consider these CSS classes:

/** A WebReflection Solution */
.position-fixed-top {
position:fixed !important;
top: 0;
}
.position-fixed-center {
position:fixed !important;
top: 50%;
}
.position-fixed-bottom {
position:fixed !important;
bottom:0;
}

Hopefully choose name are semantic enough, so it's quite clear that these classes aim is only to position elements, and nothing else, in order to be able to add other classes for whatever other property, zIndex if necessary included.
Choose classes are about most common usage of fixed elements in a page, top, center, or bottom, and adjusting positions or margins it is really simple to put the element in whatever part of the page starting from the bottom, from the top, or the left.
To let the magic be in Internet Explorer 6 and others in quirks mode, these classes are completely replaced, as you can read in IE dedicated file.
Being the IE solution based on CSS expressions, there should not be anything better or quicker than that, render time and call speaking, same should be for memory leaks, timers, and whatever strategy we have adopted 'till now (but of course if there is something better please share!).

Android & iPhone - Not Worth It

These mobile devices implement a stunning browser as dedicated WebKit is, able to render faster than IE8, for example, my last Liquid FX, based on 1 image, and one div, that's it! (congrats IE8 for stretched images rendering time! 7, 6, and 5.5. are much better) ... uh, wait, it's not about IE ...
Android and iPhone have both a great CSS 2.1 support, and even some CSS 3. Unfortunately the position fixed does not work as expected. To fix it I have tried different scripts failing each time. The reason is quite simple: both Android and iPhone block timers or render during scroll, so the effect is that divs move with the scrolled page and only after, eventually, divs come back in the expected position. This is against position fixed idea, and having a truly small screen we should ask our self if it makes sense to cover precious pixels with something fixed there.
It does not matter, as soon as I'll be able to test an iPhone I will continue to optimize my script in order to make the position fixed property usable somehow with mobile devices as well ( center right or center left could be interesting, bottom or top bar quite intrusive for user and/or zooming features ).

How To Implement My Solution

It's simple, if we are in a quirks page, we should include the CSS hacked file after the normal one, and for every IE:

<link rel="stylesheet" type="text/css" href="position-fixed.css" />
<!--[if IE]>
<link rel="stylesheet" type="text/css" href="position-fixed.IE.css" />
<![endif]-->

While for every standard or strict web page we can include the hack only for IE less than version 7:

<link rel="stylesheet" type="text/css" href="position-fixed.css" />
<!--[if lt IE 7]>
<link rel="stylesheet" type="text/css" href="position-fixed.IE.css?444" />
<![endif]-->

I can spot a new expression in your face, isn't it?


* if we multiply per 7 dogs age, I think it is reasonable to say that in IT each year could be multiplied for 8

Friday, September 04, 2009

@font-face we are already doing wrong

Update - Now We Do Right

Thanks everybody for your tests and contributions. For those interested about why we were doing wrong please read both post and comments but for those just interested about the best way so far to serve correctly one or more font-face, this is the hack:

@font-face {
// define the font name to use later as font-family
font-family: "uni05_53";
// define the font for IE which totally ignores local() directive
src: url(../font/uni05/uni05_53.eot);
// use local to let IE jump this line and
// redefine the src for this font in order to let
// other clever browser download *only* this font rather than 2
src: local("uni05_53"), url(../font/uni05/uni05_53.ttf) format("truetype");
}

You can test directly this technique in my HTML5 Prime Directives Test Page



Credits

  • Paul Irish for its Bulletproof @font-face syntax

  • Mikuso, comments, for his suggestions about server configurations, instantly followed by Weston Ruter for its excellent article Efficiently Serving Custom Web Fonts

  • last, but not least, Scott Kimler, for his Better @font-face Syntax and his patience, testing directly inside a trace log, rather than trust 100% Fiddler or Firebug - P.S. my hat is off for that page, unfortunatly you have trolls problems as well, reading the first comment from somebody that got -1% of what you have done!
Links, snippets, tests, we have got everything we need to understand why font-face CSS plus file serving has been generally misunderstood and how we should do correctly, trolls included (the problem is not the browser).

Good Stuff!
Just last quick info for Scott Kimler, IE simply lacks "local" directive support, and this is the reason it ignores the second call.
If we put local(fontName), url(fontName.eot) it will not load the eot, neither the ttf - local is the key for this trick, but we'll have problems the day IE will understand local, unless the first src will not considered synchronous.
Hopefully, that day IE will support ttf since windows does already without problems.


Few weeks with new browsers and @font-face support that suddenly everybody started to suggest the "cross browser way" to include them ... which is 90% of cases apparently wrong.

The Wrong Way



/* IE first */
@font-face {
font-family: nomeDelFont;
src: url( /nomeDelFont.eot );
}

/* Firefox 3.5/Safari/Opera 10 */
/* but IE will download in any case */
@font-face {
font-family: nomeDelFont ;
src: url( nomeDelFont.ttf );
}

almost the equivalent showed here, via Ajaxian, and Edit ...

What Is Exactly Wrong


It does not matter if we use conditional comments, it does not matter if we put the right font for Internet Explorer before the other one (tricky, since IE does not overwrite the rule just because it does not understand the truetype format).

Our "favorite" browser, and others as well in some case, will always request the truetype as well, and being fonts not that lightweight, our page response could sensibly increase.

HTML5 Prime Directives


Inspired by RoboCop, I have created a simple test page that does not suffer the problem described before.
What we have there is an extremely compact and valid HTML5 page which size is up to 140Kb, and almost 67Kb just for the font.

Plus, as I've said, If we use common suggested snippets Internet Explorer will download in any case the non IE font, try yourself!

First Suggestions To Try To Solve The Problem



  1. never forget to specify the format, format("truetype"), which is apparently able to let IE misunderstand correctly the url and the result is a Error 404, still better than 70Kb to download

  2. moreover, use whatever strategy you know to avoid non IE file serving for IE as well (use Fiddler to monitor the network)

  3. try to create gzipped or deflated version of each font, possibly not runtime, and serve them via proper headers (69Kb down to 22Kb, as example, with 7Zip deflate)

  4. please tell us how you avoided IE wrong font download without using an horrible JavaScript document.write as I did in my little test page


Thanks, and I hope you agree about Prime Directives :D

Monday, July 27, 2009

back in town with a little CSS present

Hi everybody! I am definitively back in London: completely tanned, thanks to Ancona holidays, but right now under the rain (OK, in this second it's sunny here...)

This is a quick "here I am again" but with a simple and little present:

Easy CSS Reset Creator


Sometimes we need to reset CSS to be sure that our document will be clear and hopefully equal for each browser, respecting our rules rather than browsers default.
To better understand what I am talking about, please have a look into this Eric A. and Kathryn S. Meyer page, the basis used to create my simple tool.

What Eric did not think about, is that thanks to Web 2.0 injections and flexibilities, it could be useful to reset a single node and everything contained rather than a full document, specially when we need quick improvements or our cool widget/gadget to add somewhere in the page without an iframe or inherited rules.

So, this is the page able to create the CSS you need with or without a parent rule.

If you need a parent container you can simply use a query string like
http://www.3site.eu/css.reset.php?parent=.myelement

Obviously you can add more complex rules like
?parent=table.test td.last
or, if you need an id, a dollar character rather than a sharp one:
?parent=$myid

where $myid will be converted into #myid

Please note that my host is not that expensive so it cannot handle hundreds f requestes (copy and paste or download the resulted CSS rather than use it directly as link source)

I guess that's it, and see you soon ;)

Sunday, July 05, 2009

YUI Compressor Meets The Batch Scripting

Mainly to work, also to investigate some good old DOS feature, I created a batch file able to make YUI Compressor more portable and easy for every Windows based client/server developer.
I wrote the story, and I described each file, plus I added a workable Zip with everything you need to understand what I have created and use it, starting with a double click into a projects/vice-versa.bat file which aim is to create from a list of files a unique YUI Compressed one.
Here is the link, the rest is up to you (comments, questions, suggestions, etc)

Thursday, April 30, 2009

vice-versa sub project: css2xpath

Update

I completely re-wrote the test suite. You can check a live example here where results are compared with Sizzle selector engine against the common W3C page.



After this Ajaxian post and some opinion exchange in its comments, I decided to extract the css2xpath function I used inside experiments in vice-versa project, creating a separated project specific for this purpose that some how could be interesting or useful.
Bugs, problems, questions, and helps are more than welcome, so far I focused my attention to SlickSpeed test selectors and nothing else but at least for that it seems to be stable and reliable.

Tuesday, April 28, 2009

The Fastest Selector Engine For FireFox 3.0 ?

I am putting some effort to make vice-versa project a good, production ready, alternative against common libraries, and since these days I am working hard with XML, XSL(T), and XPath I decided to try an experiment implementing CSS to XPath translator for FireFox 3.0



With version 3.1 we will have querySelector and querySelectorAll but version 3.0 is still the most used one, FireFox speaking!

The nightly build of vice-versa introduces a new file, mainly used for personal experiments via vice-versa library and the first experiment is an improved document.query for those browsers with document.evaluate support without document.querySelectorAll.
Unfortunately Internet Explorer < 8 does not support XPath queries over (x)HTML but at least for FireFox 3.0 I have obtained best overall performances via SlickSpeed Selector Speed Test comparing latest version of each library such Dojo, DOMAssistant, Sizzle (congrats for the new site!), Sly, and finally vice-versa project.
Here the summary, from faster to slower:

vice-versa 760ms
Dojo 1.3.1 868ms (2 tests failed)
DOMAssistant 880ms (good stuff Robert!)
Sly 890ms
Sizzle 914ms

Now, the good part is that nowadays every selector engine seems to perform truly fast and in whatever browser you like, but the "even better" part is that the experiments file in vice-versa is 1Kb (minified and gzipped) and with just "that Kb" it is possible to use a specific and fast selector engine for FireFox 3.0.

Finally, the experimental CSS to XPath translator cannot support pseudo searches like :hover, :active, or similar, due to the XPath nature, a query language mainly designed for XML where CSS, unless we do not transform it via XSLT, has a complete different meaning from the one used in (x)HTML.

I wonder now who will be able to create better overall performances for FireFox 3.0 ( changing my translator implementation, for example ;) )

Monday, March 31, 2008

Bases, merits, and defects of packed code

How many times we have seen an included JavaScript apparently incomprehensible?
These examples could explain better what I mean:
packed.it via MyMin

eval((function(M,i,n){return '0("1");'.replace(/\w+/g,function(m){return (n[m]!=i[m]&&i[m])||(i[m]=M[parseInt(m,36)])})})('alert.test'.split('.'),{},Object.prototype))


Dean Edwards packer

eval(function(p,a,c,k,e,d){e=function(c){return c};if(!''.replace(/^/,String)){while(c--)d[c]=k[c]||c;k=[(function(e){return d[e]})];e=(function(){return'\w+'});c=1};while(c--)if(k[c])p=p.replace(new RegExp('\b'+e(c)+'\b','g'),k[c]);return p}('1('0');',2,2,'test|alert'.split('|'),0,{}))


These are only two parsers which aim is to reduce code size using an inline decompression technique that is able to evaluate source code after common keywords replacement.


Basis of portable and packed code


The main goal of these services is to compress a source reducing occurrences of repeated words, using different technique to create both compressed string and inline function with decompression algo.
In this paragraph we will see a rudimentary example on how can be possible to create our own compressor. Let's go with the first function:

function pack(code, keywords){

var re = /\w+/g,
filter = {},
key;

// foreach word or number in string
while(key = re.exec(code))
// make found one unique
// if does not exists it creates them
// otherwise it overwrite them
filter[key[0]] = 0;
// for example, if code is "a b a", filter
// will contain only two properties, a and b
// with value 0 for both of them

// with found list of unique words or numbers
for(key in filter)
// avoid inherited Object.prototype parameters or methods
if(filter.hasOwnProperty(key))
// add key to array
// save into filter key position in the array
// converting them into base 36 string
filter[key] = (keywords.push(key) - 1).toString(36);
// for example, if code is "a b a", filter.a value will be 0, and filter.b will be 1

// for each word or number
// return keyword index in base 36 format
return code.replace(re, function(key){
return filter[key];
// for example, if code is "a b a"
// returned code will be "0 1 0"
});
};


var myCode = 'alert("this alert will show this text");',
myKeywords = [],
packed = pack(myCode, myKeywords);
alert(packed); // 0("1 0 2 3 1 4");

Reading comments, we can understand the logic behind a client side based compressor.
And since compression operation follows usually a "one to many" logic, where one is the operation to compress, and many are clients that will decompress code, more simple and fast will be the decompression operation, more powerful, portable, and compatible will be our algorithm.

function unpack(code, keywords){

// foreach word or number
return code.replace(/\w+/g, function(key){
// return related keywords value
// converting base 36 string into
// base 10 index
return keywords[parseInt(key, 36)];
// for example, if code is "0 1 0"
// returned string will be like
// keywords[0] + " " + keywords[1] + " " + keywords[0]
});
};

(unpack(packed, myKeywords) === myCode); // true

The last ring of our chain, is a function that is able to create automatically final result code:

function portablePack(code){
var
// keywords container
keywords = [],

// packed version of the code
packed = pack(code, keywords),

// object to make returned string evaluable
safe = {"'":"\\'", "\\":"\\\\", "\n":"\\n", "\r":"\\r"};

// to solve problems with some special char inside the string
// make packed result more safe replacing chars using safe object keys values
packed = packed.replace(/'|\\|\n|\r/g, function(match){
return safe[match];
});

// return an evaluable string
return "eval((function(p,l){return p.replace(/\\w+/g,function(k){return l[parseInt(k,36)]})})('" + packed + "','" + keywords.join(".") + "'.split('.')))";

// created string has to contain an inline function
// that should be able to return original code
// to eval function. Created string will be
// something like
// eval((function(packedString,keywords){return unpack(packedString,keywords)})("packed string", "key.words.list".split(".")))
};

This is our first home made client side compression example, not really so efficient, but good enough to understand the logic behind.


Merits of client side compression technique


It simply does not necessary require server side operations to optimize the result size of our scripts, that are every day more than ever "thanks" to the Web 2.0 era.
Required bandwidth will be less than before, while download speed will be increased, and more code we pack, more possibilities we have that ratio between source and packed code will be greater, thanks to common names for common tasks programming routines.


Defects of packed code


Nowadays, quite every browser supports gzip or deflate runtime decompression.
These compression algorithms are really efficient thanks to decompression speed, 10 to 100 faster than pure JavaScript operations plus evaluation, and thanks to their support provided by every server side program language.
Every time we download a client side packed code, even if file will be saved in browser cache, it has to be executed every time we will visit that page again.
So, if our goal is to increase page interaction speed during navigation, JavaScript decompression delay will be a problem.
If this problem will be hilarious or heavy, it depends only on client hardware and its browser performances.
At the same time, using a gzip or deflate compression over a packed code, will not truly increase performances and result will be bigger than clear code gzip compression.

The reason is that common compression algorithms create compressed code using a dictionary that will contain common, repeated, words or letters, found in original string.

Since JavaScript compressors usually replace numbers or words with a unique identfier to be able to recreate original string, resulted string will contain much more characters pairs than before and every baseN encoded key, that is not human friendly and for this reason rarely wrote in original code, could be one more byte inside final compressed string.

Finally, client side compressors are not, usually, 100% compatible with every kind of code, and this is another reason to prefer minifiers + gzip|deflate to obtain the best, fastest, and finally smallest, result.


Conclusion


Nowadays, pure JavaScript client side runtime decompression technique is not really a necessary, but in some case, it could do things that gzip or deflate will never be able to do, for example merging both JavaScript and CSS using a single and common keywords list to produce a unique file that could contain both JavaScript and CSS with the best size result requiring only 1 download instead of 2 (1 for JavaScript, 1 for CSS). That is what packed.it is able to do since 2007, but never forget speed issue and please remember that more great will be packed code, more delay there will be in every page that will use them.

Wednesday, February 20, 2008

packed.it goes off line !

... or, to be honest, that's what it's gonna do in few days, but PHP version is out!

You can find every information about server side version of packed it directly in this page.

I am not joking when I said that packed.it is probably the fastest optimized client files server you can find over the net, even with an uncompiled program language like PHP.

The key is the JOT compiler, compile one time, serve all the time without paranoia, saving bandwidth for both server and client, avoiding the usage of gz handlers, avoiding runtime compression, avoiding whathever you want, and finally, having the possibility to serve js, css, or both with a single file.

Discover by yourself how long server need to serve, for example, jQuery ... less than one millisecond without louds of requests ... please look at X-Served-In header, if you do not trust me :P

What's new? You do not need to pass in packed.it site to compile your projects, you can just serve and compile them directly from your one.

To Do:
Python PSP and SWGI version, C# version and finally, Jaxter version for server side JavaScript auto compilation in itself language ... does it sound good?

Enjoy packed.it, and please do not ignore totally PayPal Donation :D

Cheers

Wednesday, February 13, 2008

jQuery + jQuery UI + Full Flora Theme ... less than 32Kb

Don't You trust me? It's so diabolically simple with packed.it ... and more than a professional Web Developer complained about "why on heart noone talk about that service" :D

It's not packer, it's not YUICompressor, It's the only one that cache both CSS and JavaScript in a single file ... it's for PHP4, PHP5, Python wsgi, Python psp, C#.NET ... so, what are you waiting for?

Ok, I'll let you try this full package:
jQuery 1.2.3 and jQuery UI 1.5b with full Flora Theme included.

Enjoy ;)

P.S. jQueryUI.html example file calls jQueryUI.php, jut change estension in your server if you want python or .NET

Thursday, December 20, 2007

packed.it ... again online

I am sorry for last days while packed.it wasn't working as expected because of new server.
It seems to be faster than precedent one so thank you again Daniele , I'll write your link as soon as I can :-)

Enjoy both JavaScript and CSS compressed files in a single one, enjoy packed.it!

Monday, October 08, 2007

packed.it screencast ... (maybe) Yesss!!!

I didn't find a way to create a clean video, probably 450 pixels are not enought to show how does packed.it work?

However, I'll try to explain these two screencast.

First one - Ext JS Home Page - from 223Kb to 52Kb


This video shows a saved version of Ext JS Home Page.
This site uses a lot of external CSS, one imported and one in page but not every one is used by JavaScript disabled browsers.
Total CSS size is about 93,2Kb while 4 used JavaScript files size is about 130Kb.

With packed.it You can create a project using both CSS and JavaScript and the result will be a single file with total size of 52Kb, including both CSS and JavaScript.

I didn't add to project Google Analytics unrich.js file but this should be included without problems too saving other 15Kb.

As You can see (I hope), the result is even smaller on page, just three tags, using IE5 compatibility one, instead of 8 inside page ... these are few bytes less than original and layout is even more clean than ever.

CSS file dedicated only for JavaScript incompatible or disabled browsers is just 36Kb instead of 93 without optimization but as You know You could use packed.it to serve an optimized version of this file too (just change packed.it folder name to packed.css, for example, and change prefix inside automatic generator).




Prototype and Scriptaculous in less than a minute, from 230Kb to 38Kb



This second example just shows a JavaScript only project, Scriptaculous 1.7.1 beta 3 using prototype version 1.5.1
You just need to upload these sources and with a click You'll download full Scriptaculous enviroment, reducing size from 230Kb to 38Kb.

Using client compression too, every gzip or deflate incompatible browser will download about 90Kb instead of 230Kb, reducing bandwidth about 38% of original.

Sorry for missed audio and bad video quality, I'll try to do something better next time, ok? :-)

Saturday, October 06, 2007

new packed.it automatic content generator

packed.it service now creates archives with 3 types of automatic content generator: ASP.NET (C#), PHP (4 or 5) and Python (mod_python and psp or WSGI version).

These generators complete packed.it service and are usable with MyMin produced code too if You choose to manage your own projects by yourself.

Probably there will be future implementations (Java, Perl, Ruby), however today You can use packed.it to create optimized CSS and JavaScript for more than 80% of hosting solutions.

A special thanks to Cristian Carlesso for C# porting, He doesn't like my revision style so much ... but it works perfectly and it's more simple to mantain too (at least for me :D)

Have fun with packed.it :-)

Friday, October 05, 2007

MyMin project 1.0.1 available

I've just uploaded last version of MyMin project fixing only JSmin problems with regular expressions when it's not inside a closure, not after '{' or ';' allowing them to parse entire jQuery UI, for example, without problems.

This fix has been successfully tested on Python 2.5, PHP 5.2, C# 2 and JavaScript 1.3

You can find MyMin project description in this page while You can optimize CSS and JavaScript in a single file simply using my on-line packed.it service.

Have fun with optimizations and please feel free to post a comment if You find some bug using MyMin project, Thank You!

Thursday, October 04, 2007

A "little bastard" BUG using JSmin parsers

Update
It seems I found a valid fix for "strange" regular expressions. I suppose MyMin will be available tomorrow while packed.it has been just updated with last client version.

Have fun with packed.it and please tell me if some source cannot be parsed.





--------------------------------------
While I was testing every kind of source and CSS with my last creation, packed.it, I found a bug on JSmin logic, partially recoded inside MyMin project as JavaScript minifier (MyMinCSS and MyMinCompressor seem to work perfectly).

This bug seems to be present on every version linked in JSmin page.

I found this bug parsing jQuery UI + every CSS with my new service but one JavaScript file has one single, simple problem:

function(){return /reg exp with this ' char/;}


Bye bye JSmin, regexp will be parsed as string and an error will be raised.

The problem is reproducible just with a string that contains only this (so a source that begins and end with these 3 chars):

/'/

that's a normal regexp ... at this point I can be happy to found first packed.it and MyMin project bug and the coolest thing is that is inside a part of project that's not really mine :D

To solve this problem, just use
return new RegExp
or just asign reg to a var before return them ... it seems to be the only one bug I found parsing every kind of source. Did anyone solve them?

I know it's not so simple, just because a char by char parser cannot simply know if slash is for a division, a comment or a regexp.

Do You have any sugest to solve this problem? It will be really appreciated! :-)

Wednesday, October 03, 2007

Are You Ready To Pack ?

I'm pleased to announce my last revolutionary project called packed.it !

Just another minifier packer alternative ???


No guys! packed.it goals is to reduce using best practices both CSS and JavaScript sources in a single file.
You can write directly on JS area or in CSS one or upload one or more file, choosing which one should be executed before others.
Based on MyMin project, a personal revisit of JSmin plus a dedicated compressor and a CSS minifier for C#, JavaScript, PHP or Python languages, packed.it creates a project archive, in zip format, that will contain everything You need to server your files gzipped, deflated or clear for browsers or robots that does not support gz pages.


Not only JavaScript !


The innovative packed.it idea is to process both JavaScript and CSS to create a single project file just compiled to be served using gzip, deflate or clear text.
In this case your server will not need to do anything, just serve correct file verifying its sha1 summary to choose it browser need to download them or use them from its cache.
Any other JavaScript compressor system includes possibility to pack CSS too and the reason is really simple.

How many times You write CSS dedicated only for your client library?
How many times You use words such div, body, li, #some-id, float, width inside CSS using same words inside JavaScript too?
Think about document.body, var li, getElementsByTagName("div"), getElementById("some-id"), setStyle("width") and so on.

My personal compressor, inspired by fantastic Dean Edwards packer idea, creates a single list of keywords used inside both CSS and JavScript sources.

Its simple but efficient algorithm counts how many times one word is present inside merged sources, CSS + JavaScript, and orders them to put most common words at the begin of keywords list, moving before words with length bigger than others.

In few words, every word will be replaced inside source reducing its size from 30% to 60% and if browser is compatible with gzip or deflate, final size should be even less than 20% of original one.


Do You want to know more about MyMin ?


MyMin is originally based on JSmin C implementation but it was partially rewrote to be compatible with JavaScript conditional comments too (for example: /*@cc_on @*/ and //@cc_on) while MyMinCSS is a simply but powerful minifier dedicated only for CSS and totally wrote by myself.


Do You want to know more about MyMin Compressor ?


MyMin Compressor works with every kind of source. This mean that You don't need to respect any rule when You write your JS or CSS code just because it doesn't modify original output and result will be exactly the same.
Its also based on fastest decompression algorithm I could thought and sources parsed with this Compressor will be available quickly even using old computers.

Its decompression procedure is compatible with every recent browser (IE 5.5 or greater, FireFox 1 or greater, Safari 2 or greater, KDE 3 or greater, Opera 7 or greater, NetScape 6 or greater, others too!) and should be compatible with old browsers too just adding a little function like this one before decompression (required only with IE5 or lower).


Do You need something else to choose packed.it ?


I hope there's no reason to don't use packed.it service:

  • it's innovative

  • it's free

  • it's compatible with W3 validator and WatchFire too (WAI-AAA friendly)


Ok, I know, It's beta ... but it's just working so please tell me some question to create a useful F.A.Q. site section or tell me if something doesn't work as expected.

Regards, and have fun with Web 2.0 technologies !

P.S. I'm working to include a C# and Python variant to packed.it.php file (gzipped and deflated files just works with every language).
If You want to do it for me before I'll do that, please tell me and I'll put your credits in dedicated page, thank You :-)



Example using Ext (all both for JS and CSS)
ext-all.js + ex-all.css ... original size: 559.90 Kb
after packed.it conversion: one file, total size: 129.81 Kb :-)

Example using jQuery + jQuery UI + every CSS theme
From 260 Kb to 40Kb , about 15% :-)

Example using bytefx
From 18 Kb to 1.5 Kb , about 8% and Yessss, less than 2kb! :-)


Update
Please note that packed.it is beta and not totally debugged with different browsers.
However to be sure your JavaScript enabled browser is compatible with packed.it result projects just visit this page.

If You can read a text over a background #DDD body, Your browser is compatible with packed.it produced code.