ExtJS is a powerful Javascript framework for developing rich Internet applications—but with great power comes great responsibility. If you are inexperienced or careless with your implementation, your development effort can quickly spin out of control. Your project structure might grow to become unruly, steepening the learning curve for developers new to the framework. Worse yet, performance issues may arise that can be tricky to deal with once they have a foothold within your application.
Equipped with some tips from Senchacon ‘13 and my past experience with ExtJS, I’d like to share some knowledge that will help you be proactive against these issues and avoid potential roadblocks.
Folder and Code Structure
First, two pieces of advice that are not specific to ExtJS, but still helpful:
Maintain an organized project structure. Placing every view under “views” in a directory is likely to cause headaches somewhere down the line, especially if a developer unfamiliar with the project needs to find the source of a particular view.
Group views in sub-folders based on relevance and function. As the project grows and the number of views increases, more tiers should be added to your folder structure. Adding another folder in the hierarchy will have very little impact in the execution of the application, but has the potential to save some frustration.
Your source code should conform to a coding standard. A set standard will help fight against spaghetti code, promote reusability, and facilitate learning. When in doubt, the best code structure you can conform to is the ExtJS source code itself.
Ext.override
Ext.override is a function that allows you to override classes and add or change any functionality you desire. It’s important to understand that if you override a base class, the functionality will affect every instance of that class and any classes that inherit from it. There’s a good chance you will introduce a few defects in the process. Also, if you decide to upgrade to a newer version of ExtJS, there’s a chance your override will no longer work as intended.
There will be times when it is necessary to override a class. In these cases, be sure to use best practices when applying the overrides. Do not just place all of your overrides in one file and let it grow over time. Break them apart into their own succinct files and make plenty of comments to describe the reasoning behind and outcome of your changes. It will save time if another developer has to revisit that override after a long period of time.
Excessive Layouts
Layouts can be the bane of an ExtJS application’s existence. They can be triggered by adding or removing new components, changing a component’s content or size, updating a record displayed in a grid with a custom renderer, and much more.
Any time you have a code block that is making these types of changes be sure to surround it with:
suspendLayouts(); #code causing layouts to occur resumeLayouts(true);
Or if you are CRUDing records in a store that is causing a grid to perform multiple layouts, consider using:
gridStore.suspendEvents(); #CRUD operations gridStore.resumeEvents();
Large Grid Datasets
BufferedRenderer is a great plugin to use with grid panels when dealing with large datasets. Essentially this acts as an infinite scrolling solution and rows are only rendered onto the screen when they need to be, rather than all at once.
var grid = Ext.create('Ext.grid.Panel', { //.. autoLoad: true, plugins: { ptype: 'bufferedrenderer', trailingBufferZone: 10, leadingBufferZone: 20, numFromEdge: 6 }, //.. });
The config options to note are:
- trailingBufferZone – the number of rows rendered above the table
- leadingBufferZone – the number of rows rendered below the table
- numFromEdge – the number of rows from the end of the leading or trailing buffer zones that will cause more rows to be rendered into the table
Lazy Instantiation
Attempt to lazily instantiate your items array wherever possible. A primary example would be the hidden tabs of a tabpanel. If the parent container never gets rendered, the child items aren’t instantiated. The plugin here will allow you to accomplish this.
{ xtype: 'tabpanel', items: [{ title: 'T1', plugins: { ptype: 'lazyitems', items: [...] } }, { title: 'T2', plugins: { ptype:'lazyitems', items: [...] } }, {...}] }
Nesting
Overnesting occurs if a component has a single item in its list, which in turn has a single item of its own that defines the rest of the components in the view. The item in the middle should be omitted completely, if the functionality remains the same. Doing so keeps the application structure simple to help reduce the DOM burden and speed up your application.
This bookmarklet helps to automate the search and point you toward problem areas where your application might have some unneeded nesting. A simple way to run this is to copy and paste the code from Gist into your browser’s developer console while the application is running. You will notice areas of the app highlight in red and any problem areas will be logged in the console.
References:
http://www.sencha.com/blog/ext-js-4-1-performance/