Friday, November 23, 2012

Use itemId instead of id

What is Id and ItemId: Id and itemID both are the means of identifying a particular dom element from a list of dom elements. Whenever, we need to get the object of an element in ExtJs, we use Ext.getCmp(‘id’). The id must be unique in a class.
Difference between id and itemId: Although the purpose of id and itemId are same i.e. to get the reference of corresponding Dom element at run time, yet there is a very important difference between them. Id must be unique in a class and if it is repeated, then the screen, that displays the object of this class, will have more than one same id and thus resultant screen will be either distorted or will not behave as per expectation.
But, the scope of itemId is limited only to the container or object of the class in which it is being used. That is, if we define the same itemId in two different containers in the same class or same itemId present in two objects of a class, in both scenarios, screen will not be distorted and will behave as per expectation
Scenario:  Let us consider that there is a class that has a method that creates a panel object. This panel object contains a label and a button and on click of this button, we have to change the text of the label. We have to create such two panel objects and display it on html page.
First, we will do this by providing an id to this label and on click of this button we will get the reference of this label by queryById (‘id’) and will assign it new text. E.g.

    Ext.define('CustomClass',{
        config:{
            val:'This is testing',
            panelObj: {}
        },
        
        btnClickHandler: function (valob) {
            this.panelObj.queryById('labelId').setText('Value changed');
        },

        createPanel: function(){
            this.panelObj = Ext.create('Ext.panel.Panel',{
                  layout: 'vbox',
                  width: 300,
                  height: 300,
                items:[
                       {
                           xtype:'button',
                           text: 'Click me',
                           itemId: 'clickMeBtn',
                           listeners: {
                                    click: Ext.bind(this.btnClickHandler, this)
                           }
                       },
                       {
                           xtype: 'label',
                           id: 'labelId',
                           text: 'Click on button to change me'
                       }
                      ]              
            });
            return this.panelObj;
        }
    });

Code for creating the two panel object and displaying it on screen:
var panelObj1 = Ext.create('CustomClass').createPanel();
      var panelObj2 = Ext.create('CustomClass').createPanel();
     
      Ext.create("Ext.panel.Panel", {
            layout: 'border',
            width: 700,
            height: 700,
            renderTo: Ext.getBody(),
            items:
            [
                  {
                        xtype: 'panel',
                        region: 'west',
                        flex: 1,
                        items: [panelObj1]
                  },
                  {
                        xtype: 'panel',
                        region: 'center',
                        flex: 1,
                        items: [panelObj2]
                  }
            ]
      });
Observation: On screen, we will get two panel objects, but both are distorted and not working well on button click on both panel object.
Now, we are modifying the code of our CustomClass.js and use itemId instead of id in case of label as below:
                       {
                           xtype: 'label',
                           itemId: 'labelId',
                           text: 'Click on button to change me'
                       }
Now, if we create two panel object and display it on screen, it will work perfectly.
Conclusion: If we know that there will be only one occurrence of the view component on screen, we can easily use id otherwise we have to use itemId.

Monday, November 19, 2012

Reference of ‘this’ is not required for event handler


One strange thing that I have always seen that  whenever I tried to use ‘this’ keyword in ExtJs in any event handler, I didn't get the expected result. Either I got some unexpected object or sometimes ‘undefined’ in place of ‘this’. E.g.


    Ext.define('CustomClass',{
        config:{
            val:'This is testing',
            panelObj: {}
        },

       constructor: function(){
                ref = this;
       }

        createPanel: function(){
            this.panelObj = Ext.create('Ext.panel.Panel',{
                layout: 'vbox',
                width: 300,
                height: 300,
                items:[
                       {
                                   xtype:'button',
                                   text: 'Click me',
                                   itemId: 'clickMeBtn',
                                   listeners: {
                                                click: function(){
                                                 // this.panelObj.queryById('labelId').setText('Value changed');
                                                 ref.panelObj.queryById('labelId').setText('Value changed');
                                        }
                           }
                       },
                       {
                                   xtype: 'label',
                                   itemId: 'labelId',
                                   text: 'Click on button to change me'
                       }
                      ]               
            });
            return this.panelObj;
        } 
    });


In above code, if we use " this.panelObj.queryById('labelId').setText('Value changed');", I will get some unexpected result. So, I have to keep the reference of 'this' in a 'ref' variable in constructor and then I used this ref variable in the click handler to get required result.

Problem in this approach: But, this is not a good programming approach. Here, we are keeping the reference of 'this' at global level in a 'ref' variable. It will work if the above class is singleton i.e. if we will create only one object of this class in whole application. But, what will happen, if we create more than one object of this class and all the object will be active simultaneously. In this case, the 'ref' variable will contain reference of only last created object and thus using ref variable in event handlers of corresponding objects will give unexpected result.

Solution of this problem: To solve this problem, we can use bind() function provided by ExtJs. With the help of this function, we can directly use 'this' instead of 'ref' in event handler of this class. The bind() function binds a method to an event and accept a scope(may be 'this' or other object) and some more arguments. The syntax of this function is:

bind( fn, [scope], [args], [appendArgs] ) : function

fn: This is a function to be bound with an event.

scope: This is an optional parameter. It is used to provide the scope in which the function will run. E.g. here we can provide 'this' as a scope.

args: This is an optional parameter. It is an array. Overrides arguments for the call. (Defaults to the arguments passed by the caller).

appendArgs: It is an optional and boolean/number parameter. If True args are appended to call args instead of overriding, if a number the args are inserted at the specified position.

Following is the example of how can we modify our above code to use 'this' directly in an event handler  without keeping any reference of 'this' by using bind() function.


    Ext.define('CustomClass',{
        config:{
            val:'This is testing',
            panelObj: {}
        },

        btnClickHandler: function () {
            this.panelObj.queryById('labelId').setText('Value changed');
        },

        createPanel: function(){
            this.panelObj = Ext.create('Ext.panel.Panel',{
                layout: 'vbox',
                width: 300,
                height: 300,
                items:[
                       {
                                   xtype:'button',
                                   text: 'Click me',
                                   itemId: 'clickMeBtn',
                                   listeners: {
                                                click: Ext.bind(this.btnClickHandler, this)
                           }
                       },
                       {
                                   xtype: 'label',
                                   itemId: 'labelId',
                                   text: 'Click on button to change me'
                       }
                      ]               
            });
            return this.panelObj;
        } 
    });


Tuesday, August 28, 2012

Optimize performance of Applications developed in ExtJs 4 or Sencha 2: Web Storage & Sqlite

Storing Data on Client side:
We can enhance our web application response time by storing less modifiable data on our client machine. If we do this, we can minimize server hit for these data and thus can minimize the response time to a great extent.
For storing data on client side, now a day, mainly two type of storages are being used.
1)      Web Storage
2)      Some client side Relational Database like Sqlite
Web Storage:
Web storage is standardized by w3c. Web Storage can be viewed as improvement on cookies. It differs from cookies like:
·         Web Storage provides greater storage capacity ( 5 mb per domain in Mozilla, Chrome, Opera and 10 mb per storage area in IE) compared to 4 kb for cookies.
·         Unlike in case of cookies, which can be directly accessed and changed by server programming,  web storage cannot be directly altered by Server programming.
There are two main web storage types: localStorage and sessionStorage.
localStorage:
 The localStorage object stores the data with no expiration date. The data will not be deleted when the browser is closed, and will be available the next day, week, or year. Here, data is stored like a key-value pair. E.g.
// Store value on the browser beyond the duration of the session
localStorage.setItem('key', 'value');

// Retrieve value (works even after closing and re-opening the browser)
alert(localStorage.getItem('key'));

Session Storage:

The sessionStorage object is equal to the localStorage object, except that it stores the data for only one session. The data is deleted when the user closes the browser window.

// Store value on browser for duration of the session
sessionStorage.setItem('key', 'value');
 
// Retrieve value (gets deleted when browser is closed and re-opened)
alert(sessionStorage.getItem('key'));


SQLite:

SQLite is an embedded SQL database engine. A complete SQL database with multiple tables, indices, triggers, and views, is contained in a single disk file. SQLite is a compact library with library size of 350 kb when all features are enabled. SQLite can also be made to run in minimal stack space (4KiB) and very little heap (100KiB), making SQLite a popular database engine choice on memory constrained gadgets such as cellphones, PDAs, and MP3 players. Important features of Sqlite are as follows:

Important Features:

1)      Zero – Configuration: There is not any installation and configuration process for Sqlite to use it. It can be directly used.
2)      Server Less:  It is not implemented as a separate server process. With SQLite, the process that wants to access the database reads and writes directly from the database files on disk. There is no intermediary server process.
3)      Single Database file: An SQLite database is a single ordinary disk file that can be located anywhere in the directory hierarchy.
4)      Stable Cross-Platform Database File
5)      Compact
6)      Menifest Typing
7)      Variable length records
8)      Readable source code

Detail Ideas about SQLite can be found from http://www.sqlite.org.

Wednesday, August 22, 2012

Optimize performance of Applications developed in ExtJs 4 or Sencha 2: Code Minification


All of us know that just creating any application in very short time frame is not the real achievement. The real effort is invested after creation of application to make it more efficient, faster, and more responsive. Once, I have developed an application in ExtJs 4.1 in very short time frame and when we tested it in real time scenario, I found that my application was very slow and then I started considering about the ways by which I can make my application faster. I have done several changes like:

1)      Code Minification
2)      Applied Phone Gap
3)      Utilized browser local storage or SQL-lite database
4)      Masking
5)      Zip the response data
6)      Use of Dynamic Loading

Here currently we are going to discuss the technique of code minification. We will discuss the other remaining techniques in my next blog.

Code Minification:
It is the one of the easiest way to decrease the page loading time. This can reduce the code size upto 10 times i.e. if the total size of all of your custom javascript files is say 3 MB, it can reduce this size to 300 KB and thus similarly the page loading time will also be decreases. Code minification does not do any huge modification in your code. It just merge codes of all of your javascript files in a single file and removes the unwanted blank spaces, tabs and comment lines. It also reduces the variable name length.  Following are the steps of code minification by using Sencha tool.

Steps for Minification of javascript files of Sencha application.

1.       Download SenchaSDKTools-2.0.0-beta3-windows.exe

2.       Set path in window environment variable to “C:\Program Files (x86)\SenchaSDKTools-2.0.0-beta3”

3.       Restart your system if needed.

4.       Download Jsbuilder3 and unzip it

5.       Open command prompt and go to the root directory of web project i.e. WebContent in case of tomcat

6.       Now create .jsb3 file by using following command:

C:\abc\ MyWebProject\WebContent>sencha create jsb -a  C:\abc\ MyWebProject \WebContent \index.html -p MyWebProject.jsb3
       This .jsb3 file will be created at root directory i.e. WebContent

7.       Now create single .js file for all of your .js files in your project by using the previously created .jsb3 file with following command:

C:\abc\ MyWebProject \WebContent >sencha build -p MyWebProject.jsb3 -d C:\abc\ MyWebProject \WebContent
        This command will create two .js files. 1) all-classes.js 2) app-all.js

8.       Go to your index.html file and replace ext-debug.js with ext.js and app.js with app-all.js

9.       The newly created app-all.js is in unminified format and it can be further minified by using yuicompressor and for this, yuicompressor-version.jar is needed. To Further minify it, following command should be fired:

C:\xyz\Newfolder>java -jar yuicompressor-2.4.2.jar C:\xyz\Newfolder\app-all.js -o C:\xyz\Newfolder\ap.js
 
       Now copy the minified code from ap.js file and paste it in app-all.js of your application.

Important Note: During performing all of the above steps, you should be sure that your webserver is running and you are using your app.js file. Because, .jsb3 file is created by reading your app.js file and it is done only when your webserver is running.