Lately I’ve been working a lot with ExtJS and I thought it’s good to share my experience. In this post I will explain how you can achieve object orientation with the help of ExtJS Core, how easy it can be and some of its pitfalls. Read the rest of this entry »
JavaScript is evolving, and together with it, its ecosystem.
Google has launched a fantastic JavaScript “compiler” – Google Closure Compiler. The name is misleading, but the tool is great. This stands behind the famous apps from Google, like GMail, Google Maps, etc. Well, let’s see this in action.
What the compiler does is to minimize and obfuscate your JavaScript code. It has three levels of optimization: whitespace only, simple and advanced. There is nothing special about the whitespace only optimization. It’s clear what it does so let’s analyze a bit the other options! In this post I will introduce the simple optimizations option, and in a later post I will write an explanation about the advanced optimizations level.
Simple Optimization Level
This is the level you should play with first. It minimizes your code and also obfuscates it. Nothing new to this point. The good news is it also optimizes it and removes unreachable code or unused code.
// say we have this code... sayHi doesn't appear to be very useful
function hello(name) {
function sayHi(){
return "hi"
}
alert(name);
}
hello('New user');
After “compilation” the code becomes:
function hello(a){alert(a)}hello("New user");
Notice the name of the global hello function remained unchanged. This is good as this is our external API, and we don’t want to break it. Closure Compiler also renames parameters, local methods and identifiers. The name parameter has been renamed to a, and notice the unused sayHi method was removed.
Let’s see other samples as well:
function hello(name) {
function sayHi(){
return "hi"
}
return "greetings";
alert(name);
}
hello('New user');
has been compiled to
function hello(){return"greetings"}hello("New user");
//with one warning (not part of the generated code):
//JSC_UNREACHABLE_CODE: unreachable code at line 8 character 2
// alert(name);
// ^
Wowww… that’s impressive. Notice the parameter to the hello method has been removed, as it is unused!
But what really got me is the “compilation” step. After all the name is not that misleading. Look at this
function hello(){
alert('hello world'
}
Well.. it’s obvious. But try and put that in your browser, and it will break your coolest app. You can avoid that with Google Closure. Here is the result:
Number of errors: 2 JSC_PARSE_ERROR: Parse error. missing ) after argument list at line 4 character 1 JSC_PARSE_ERROR: Parse error. missing } after function body at line 4 character 1
Maybe this is one of the best parts of this “compiler”.
I have tried some tests with the Google Compiler against some libraries. Here are the results:
| Library | Library normal minified size | Library minified size with Google Closure |
|---|---|---|
| jQuery | 55.9 KB | 54 KB |
| ExtJS Core | 78.9 KB | 74 KB |
I though the results would be significantly better with ‘closure’, but you can see the difference is not that big. ExtJS uses YUICompressor for minification and obfuscation. Maybe so does jQuery. So you can still use YUICompressor confidently. It would just be interesting to test on code which is badly written, with many unreachable statements and unoptimized.
I have done the tests with jQuery and ExtJS using the compiler.jar Google offers. Simply run the compiler from command line on the library files, which have to be previously annotated with the following comments at the beginning of the files (these comments tell Google Compiler how to make the compilation):
// ==ClosureCompiler== // @compilation_level SIMPLE_OPTIMIZATIONS // ==/ClosureCompiler==
java -jar compiler.jar --js=ext-core-debug.js --js_output_file=ext-core.pack.js
You can also use the webapp UI Google offers at Google Closure Compiler Home.
I’ll come up with more details about the ADVANCED_OPTIMIZATIONS compilation in a later post.
Successful compilations!
>
I have developed a small utility library, which helps with managing logging of your JavaScript applications.
Here are some features it supports:
- Turn logging on and off
- Support for Firebug console and log4javascript
- Redefine console.log, console.warn, … (all console logging methods) through methods from log4javascript, if console is not detected
All you have to do is to keep on logging with firebug just as you did before! The problem occurs when you want to debug n a browser that doesn’t have Firebug enabled! Well, that should be no problem! Just include jslog.js and log4javascript-1.4.1.js and all logging that goes through console.log will now appear to the popup window log4javascript creates!
So jslog.js is a nice utility which allows you to work with two logging strategies, but using a single API, which you already know, the Firebug console
Another facility is disabling logging – in one single line! This is especially useful when going live! You don’t want to go through all your code and modify it! Use jslog.logging.init(false)
A small tutorial.
Include <script type=”text/javascript” src=”jslog.js”></script>
jslog.logging.init(true);
console.log('hello','this will be logged');
jslog.logging.init(false);
console.warn('sorry...','this log will not appear');
When you want to log in non-firebug environments, just include the following in your html file:
<script type=”text/javascript” src=”log4javascript.js”></script>
<script type=”text/javascript” src=”jslog.js”></script>
//You don't have to change your code.
//if jslog.js detects no console to be available,
//it creates one and redirects logging to log4javascript
jslog.logging.init(true);
console.log('hello','this will be logged');
jslog.logging.setEnabled(false);
console.warn('sorry...','this log will not appear');
If log4javascript.js is not included in the page and no Firebug console is detected, jslog will detect this and will just be silent, even if logging is enabled. It will not throw an error!
So…. happy logging! For questions and support, contact me!
Credits to Tim Down for his awesome log4javascript library!
What is really fascinating about JavaScript is it’s dynamic nature. You can dynamically change the behaviour of the code… even not your code. While this is really powerful, it can be also a pain if not used with care.
Well, let’s do something practical now. I want to intercept every log message in my js application. As people usually use Firebug (and if you’re not using it… well, you should, so start right here), the javascript code is populated with console.log or console.warn messages. Say we want to execute a function before and after console.log is called. Test the following code within firebug.
var backup = console.log;
function beforeLog(){
backup('before log:',arguments);
}
function afterLog(){
backup('after log:',arguments);
}
console.log = function(){
beforeLog.apply(this,arguments);
backup.apply(this,arguments);
afterLog.apply(this,arguments);
}
console.log('hello','world');
In the first place, make a backup to the function we want to intercept.
Second, just redefine the function… and we usually want to execute the old function (so here is where we need the backup) and perform some additional things as well. Placing the code at the beginning of your coolest app changes the behaviour of all the log messages you have.
I found this useful when going from a development environment to a live environment. The best choice would be to use a build system to comment out (or even better, delete) all the console.log() calls. But a quick fix when going live is the following:
if (!window.console){
/*
* for users who do not have firebug installed,
* just define a "mock" console object
*/
window.console = {};
}
window.console.log = function(){};
console.log('hello world'); // call to an empty function
This is just a simple use of dynamically changing the behaviour of existing code. What about you? How do you intercept function calls? Waiting for some nice suggestions.
console.log('jslog.com')