PDA

View Full Version : 4.x Framework performance – Request for an Official Statement



MrSparks
1 Nov 2011, 2:51 AM
Michael Mullany - Sencha Employee
we don’t know exactly how fast 4.1 is going to be, but if you pointed a gun at our heads, we would say it’s likely to still be slower than 3.x. If IE performance is all you care about, and you don’t care about the new features in 4.x and you have to make a decision *today* to go with 4.x vs. stay on 3.x, then we’d probably tell you to stay on 3.x. This might still turn out to be the incorrect recommendation, but if you want our best recommendation for *today* - October 31st 2011 - there it is.

@Sencha

I’ve just spotted the above on the 4.1 pr1 blog and it has me incredibly worried and depressed to say the least.

3.x by Sencha’s own admission performed very poorly and was unacceptable. If 4.x can’t even match the unacceptable performance of 3.x, then I’m really at a loss to see what the point of 4.x was. Quote “JavaScript Framework for Rich Apps in Every Browser” The key words being “apps” and “every browser” here. 4.x absolutely needs to be out-performing 3.x on all browsers to enable developers to produce “real-world” commercial web applications.

Regarding: “If IE performance is all you care about”. We have no choice other than to care about IE, it has a massive corporate install base and it’s not going away any time soon. Ironically, one of the reasons corporate users are sticking with Windows XP is because newer incantations of Windows have a huge footprint and perform badly on equivalent hardware.

Guys please tell me this awful news about 4.x isn’t true!

saprot
1 Nov 2011, 6:49 AM
The whole new class system etc is really cool, but how many people will actually care if its Ext.define instead of Ext.extend, while it's three times slower?

Would't it be better if you'd just taken 3.4.0 and improve it, rather than making framework revolution?

mmullany
1 Nov 2011, 10:44 AM
Guys,

Let me add another statement, which I'll add to my comment on the blog too. Is that we're not finished with performance optimization with the 4.1 release, we'll continue to improve performance in 4.2 and beyond, and we won't stop until we're happy - which is to say, at least as fast as 3.x.

-- michael

stahlman
1 Nov 2011, 10:46 AM
Echoing MrSparks' concerns... I found the following post a bit troubling...

http://www.sencha.com/forum/showthread.php?152195-Overall-Performance/page2#post_665792 (http://www.sencha.com/forum/showthread.php?152195-Overall-Performance/page2#post_665792)

I may be reading too much between the lines, but I got the sense while reading Ed's post that from Sencha's perspective, 4.x is the new baseline against which small incremental performance improvements are to be measured. From my perspective, 4.0 should never have been released. I appreciate and applaud the desire to provide a cleaner, more object-oriented approach to html and the dom, but only insofar as it can be done without significantly impacting performance. Encapsulating messy dom implementation details in an OO cloak can be helpful, but not if I have to spend countless hours rewriting/optimizing what I've developed under the OO paradigm because it's simply too sluggish to be usable by the customer. In my case, I've spent so much time optimizing that I'm thinking I would have been better off time-wise (and certainly performance-wise) writing the whole thing using a more traditional DHTML approach.

On a philosophical note... I'm beginning to wonder whether the fundamental problem here is that the attempts to encapsulate do not sufficiently recognize the constraints of the underlying implementation (html/dom) being encapsulated. When I was profiling one of my views in Ext 4.0, Chrome and Firefox profilers were showing something on the order of 500 layouts being performed by the browser just to render the initial view! Chrome Speed Tracer flagged this (rightly so) as a problem, even though its rendering engine was sufficiently optimized (or perhaps it was that Ext was sufficiently optimized for Chrome's rendering engine ;-) to render the view without a lot of noticeable delay. But even if, by dint of Herculean efforts, the browser's rendering engine is able to do those ~500 layouts in a reasonable amount of time, the fact that it needs to makes me wonder whether we've taken a wrong turn somewhere... Just because something can be done, doesn't mean it should be. I can't speak for all developers, but from my perspective, I'd be willing to give up a bit of layout configurability/flexibility if it permitted the framework to do things in a manner that was more "natural" - i.e., in a way that didn't seem to be fighting the way the browser works. I'm thinking that if this approach were taken, we'd never see anywhere near 500 layouts for a single view rendering...

Incidentally, I don't know how many browser layouts are required under 4.1. I'm getting too many rendering errors with it at this point to do much performance testing.

Sincerely,
Brett Stahlman

MrSparks
1 Nov 2011, 12:24 PM
@stahlman, excellent post.

@Sencha
With regards to other talk of 4.2, beyond and the performance will come. Realistically 4.2 is a year away for a stable release and that's far too long to wait for most dev's and certainly far too long to wait without a rock solid performance promise.

Comments of at least as fast as 3.x isn't anything to shout about. 3.x is already acknowledge (by Sencha) to be a poor performer, so why on earth would that now be the performance target for 4.x. That makes no commercial/development sense.

Surly when 4.x was in early alpha / proof of concept, someone at Sencha must have checked to see if it was an improvement over 3.x?

Whilst researching frameworks for my app, my 3.x proof of concepts showed me that 3.x didn’t quite have enough horsepower for my app, so my commitment (commercial and time investment) in EXT JS and 4.x was based on the fact that 4.x was going to be a huge performance hike over 3.x

Is the official line on 4.x now that performance won’t be any better that 3.x?

If that's the case (aside from the absolute nightmare that will cause me of finding a new framework and rewriting my app), what does the future hold for EXT JS. Will 5.x be even bigger and slower 4.x? Based on past major EXT JS framework releases, there's an obvious pattern developing. Where is the line in the sand? There has to be one Guys.

It honestly pains me to have to post these words because I know how much hard work and person effort the Sencha Devs have put into the framework.

chinabuffet
2 Nov 2011, 6:50 AM
Great post stahlman... that pretty much sums up what we've been dealing with as well.

I managed to get a few screens in our app to partially render at least, but it involved numerous hacks to both my app code + the ext source files. For the most part it seemed to be quicker, but some areas just wouldn't render at all so that was probably factoring into it.

dongryphon
3 Nov 2011, 12:16 AM
@MrSparks

Can you (without too much trouble) provide some examples that could help us profile/measure your use case(s) and understand more specifically where you are having performance problems? I know that it may not yet be possible for you to measure on 4.1, but even if the example works in 4.0 and not in 4.1, it would still be very helpful.

We rely a lot on our own examples, especially the combination examples, but they are not real apps. It would be very helpful to us to have examples from folks like yourself to improve our performance test suite with some real-world use cases.

Before joining Sencha, at my previous employer, I used Ext JS 3.x heavily in complex ways and the performance problems we experienced were mostly of our own making. Not to say the problems you are describing are dismissable or anything, but rather I am curious to understand the specific problems you are describing.

I don't know if this is one of the areas where you are having performance problems, but I feel confident that we will see some real gains in Grid. As you no doubt know, Grid in v3 was a rather complex piece of DOM. This costed in many ways (column resizing for example). In v4, Grid's DOM is much simpler: a table in most cases. And you don't have to turn off all the features to do buffered rendering as we often did in our app in v3. In 4.1, Grid now uses native scrolling as well, which helps tremendously on the user experience there.

As we solve the performance problems around Grid, the improvements inside Grid should really stand out.

(:|+~o) =:D
Don

dongryphon
3 Nov 2011, 12:25 AM
@chinabuffet,

Please do report problems you have getting your apps/pages to load in 4.1. (in another thread ;))

Seriously, though, we know there are some unfinished things that will block some apps/pages, but it will help us to prioritize knowing what folks are bumping into.

This applies not only to correctness issues, but performance issues as well. Any examples you can supply that show us how you are using the components and structuring your UI will help us optimize the framework based on actual usage. Not to mention, it will also help us test compatibility ... we cannot brute force our way through all possible combinations of configuration options.

dongryphon
3 Nov 2011, 12:49 AM
@Stahlman,

In 4.0, reflows were optimized locally (at the container level), but because v4 typically had 2x the number of components/containers as v3 for a roughly equivalent configuration, this was not enough to avoid a catastrophic number of reflows.

For 4.1, eliminating reflows was a key part of our effort. The changes to layouts were specificially designed to perform the fewest number of reflows possible for all layouts being calculated. Given that some measurement is still required and some of that depends on previous calculations being written to the DOM.

In addition to layout changes, 4.1's rendering changes were also essential in reducing the number of reflows. For example, many components performed additional rendering and DOM manipulation after they had just placed their markup into the DOM. Now in 4.1, we do almost all that work as we produce the markup.

Please feel free to report any problems you are having getting your app/pages to load in 4.1. Our goal is to ensure as smooth a transition as possible from 4.0.x to 4.1 (final), so we really want to hear about any compatibility issues you are having.

saprot
3 Nov 2011, 1:38 AM
@DonGryphon

let's use Sencha's own example: ext-4.1-pr1/examples/window/layout.html and ext-3.4.0/examples/window/layout.html, so they are the same.

Time used for clicking on "Show window" button and changing from Tab1 to Tab2, and from Tab2 to Tab3 (measured by Firefox with Firebug Profile button):
Ext 3.4.0: (183.555ms, 11683 calls)
Ext 4.1.PR1: (328.84ms, 32406 call)

And please don't respond like 'post your computer configuration'. Ext 4.1 is still a lot slower than 3.4.0 :(

tvanzoelen
3 Nov 2011, 2:54 AM
I was hoping that 4.1 would be more stable compared to 3.4. There are a lot of layout issues. I think Sencha should focus on that instead of performance.

Grid and (tab)panel layout do strange things. I now tested 4.07, 4.1 is not working in my app. Performance is not that good but will do, but get it stable please!

A stable program is better then a fast unstable program. And please throw out that MVC Loader stuff. I want all my js files loaded at once. It is really impossible to put my 3.4 in that MVC thing, my app is to big to handle it in the way the architecture of Ext 4 wants me to do.

MrSparks
3 Nov 2011, 3:51 AM
@MrSparks

Can you (without too much trouble) provide some examples that could help us profile/measure your use case(s) and understand more specifically where you are having performance problems? I know that it may not yet be possible for you to measure on 4.1, but even if the example works in 4.0 and not in 4.1, it would still be very helpful. (:|+~o) =:D
Don

@Don,

I've always used the Sencha examples (themes) when posting benchmarks on the forum. It seemed the best approach because everyone has access to the same code and its a constant.

Happy to profile my own app under 4.0.7 (it won't work on 4.1 pr1) and supply the trace file. Do you want both the IE and DNA trances? Unfortunately I wont be able to supply my apps code base because of IP. Where do I send the traces to?

Out of interest if the Sencha shipped examples (big and small) are consistently showing 4.x is slower than 3.x, how will having a trace of my App help? The performance problem isn't a customer specific case. Every user of 4.x is effected.

Best
MrSparks

rich02818
3 Nov 2011, 5:35 AM
There are two very simple examples with code that have been in the forum for months and show that the performance problems with 4.x are not only the result of complex pages. Thus far Sencha has apparently not tried these simple examples...or has not posted the results even though that was asked for.

@Don please run the examples from the post below and let us know what the performance is on your machine using 4.1. Thanks.

http://www.sencha.com/forum/showthread.php?141113-v4-performance-very-slow-with-very-simple-page

(http://www.sencha.com/forum/showthread.php?141113-v4-performance-very-slow-with-very-simple-page)

LesJ
3 Nov 2011, 6:22 AM
I now tested 4.07, 4.1 is not working in my app. Performance is not that good but will do, but get it stable please!

tvanzoelen, hi!

I could not agree more. Fixing bugs should be a priority. 4.1 already provides a decent speed improvement, but I'm not able to upgrade due to bugs, and it takes too much time to work around issues.

Here's one example... text rotation is broken and it's not trivial to find a workaround:

http://www.sencha.com/forum/showthread.php?152104-4.0.7-4.0.6-VML-broken-text-rotation

dongryphon
3 Nov 2011, 9:46 AM
@saprot,

I hope I was not coming across as saying that we don't see any performance differences when we measure our examples. We are optimizing using them as a benchmarks.

What I am saying is that apps tend to be more complex than our examples. :) Their interactions and use of components is an important thing for us to understand, but without knowing how real apps use the framework, we have to use approximations (like our examples).

I am also suggesting that if we treat performance as we do other bugs (where possible and within reason) and we get some concrete use cases derived from how folks actually use the framework, we can incorporate that in to our continuous integration loop to the benefit of everyone.

Apologies for any confusion on that.

dongryphon
3 Nov 2011, 9:52 AM
@tvanzoelen,

The current release of 4.1 is a Preview and I hope we were clear about its stability... or really its lack thereof. :)

We are currently focused on stabilizing 4.1.

MVC is optional as is the loader. One of the goals of 4 was to really help produce optimized builds based on class dependencies, so you should be able to get your JS built the way you describe.

dongryphon
3 Nov 2011, 9:57 AM
@LesJ,

The current 4.1 release is just a Preview and would (obviously) not be something to upgrade to just yet. We released it to see if we were on track with performance gains that we observed internally.

Thanks for taking a look and working with 4.1. Please report issues you are having so we can fix as many as possible for the final release.

dongryphon
3 Nov 2011, 10:46 AM
@MrSparks,

You are correct and we are focused on the performance of our examples as we work to eliminate those general performance problems. That said, we are also keenly aware that while we may rack up wins with our examples, that does not necessarily translate into real world gains or at least those gains may vary by some amount. Which is why we released 4.1 so early in its stabilization phase.

What I was thinking would be of value is example code that illustrates how you compose and configure components in your app. If your app is very similar to our examples, then our current process should provide adequate coverage for your use of the framework. But if not, any examples you might provide would help expand that coverage.

An example of where this can be of value to our development process (and this is not a complaint :)): In 4.1 PR1, we have an unsupported layout use case: auto width derived from CSS and not from "shrink-wrap to content". It turns out that the Portal example and little else uses this particular flavor of autoWidth so we decided to ship with that as a known issue. It may well be that some apps are heavily reliant on that. Or maybe 99% of apps rely on it. Perhaps we would have gotten 10x the feedback on 4.1 PR1 had we prioritized this over other fixes.

The same can apply to use cases for which we might have or need special optimizations. We obviously want the most common use cases to be particularly well optimized, but "common" is really a statistical question.

A trace on 4.0.7 would probably not be that helpful now that we have reworked so much of the known problem areas... maybe 4.1... once it is stable enough for you to test. :)

Thanks for all your feedback and assistance... much appreciated!

MrSparks
3 Nov 2011, 11:53 AM
@Don,

Thanks for the reply.

My app is on the very large side but isn’t doing anything out of the ordinary. By that I mean I’m not doing any cleaver overrides, custom components and only have a hand full of my own JavaScript functions, which are basic condition checks. Essentially think Sencha complex layout example, with many more tabs, a dozen or so grids, forms etc the basic stuff you need in a UI.

I would love to give you access to my code but IP consideration prevent me form doing so.

Just to give an idea of how badly 4.0.7 performs under IE, my app takes 27 seconds to load and the UI is barley responsive. The same app under Chrome takes 5 seconds and the UI has acceptable response times.

My app is a bit of a mute point however, as say it’s not more technically complex than the Sencha example, it’s just much bigger.

Can we for clarities sake agree that there is a fundamental performance issue on 4.1 pr1? With that in mind can we agree that when the release build of 4.1 is made available, if that also exhibits the same performance profile as 4.1 pr1, that Sencha communicate exactly what the situation is.

i.e.
1. We accept there is a serious issue here and will fix the problem and give the promised performance hike over 3.x

2. We know there is a serious issue here but that's the best we can do performance wise in the 4.x framework. (Outside of minor optimisations)

On a related diagnostic note, I have noticed when profiling the layout example that IE typically loads twice as many images as say Chrome or FF. Just speculation here but are you doing anything clever with the IO that waits on each get? i.e. something that you weren’t doing in 3.x

Best
MrSparks

dongryphon
3 Nov 2011, 12:13 PM
I would love to give you access to my code but IP consideration prevent me form doing so.

Fully understand that. I was in the same place at my last job. Maybe modifying one of our examples to be closer to your use would be possible, but I hear what you're saying: same but bigger. :)

dongryphon
3 Nov 2011, 12:17 PM
Just to give an idea of how badly 4.0.7 performs under IE, my app takes 27 seconds to load and the UI is barley responsive. The same app under Chrome takes 5 seconds and the UI has acceptable response times.

If we could reproduce something with these characteristics perhaps extended from our examples, I think that would go a long way. Obviously, none of the examples we work with are large enough to approach that number.

MrSparks
3 Nov 2011, 12:22 PM
@Don,

I'll mock a large example up over the weekend. Can you give commitment that when 4.1 is GA, there will be a definite answer either way on the framework?

dongryphon
3 Nov 2011, 12:33 PM
Can we for clarities sake agree that there is a fundamental performance issue on 4.1 pr1? With that in mind can we agree that when the release build of 4.1 is made available, if that also exhibits the same performance profile as 4.1 pr1, that Sencha communicate exactly what the situation is.

i.e.
1. We accept there is a serious issue here and will fix the problem and give the promised performance hike over 3.x

2. We know there is a serious issue here but that's the best we can do performance wise in the 4.x framework. (Outside of minor optimisations)

First a disclaimer: I am not qualified to speak on that level for Sencha. I don't make prioritization or direction decisions.

It is safe to say that we are extremely focused on performance in this release and I don't see that focus shifting until we are happy with our performance. That said, quantifying the measure of success I think would benefit from community input. Hence the request for more representative use cases. Having concrete examples of performance numbers like what you describe would go a long way to help focus attention. :)

dongryphon
3 Nov 2011, 12:37 PM
@Don,

I'll mock a large example up over the weekend. Can you give commitment that when 4.1 is GA, there will be a definite answer either way on the framework?

That would be awesome, very helpful and much appreciated. :)

Your request is very reasonable and I wish I could speak to it myself. I think that will need to be an Ed, Abe or Michael question.

MrSparks
3 Nov 2011, 12:45 PM
That would be awesome, very helpful and much appreciated. :)

Your request is very reasonable and I wish I could speak to it myself. I think that will need to be an Ed, Abe or Michael question.

Great, I've just dropped Ed a little email with where I'm up to and I'll crack on with a big example ready for close of play Sunday.

Best
MrSparks

rich02818
3 Nov 2011, 2:41 PM
@Don I'm feeling ignored :)

You answered all other posts except mine. My suspicious mind makes me wonder why Sencha has consistently requested complex examples of performance problems, but ignored the posts showing that only a very simple page is needed to see the difference clearly. Please take a good look at the post I mentioned earlier, which I will provide again. I'd very much appreciate feedback.

http://www.sencha.com/forum/showthread.php?141113-v4-performance-very-slow-with-very-simple-page


(http://www.sencha.com/forum/showthread.php?141113-v4-performance-very-slow-with-very-simple-page)

dongryphon
3 Nov 2011, 2:57 PM
@Don I'm feeling ignored :)

You answered all other posts except mine. My suspicious mind makes me wonder why Sencha has consistently requested complex examples of performance problems, but ignored the posts showing that only a very simple page is needed to see the difference clearly. Please take a good look at the post I mentioned earlier, which I will provide again. I'd very much appreciate feedback.

http://www.sencha.com/forum/showthread.php?141113-v4-performance-very-slow-with-very-simple-page
(http://www.sencha.com/forum/showthread.php?141113-v4-performance-very-slow-with-very-simple-page)

Apologies... I was not ignoring your post. I actually have the page open and was going to look at your code... once my working branch is running again ;)

One of the items on my list to check is if we can simplify field layouts in particular because it has "work around" code in it currently to measure each element and sum their individual widths. I don't think that is needed in 4.1 and it should help a lot to remove it. Also, since fields typically show up in multiples, I have been considering a FieldGroup container (name TBD) that uses tables to achieve alignment (and auto labelWidths) which should avoid even more calculation. I believe there was such a ux in v3 (table form or something).

I guess that your post (because it is field related) fell into my "more research required to provide details" filter, but I do apologize for the silence. No slight intended. :">

Thanks for posting code to help illustrate the issues you are seeing by the way! It is helpful and is not being ignored, despite all evidence to the contrary. ;)

rich02818
3 Nov 2011, 3:01 PM
@Don, thanks for the reply. I actually only added text fields to the simple example to extend it a bit. The performance difference is quite visible by simply creating a viewport with no fields or labels at all. That is the first of the test cases in my earlier post.

dongryphon
3 Nov 2011, 3:16 PM
@Don, thanks for the reply. I actually only added text fields to the simple example to extend it a bit. The performance difference is quite visible by simply creating a viewport with no fields or labels at all. That is the first of the test cases in my earlier post.

I think the trick here is to separate marginal, fixed costs from those that scale in unfriendly ways as the UI grows to a meaningful size.

While we are looking at those fixed costs like load time, class definition/processing and onready detection (esp in IE), we are more focused on costs that grow with UI complexity. Things like component creation, container initialization, rendering and layout. Then there is intelligent layout invalidation (to only recalculate what is necessary) to ensure a responsive UI.

A few milliseconds of extra fixed cost is not nearly as important when compared to even a small cost that gets multiplied by M*N (M=# of containers, N=# of components) or something like that.

Hopefully that helps explain why we are mostly looking at and asking for larger examples. If we make those perform acceptably, the small ones should come along for the ride :)

Gummy
3 Nov 2011, 9:17 PM
What would be nice is to have some guidelines on how to make an fast ExtJS application.
What parts of an application makes it slow ?
Is is the number of components ? The complexity of the layout ?
Are some components slower than others ? Could it be mentioned in their documentation ?

As a side note I think ExtJS is great, it made me love web programming. I hope it will be fast, reliable and successful :)

ftrack
3 Nov 2011, 11:26 PM
@Gummy - Yes! I would really like to see this as a sticky thread. Like "tips and trick on performance". What should be avoided and how can you work around some of the worst scenarios.

This could turn out to be extremely useful, as i sometimes might be hard to understand the performance impact from a certain configuration.

skirtle
4 Nov 2011, 8:43 AM
@Gummy & @ftrack. I think this is a great idea. I've started a thread here to try to gather performance tips from the community:

http://www.sencha.com/forum/showthread.php?153565

rich02818
5 Nov 2011, 6:12 AM
Great, I've just dropped Ed a little email with where I'm up to and I'll crack on with a big example ready for close of play Sunday.

Best
MrSparks

Any response from Ed? It's getting uncomfortable to have *no* official position from Sencha on the level of performance that we can count on for our business. Your statements about better than v3 performance being necessary are right on, and we were previously told we could count on this. Come to think of it, we've been told (in the video presentation of v4) that it's already been achieved!

MrSparks
5 Nov 2011, 12:45 PM
@Rich, nothing from Ed yet.

@Don,

Below are 2 x Simple "Apps". The 4.x version runs around 2.5 to 3 times slower that the 3.4.0 version. That's consistent with every other benchmark I've ran. There nothing complex here, just a load of examples bolted together. A real app would be more complex and slower.

I'm not exactly sure what advantage you will gain by profiling these, as opposed to your own examples.

EXTJS 3.4.0


<html>
<head>
<title>Simple App EXTJS 3.4.0</title>
<script>
//alert("start");
var oneDay = 24*60*60*1000; // hours*minutes*seconds*milliseconds
var now = new Date();
var starthours = now.getHours();
var startminutes = now.getMinutes();
var startseconds = now.getSeconds();
var startmilli = now.getMilliseconds();
var date1 = new Date(2011,06,05,starthours,startminutes,startseconds,startmilli)
</script>
<link rel="stylesheet" type="text/css" href="/ext3.4.0/resources/css/ext-all.css" />

<style type="text/css">
html, body {
font:normal 12px verdana;
margin:0;
padding:0;
border:0 none;
overflow:hidden;
height:100%;
}
p {
margin:5px;
}
.settings {
background-image:url(/ext3.4.0/examples/shared/icons/fam/folder_wrench.png);
}
.nav {
background-image:url(/ext3.4.0/examples/shared/icons/fam/folder_go.png);
}
</style>


<!-- GC -->
<!-- LIBS -->
<script type="text/javascript" src="/ext3.4.0/adapter/ext/ext-base.js"></script>
<!-- ENDLIBS -->


<script type="text/javascript" src="/ext3.4.0/ext-all.js"></script>


<!-- EXAMPLES -->
<script type="text/javascript" src="/ext3.4.0/examples/ux/SearchField.js"></script>
<script type="text/javascript" src="/ext3.4.0/examples/form/states.js"></script>

<script type="text/javascript">
Ext.onReady(function(){

// NOTE: This is an example showing simple state management. During development,
// it is generally best to disable state management as dynamically-generated ids
// can change across page loads, leading to unpredictable results. The developer
// should ensure that stable state ids are set for stateful components in real apps.
Ext.state.Manager.setProvider(new Ext.state.CookieProvider());
Ext.BLANK_IMAGE_URL = '/ext3.4.0/resources/images/default/s.gif';
Ext.QuickTips.init();

northTb = new Ext.Toolbar ({
region: 'north',
xtype: 'button',
items: [
{
text: 'Button 1',
scale: 'medium',
width: 100
},
{
text: 'Button 2',
scale: 'medium',
width: 100
},
{
text: 'Button 3',
scale: 'medium',
width: 100
},
{
text: 'Button 4',
scale: 'medium',
width: 100
},
{
text: 'Button 5',
scale: 'medium',
width: 100
},
{
text: 'Button 6',
scale: 'medium',
width: 100
},
{
text: 'Button 7',
scale: 'medium',
width: 100
}
]
})



var tree1 = new Ext.tree.TreePanel({
title: 'My Task List 1',
useArrows:true,
autoScroll:true,
animate:true,
enableDD:true,
containerScroll: true,
rootVisible: false,
frame: true,
root: {
nodeType: 'async'
},

// auto create TreeLoader
dataUrl: '/ext3.4.0/examples/tree/check-nodes.json',

listeners: {
'checkchange': function(node, checked){
if(checked){
node.getUI().addClass('complete');
}else{
node.getUI().removeClass('complete');
}
}
},

buttons: [{
text: 'Get Completed Tasks',
handler: function(){
var msg = '', selNodes = tree1.getChecked();
Ext.each(selNodes, function(node){
if(msg.length > 0){
msg += ', ';
}
msg += node.text;
});
Ext.Msg.show({
title: 'Completed Tasks',
msg: msg.length > 0 ? msg : 'None',
icon: Ext.Msg.INFO,
minWidth: 200,
buttons: Ext.Msg.OK
});
}
}]
});

var tree2 = new Ext.tree.TreePanel({
title: 'My Task List 2',
useArrows:true,
autoScroll:true,
animate:true,
enableDD:true,
containerScroll: true,
rootVisible: false,
frame: true,
root: {
nodeType: 'async'
},

// auto create TreeLoader
dataUrl: '/ext3.4.0/examples/tree/check-nodes.json',

listeners: {
'checkchange': function(node, checked){
if(checked){
node.getUI().addClass('complete');
}else{
node.getUI().removeClass('complete');
}
}
},

buttons: [{
text: 'Get Completed Tasks',
handler: function(){
var msg = '', selNodes = tree2.getChecked();
Ext.each(selNodes, function(node){
if(msg.length > 0){
msg += ', ';
}
msg += node.text;
});
Ext.Msg.show({
title: 'Completed Tasks',
msg: msg.length > 0 ? msg : 'None',
icon: Ext.Msg.INFO,
minWidth: 200,
buttons: Ext.Msg.OK
});
}
}]
});

var tree3 = new Ext.tree.TreePanel({
title: 'My Task List 3',
useArrows:true,
autoScroll:true,
animate:true,
enableDD:true,
containerScroll: true,
rootVisible: false,
frame: true,
root: {
nodeType: 'async'
},

// auto create TreeLoader
dataUrl: '/ext3.4.0/examples/tree/check-nodes.json',

listeners: {
'checkchange': function(node, checked){
if(checked){
node.getUI().addClass('complete');
}else{
node.getUI().removeClass('complete');
}
}
},

buttons: [{
text: 'Get Completed Tasks',
handler: function(){
var msg = '', selNodes = tree3.getChecked();
Ext.each(selNodes, function(node){
if(msg.length > 0){
msg += ', ';
}
msg += node.text;
});
Ext.Msg.show({
title: 'Completed Tasks',
msg: msg.length > 0 ? msg : 'None',
icon: Ext.Msg.INFO,
minWidth: 200,
buttons: Ext.Msg.OK
});
}
}]
});



var tree4 = new Ext.tree.TreePanel({
title: 'My Task List 4',
useArrows:true,
autoScroll:true,
animate:true,
enableDD:true,
containerScroll: true,
rootVisible: false,
frame: true,
root: {
nodeType: 'async'
},

// auto create TreeLoader
dataUrl: '/ext3.4.0/examples/tree/check-nodes.json',

listeners: {
'checkchange': function(node, checked){
if(checked){
node.getUI().addClass('complete');
}else{
node.getUI().removeClass('complete');
}
}
},

buttons: [{
text: 'Get Completed Tasks',
handler: function(){
var msg = '', selNodes = tree4.getChecked();
Ext.each(selNodes, function(node){
if(msg.length > 0){
msg += ', ';
}
msg += node.text;
});
Ext.Msg.show({
title: 'Completed Tasks',
msg: msg.length > 0 ? msg : 'None',
icon: Ext.Msg.INFO,
minWidth: 200,
buttons: Ext.Msg.OK
});
}
}]
});

var tree5 = new Ext.tree.TreePanel({
title: 'My Task List 5',
useArrows:true,
autoScroll:true,
animate:true,
enableDD:true,
containerScroll: true,
rootVisible: false,
frame: true,
root: {
nodeType: 'async'
},

// auto create TreeLoader
dataUrl: '/ext3.4.0/examples/tree/check-nodes.json',

listeners: {
'checkchange': function(node, checked){
if(checked){
node.getUI().addClass('complete');
}else{
node.getUI().removeClass('complete');
}
}
},

buttons: [{
text: 'Get Completed Tasks',
handler: function(){
var msg = '', selNodes = tree5.getChecked();
Ext.each(selNodes, function(node){
if(msg.length > 0){
msg += ', ';
}
msg += node.text;
});
Ext.Msg.show({
title: 'Completed Tasks',
msg: msg.length > 0 ? msg : 'None',
icon: Ext.Msg.INFO,
minWidth: 200,
buttons: Ext.Msg.OK
});
}
}]
});



var store1 = new Ext.data.Store({
// load using HTTP
url: '/ext3.4.0/examples/grid/sheldon.xml',

// the return will be XML, so lets set up a reader
reader: new Ext.data.XmlReader({
// records will have an "Item" tag
record: 'Item',
id: 'ASIN',
totalRecords: '@total'
}, [
// set up the fields mapping into the xml doc
// The first needs mapping, the others are very basic
{name: 'Author', mapping: 'ItemAttributes > Author'},
'Title', 'Manufacturer', 'ProductGroup'
])
});

// create the grid
var grid1 = new Ext.grid.GridPanel({
store: store1,
height: 500,
columns: [
{header: "Author", width: 120, dataIndex: 'Author', sortable: true},
{header: "Title", width: 180, dataIndex: 'Title', sortable: true},
{header: "Manufacturer", width: 115, dataIndex: 'Manufacturer', sortable: true},
{header: "Product Group", width: 100, dataIndex: 'ProductGroup', sortable: true}
]
});
store1.load();

var store2 = new Ext.data.Store({
// load using HTTP
url: '/ext3.4.0/examples/grid/sheldon.xml',

// the return will be XML, so lets set up a reader
reader: new Ext.data.XmlReader({
// records will have an "Item" tag
record: 'Item',
id: 'ASIN',
totalRecords: '@total'
}, [
// set up the fields mapping into the xml doc
// The first needs mapping, the others are very basic
{name: 'Author', mapping: 'ItemAttributes > Author'},
'Title', 'Manufacturer', 'ProductGroup'
])
});

// create the grid
var grid2 = new Ext.grid.GridPanel({
store: store2,
height: 500,
columns: [
{header: "Author", width: 120, dataIndex: 'Author', sortable: true},
{header: "Title", width: 180, dataIndex: 'Title', sortable: true},
{header: "Manufacturer", width: 115, dataIndex: 'Manufacturer', sortable: true},
{header: "Product Group", width: 100, dataIndex: 'ProductGroup', sortable: true}
]
});
store2.load();


var store3 = new Ext.data.Store({
// load using HTTP
url: '/ext3.4.0/examples/grid/sheldon.xml',

// the return will be XML, so lets set up a reader
reader: new Ext.data.XmlReader({
// records will have an "Item" tag
record: 'Item',
id: 'ASIN',
totalRecords: '@total'
}, [
// set up the fields mapping into the xml doc
// The first needs mapping, the others are very basic
{name: 'Author', mapping: 'ItemAttributes > Author'},
'Title', 'Manufacturer', 'ProductGroup'
])
});

// create the grid
var grid3 = new Ext.grid.GridPanel({
store: store3,
height: 500,
columns: [
{header: "Author", width: 120, dataIndex: 'Author', sortable: true},
{header: "Title", width: 180, dataIndex: 'Title', sortable: true},
{header: "Manufacturer", width: 115, dataIndex: 'Manufacturer', sortable: true},
{header: "Product Group", width: 100, dataIndex: 'ProductGroup', sortable: true}
]
});
store3.load();


var store4 = new Ext.data.Store({
// load using HTTP
url: '/ext3.4.0/examples/grid/sheldon.xml',

// the return will be XML, so lets set up a reader
reader: new Ext.data.XmlReader({
// records will have an "Item" tag
record: 'Item',
id: 'ASIN',
totalRecords: '@total'
}, [
// set up the fields mapping into the xml doc
// The first needs mapping, the others are very basic
{name: 'Author', mapping: 'ItemAttributes > Author'},
'Title', 'Manufacturer', 'ProductGroup'
])
});

// create the grid
var grid4 = new Ext.grid.GridPanel({
store: store4,
height: 500,
columns: [
{header: "Author", width: 120, dataIndex: 'Author', sortable: true},
{header: "Title", width: 180, dataIndex: 'Title', sortable: true},
{header: "Manufacturer", width: 115, dataIndex: 'Manufacturer', sortable: true},
{header: "Product Group", width: 100, dataIndex: 'ProductGroup', sortable: true}
]
});
store4.load();


// turn on validation errors beside the field globally
Ext.form.Field.prototype.msgTarget = 'side';

var bd = Ext.getBody();

// Define the Grid data and create the Grid
var myData = [
['3m Co',71.72,0.02,0.03,'9/1 12:00am'],
['Alcoa Inc',29.01,0.42,1.47,'9/1 12:00am'],
['Altria Group Inc',83.81,0.28,0.34,'9/1 12:00am'],
['American Express Company',52.55,0.01,0.02,'9/1 12:00am'],
['American International Group, Inc.',64.13,0.31,0.49,'9/1 12:00am'],
['AT&T Inc.',31.61,-0.48,-1.54,'9/1 12:00am'],
['Boeing Co.',75.43,0.53,0.71,'9/1 12:00am'],
['Caterpillar Inc.',67.27,0.92,1.39,'9/1 12:00am'],
['Citigroup, Inc.',49.37,0.02,0.04,'9/1 12:00am'],
['E.I. du Pont de Nemours and Company',40.48,0.51,1.28,'9/1 12:00am'],
['Exxon Mobil Corp',68.1,-0.43,-0.64,'9/1 12:00am'],
['General Electric Company',34.14,-0.08,-0.23,'9/1 12:00am'],
['General Motors Corporation',30.27,1.09,3.74,'9/1 12:00am'],
['Hewlett-Packard Co.',36.53,-0.03,-0.08,'9/1 12:00am'],
['Honeywell Intl Inc',38.77,0.05,0.13,'9/1 12:00am'],
['Intel Corporation',19.88,0.31,1.58,'9/1 12:00am'],
['International Business Machines',81.41,0.44,0.54,'9/1 12:00am'],
['Johnson & Johnson',64.72,0.06,0.09,'9/1 12:00am'],
['JP Morgan & Chase & Co',45.73,0.07,0.15,'9/1 12:00am'],
['McDonald\'s Corporation',36.76,0.86,2.40,'9/1 12:00am'],
['Merck & Co., Inc.',40.96,0.41,1.01,'9/1 12:00am'],
['Microsoft Corporation',25.84,0.14,0.54,'9/1 12:00am'],
['Pfizer Inc',27.96,0.4,1.45,'9/1 12:00am'],
['The Coca-Cola Company',45.07,0.26,0.58,'9/1 12:00am'],
['The Home Depot, Inc.',34.64,0.35,1.02,'9/1 12:00am'],
['The Procter & Gamble Company',61.91,0.01,0.02,'9/1 12:00am'],
['United Technologies Corporation',63.26,0.55,0.88,'9/1 12:00am'],
['Verizon Communications',35.57,0.39,1.11,'9/1 12:00am'],
['Wal-Mart Stores, Inc.',45.45,0.73,1.63,'9/1 12:00am']
];

var ds = new Ext.data.Store({
reader: new Ext.data.ArrayReader({}, [
{name: 'company'},
{name: 'price', type: 'float'},
{name: 'change', type: 'float'},
{name: 'pctChange', type: 'float'},
{name: 'lastChange', type: 'date', dateFormat: 'n/j h:ia'},

// Rating dependent upon performance 0 = best, 2 = worst
{name: 'rating', type: 'int', convert: function(v, rec) {
if (rec[3] < 0) return 2;
if (rec[3] < 1) return 1;
return 0;
}
}
])
});
ds.loadData(myData);

// example of custom renderer function
function italic(value){
return '<i>' + value + '</i>';
}

// example of custom renderer function
function change(val){
if(val > 0){
return '<span style="color:green;">' + val + '</span>';
}else if(val < 0){
return '<span style="color:red;">' + val + '</span>';
}
return val;
}
// example of custom renderer function
function pctChange(val){
if(val > 0){
return '<span style="color:green;">' + val + '%</span>';
}else if(val < 0){
return '<span style="color:red;">' + val + '%</span>';
}
return val;
}

// render rating as "A", "B" or "C" depending upon numeric value.
function rating(v) {
if (v == 0) return "A"
if (v == 1) return "B"
if (v == 2) return "C"
}

// the DefaultColumnModel expects this blob to define columns. It can be extended to provide
// custom or reusable ColumnModels
var colModel = new Ext.grid.ColumnModel([
{id:'company',header: "Company", width: 160, sortable: true, locked:false, dataIndex: 'company'},
{header: "Price", width: 55, sortable: true, renderer: Ext.util.Format.usMoney, dataIndex: 'price'},
{header: "Change", width: 55, sortable: true, renderer: change, dataIndex: 'change'},
{header: "% Change", width: 65, sortable: true, renderer: pctChange, dataIndex: 'pctChange'},
{header: "Last Updated", width: 80, sortable: true, renderer: Ext.util.Format.dateRenderer('m/d/Y'), dataIndex: 'lastChange'},
{header: "Rating", width: 40, sortable: true, renderer: rating, dataIndex: 'rating'}
]);

bd.createChild({tag: 'h2', html: 'Using a Grid with a Form'});

/*
* Here is where we create the Form
*/
var gridForm = new Ext.FormPanel({
id: 'company-form',
frame: true,
labelAlign: 'left',
title: 'Company data',
bodyStyle:'padding:5px',
width: 750,
layout: 'column', // Specifies that the items will now be arranged in columns
items: [{
columnWidth: 0.60,
layout: 'fit',
items: {
xtype: 'grid',
ds: ds,
cm: colModel,
sm: new Ext.grid.RowSelectionModel({
singleSelect: true,
listeners: {
rowselect: function(sm, row, rec) {
Ext.getCmp("company-form").getForm().loadRecord(rec);
}
}
}),
autoExpandColumn: 'company',
height: 350,
title:'Company Data',
border: true,
listeners: {
viewready: function(g) {
g.getSelectionModel().selectRow(0);
} // Allow rows to be rendered.
}
}
},{
columnWidth: 0.4,
xtype: 'fieldset',
labelWidth: 90,
title:'Company details',
defaults: {width: 140, border:false}, // Default config options for child items
defaultType: 'textfield',
autoHeight: true,
bodyStyle: Ext.isIE ? 'padding:0 0 5px 15px;' : 'padding:10px 15px;',
border: false,
style: {
"margin-left": "10px", // when you add custom margin in IE 6...
"margin-right": Ext.isIE6 ? (Ext.isStrict ? "-10px" : "-13px") : "0" // you have to adjust for it somewhere else
},
items: [{
fieldLabel: 'Name',
name: 'company'
},{
fieldLabel: 'Price',
name: 'price'
},{
fieldLabel: '% Change',
name: 'pctChange'
},{
xtype: 'datefield',
fieldLabel: 'Last Updated',
name: 'lastChange'
}, {
xtype: 'radiogroup',
columns: 'auto',
fieldLabel: 'Rating',
// A radio group: A setValue on any of the following 'radio' inputs using the numeric
// 'rating' field checks the radio instance which has the matching inputValue.
items: [{
name: 'rating',
inputValue: 0,
boxLabel: 'A'
}, {
name: 'rating',
inputValue: 1,
boxLabel: 'B'
}, {
name: 'rating',
inputValue: 2,
boxLabel: 'C'
}]
}]
}]
});


// turn on validation errors beside the field globally
Ext.form.Field.prototype.msgTarget = 'side';

var fs1 = new Ext.FormPanel({
frame: true,
title:'XML Form',
labelAlign: 'right',
labelWidth: 85,
width:340,
waitMsgTarget: true,

// configure how to read the XML Data
reader : new Ext.data.XmlReader({
record : 'contact',
success: '@success'
}, [
{name: 'first', mapping:'name/first'}, // custom mapping
{name: 'last', mapping:'name/last'},
'company', 'email', 'state',
{name: 'dob', type:'date', dateFormat:'m/d/Y'} // custom data types
]),

// reusable eror reader class defined at the end of this file
errorReader: new Ext.form.XmlErrorReader(),

items: [
new Ext.form.FieldSet({
title: 'Contact Information',
autoHeight: true,
defaultType: 'textfield',
items: [{
fieldLabel: 'First Name',
emptyText: 'First Name',
name: 'first',
width:190
}, {
fieldLabel: 'Last Name',
emptyText: 'Last Name',
name: 'last',
width:190
}, {
fieldLabel: 'Company',
name: 'company',
width:190
}, {
fieldLabel: 'Email',
name: 'email',
vtype:'email',
width:190
},

new Ext.form.ComboBox({
fieldLabel: 'State',
hiddenName:'state',
store: new Ext.data.ArrayStore({
fields: ['abbr', 'state'],
data : Ext.exampledata.states // from states.js
}),
valueField:'abbr',
displayField:'state',
typeAhead: true,
mode: 'local',
triggerAction: 'all',
emptyText:'Select a state...',
selectOnFocus:true,
width:190
}),

new Ext.form.DateField({
fieldLabel: 'Date of Birth',
name: 'dob',
width:190,
allowBlank:false
})
]
})
]
});

// simple button add
fs1.addButton('Load', function(){
fs1.getForm().load({url:'/ext3.4.0/examples/form/xml-form.xml', waitMsg:'Loading'});
});

// explicit add
var submit = fs1.addButton({
text: 'Submit',
disabled:true,
handler: function(){
fs1.getForm().submit({url:'xml-errors.xml', waitMsg:'Saving Data...', submitEmptyText: false});
}
});

fs1.on({
actioncomplete: function(form, action){
if(action.type == 'load'){
submit.enable();
}
}
});



// turn on validation errors beside the field globally
Ext.form.Field.prototype.msgTarget = 'side';
var fs2 = new Ext.FormPanel({
frame: true,
title:'XML Form',
labelAlign: 'right',
labelWidth: 85,
width:340,
waitMsgTarget: true,

// configure how to read the XML Data
reader : new Ext.data.XmlReader({
record : 'contact',
success: '@success'
}, [
{name: 'first', mapping:'name/first'}, // custom mapping
{name: 'last', mapping:'name/last'},
'company', 'email', 'state',
{name: 'dob', type:'date', dateFormat:'m/d/Y'} // custom data types
]),

// reusable eror reader class defined at the end of this file
errorReader: new Ext.form.XmlErrorReader(),

items: [
new Ext.form.FieldSet({
title: 'Contact Information',
autoHeight: true,
defaultType: 'textfield',
items: [{
fieldLabel: 'First Name',
emptyText: 'First Name',
name: 'first',
width:190
}, {
fieldLabel: 'Last Name',
emptyText: 'Last Name',
name: 'last',
width:190
}, {
fieldLabel: 'Company',
name: 'company',
width:190
}, {
fieldLabel: 'Email',
name: 'email',
vtype:'email',
width:190
},

new Ext.form.ComboBox({
fieldLabel: 'State',
hiddenName:'state',
store: new Ext.data.ArrayStore({
fields: ['abbr', 'state'],
data : Ext.exampledata.states // from states.js
}),
valueField:'abbr',
displayField:'state',
typeAhead: true,
mode: 'local',
triggerAction: 'all',
emptyText:'Select a state...',
selectOnFocus:true,
width:190
}),

new Ext.form.DateField({
fieldLabel: 'Date of Birth',
name: 'dob',
width:190,
allowBlank:false
})
]
})
]
});

// simple button add
fs2.addButton('Load', function(){
fs2.getForm().load({url:'/ext3.4.0/examples/form/xml-form.xml', waitMsg:'Loading'});
});

// explicit add
var submit = fs2.addButton({
text: 'Submit',
disabled:true,
handler: function(){
fs2.getForm().submit({url:'xml-errors.xml', waitMsg:'Saving Data...', submitEmptyText: false});
}
});


fs2.on({
actioncomplete: function(form, action){
if(action.type == 'load'){
submit.enable();
}
}
});





var viewport = new Ext.Viewport({
layout: 'border',
items: [
{
region: 'north',
height: 35,
items:[
northTb
]
}, {
// lazily created panel (xtype:'panel' is default)
region: 'south',
split: true,
height: 100,
minSize: 100,
maxSize: 200,
collapsible: true,
title: 'South',
margins: '0 0 0 0'
}, {
region: 'east',
title: 'East Side',
collapsible: true,
split: true,
width: 225, // give east and west regions a width
minSize: 175,
maxSize: 400,
margins: '0 5 0 0',
layout: 'fit', // specify layout manager for items
items: // this TabPanel is wrapped by another Panel so the title will be applied
new Ext.TabPanel({
border: false, // already wrapped so don't add another border
activeTab: 2, // second tab initially active
tabPosition: 'bottom',
items: [
{
html: '<p>A TabPanel component can be a region.</p>',
title: 'A Tab',
autoScroll: true
},
{
html: '<p>A TabPanel component can be a region.</p>',
title: 'A Tab',
autoScroll: true
},
new Ext.grid.PropertyGrid({
title: 'Property Grid',
closable: true,
source: {
"(name)": "Properties Grid",
"grouping": false,
"autoFitColumns": true,
"productionQuality": false,
"created": new Date(Date.parse('10/15/2006')),
"tested": false,
"version": 0.01,
"borderWidth": 1
}
}

)]
})
}, {
region: 'west',
id: 'west-panel', // see Ext.getCmp() below
title: 'West',
split: true,
width: 200,
minSize: 175,
maxSize: 400,
collapsible: true,
margins: '0 0 0 5',
layout: {
type: 'accordion',
animate: true
},
items: [{
title: 'Navigation',
border: false,
iconCls: 'nav',
items: [
tree1
]
},{
title: 'Settings',
border: false,
iconCls: 'settings',
items: [
tree2
]
},{
title: 'Advanced',
border: false,
iconCls: 'settings',
items: [
tree3
]
},{
title: 'Misc',
border: false,
iconCls: 'settings',
items: [
tree4
]
},{
title: 'Admin',
border: false,
iconCls: 'settings',
items: [
tree5
]
}]
},
// in this instance the TabPanel is not wrapped by another panel
// since no title is needed, this Panel is added directly
// as a Container
new Ext.TabPanel({
region: 'center', // a center region is ALWAYS required for border layout
deferredRender: false,
activeTab: 0, // first tab initially active
items: [{
title: 'Close Me',
closable: true,
autoScroll: true,
items: [
gridForm
]
}, {
title: 'Center Panel 1',
autoScroll: true,
items:[

grid1
]
},{
title: 'Center Panel 2',
autoScroll: true,
items:[
fs1
]
},{
title: 'Center Panel 3',
autoScroll: true,
items:[
grid4
]
},{
title: 'Center Panel 4',
autoScroll: true,
items:[
grid2

]
},{
title: 'Center Panel 5',
autoScroll: true,
items:[
grid3
]
},{
title: 'Center Panel 6',
autoScroll: true,
items:[
fs2
]
},{
title: 'Center Panel 7',
autoScroll: true,
items:[{
contentEl: 'center7'
}]
}
]
})]
});
var end = new Date();
var endhours = now.getHours();
var endminutes = end.getMinutes();
var endseconds = end.getSeconds();
var endmilli = end.getMilliseconds();
var date2 = new Date(2011,06,05,endhours,endminutes,endseconds,endmilli)
var diffDays = Math.abs((date1.getTime() - date2.getTime())/1000);
alert("Total Load and layout Time"+' ' +diffDays);

});
// A reusable error reader class for XML forms
Ext.form.XmlErrorReader = function(){
Ext.form.XmlErrorReader.superclass.constructor.call(this, {
record : 'field',
success: '@success'
}, [
'id', 'msg'
]
);
};
Ext.extend(Ext.form.XmlErrorReader, Ext.data.XmlReader);
</script>
</head>
<body>
<div id="center7" class="x-hide-display">
<a id="hideit" href="#">Toggle the west region</a>
<p>My closable attribute is set to false so you can't close me. The other center panels can be closed.</p>
<p>The center panel automatically grows to fit the remaining space in the container that isn't taken up by the border regions.</p>
<hr>
<p>Lorem ipsum dolor sit amet, consectetuer adipiscing elit. Sed metus nibh, sodales a, porta at, vulputate eget, dui. Pellentesque ut nisl. Maecenas tortor turpis, interdum non, sodales non, iaculis ac, lacus. Vestibulum auctor, tortor quis iaculis malesuada, libero lectus bibendum purus, sit amet tincidunt quam turpis vel lacus. In pellentesque nisl non sem. Suspendisse nunc sem, pretium eget, cursus a, fringilla vel, urna. Aliquam commodo ullamcorper erat. Nullam vel justo in neque porttitor laoreet. Aenean lacus dui, consequat eu, adipiscing eget, nonummy non, nisi. Morbi nunc est, dignissim non, ornare sed, luctus eu, massa. Vivamus eget quam. Vivamus tincidunt diam nec urna. Curabitur velit. Quisque dolor magna, ornare sed, elementum porta, luctus in, leo.</p>
<p>Donec quis dui. Sed imperdiet. Nunc consequat, est eu sollicitudin gravida, mauris ligula lacinia mauris, eu porta dui nisl in velit. Nam congue, odio id auctor nonummy, augue lectus euismod nunc, in tristique turpis dolor sed urna. Donec sit amet quam eget diam fermentum pharetra. Integer tincidunt arcu ut purus. Cum sociis natoque penatibus et magnis dis parturient montes, nascetur ridiculus mus. Nulla blandit malesuada odio. Nam augue. Aenean molestie sapien in mi. Suspendisse tincidunt. Pellentesque tempus dui vitae sapien. Donec aliquam ipsum sit amet pede. Sed scelerisque mi a erat. Curabitur rutrum ullamcorper risus. Maecenas et lorem ut felis dictum viverra. Fusce sem. Donec pharetra nibh sit amet sapien.</p>
<p>Aenean ut orci sed ligula consectetuer pretium. Aliquam odio. Nam pellentesque enim. Nam tincidunt condimentum nisi. Maecenas convallis luctus ligula. Donec accumsan ornare risus. Vestibulum id magna a nunc posuere laoreet. Integer iaculis leo vitae nibh. Nam vulputate, mauris vitae luctus pharetra, pede neque bibendum tellus, facilisis commodo diam nisi eget lacus. Duis consectetuer pulvinar nisi. Cras interdum ultricies sem. Nullam tristique. Suspendisse elementum purus eu nisl. Nulla facilisi. Phasellus ultricies ullamcorper lorem. Sed euismod ante vitae lacus. Nam nunc leo, congue vehicula, luctus ac, tempus non, ante. Morbi suscipit purus a nulla. Sed eu diam.</p>
<p>Vestibulum ante ipsum primis in faucibus orci luctus et ultrices posuere cubilia Curae; Cras imperdiet felis id velit. Ut non quam at sem dictum ullamcorper. Vestibulum pharetra purus sed pede. Aliquam ultrices, nunc in varius mattis, felis justo pretium magna, eget laoreet justo eros id eros. Aliquam elementum diam fringilla nulla. Praesent laoreet sapien vel metus. Cras tempus, sapien condimentum dictum dapibus, lorem augue fringilla orci, ut tincidunt eros nisi eget turpis. Nullam nunc nunc, eleifend et, dictum et, pharetra a, neque. Ut feugiat. Aliquam erat volutpat. Donec pretium odio nec felis. Phasellus sagittis lacus eget sapien. Donec est. Vestibulum ante ipsum primis in faucibus orci luctus et ultrices posuere cubilia Curae;</p>
<p>Vestibulum semper. Nullam non odio. Aliquam quam. Mauris eu lectus non nunc auctor ullamcorper. Sed tincidunt molestie enim. Phasellus lobortis justo sit amet quam. Duis nulla erat, varius a, cursus in, tempor sollicitudin, mauris. Aliquam mi velit, consectetuer mattis, consequat tristique, pulvinar ac, nisl. Aliquam mattis vehicula elit. Proin quis leo sed tellus scelerisque molestie. Quisque luctus. Integer mattis. Donec id augue sed leo aliquam egestas. Quisque in sem. Donec dictum enim in dolor. Praesent non erat. Nulla ultrices vestibulum quam.</p>
<p>Duis hendrerit, est vel lobortis sagittis, tortor erat scelerisque tortor, sed pellentesque sem enim id metus. Maecenas at pede. Nulla velit libero, dictum at, mattis quis, sagittis vel, ante. Phasellus faucibus rutrum dui. Cras mauris elit, bibendum at, feugiat non, porta id, neque. Nulla et felis nec odio mollis vehicula. Donec elementum tincidunt mauris. Duis vel dui. Fusce iaculis enim ac nulla. In risus.</p>
<p>Donec gravida. Donec et enim. Morbi sollicitudin, lacus a facilisis pulvinar, odio turpis dapibus elit, in tincidunt turpis felis nec libero. Nam vestibulum tempus ipsum. In hac habitasse platea dictumst. Nulla facilisi. Donec semper ligula. Donec commodo tortor in quam. Etiam massa. Ut tempus ligula eget tellus. Curabitur id velit ut velit varius commodo. Vestibulum ante ipsum primis in faucibus orci luctus et ultrices posuere cubilia Curae; Nulla facilisi. Fusce ornare pellentesque libero. Nunc rhoncus. Suspendisse potenti. Ut consequat, leo eu accumsan vehicula, justo sem lobortis elit, ac sollicitudin ipsum neque nec ante.</p>
<p>Aliquam elementum mauris id sem. Vivamus varius, est ut nonummy consectetuer, nulla quam bibendum velit, ac gravida nisi felis sit amet urna. Aliquam nec risus. Maecenas lacinia purus ut velit. Vestibulum ante ipsum primis in faucibus orci luctus et ultrices posuere cubilia Curae; Suspendisse sit amet dui vitae lacus fermentum sodales. Donec varius dapibus nisl. Praesent at velit id risus convallis bibendum. Aliquam felis nibh, rutrum nec, blandit non, mattis sit amet, magna. Lorem ipsum dolor sit amet, consectetuer adipiscing elit. Pellentesque habitant morbi tristique senectus et netus et malesuada fames ac turpis egestas. Etiam varius dignissim nibh. Quisque id orci ac ante hendrerit molestie. Aliquam malesuada enim non neque.</p>
</div>

</body>
</html>


EXTJS 4.1. Pr 1


<html>
<head>
<title>Simple App EXTJS 4.1 PR 1</title>
<script>
//alert("start");
var oneDay = 24*60*60*1000; // hours*minutes*seconds*milliseconds
var now = new Date();
var starthours = now.getHours();
var startminutes = now.getMinutes();
var startseconds = now.getSeconds();
var startmilli = now.getMilliseconds();
var date1 = new Date(2011,06,05,starthours,startminutes,startseconds,startmilli)
</script>


<link rel="stylesheet" type="text/css" href="/ext4.1pr1/resources/css/ext-all.css" />
<style type="text/css">
p {
margin:5px;
}
.settings {
background-image:url(/ext4.1pr1/examples/shared/icons/fam/folder_wrench.png);
}
.nav {
background-image:url(/ext4.1pr1/examples/shared/icons/fam/folder_go.png);
}
.info {
background-image:url(/ext4.1pr1/examples/shared/icons/fam/information.png);
}
</style>
<script type="text/javascript" src="/ext4.1pr1/ext-all.js"></script>
<script type="text/javascript" src="/ext4.1pr1/examples/shared/states.js"></script>


<script type="text/javascript">
Ext.require(['*']);


Ext.onReady(function() {


Ext.QuickTips.init();


// NOTE: This is an example showing simple state management. During development,
// it is generally best to disable state management as dynamically-generated ids
// can change across page loads, leading to unpredictable results. The developer
// should ensure that stable state ids are set for stateful components in real apps.
Ext.state.Manager.setProvider(Ext.create('Ext.state.CookieProvider'));
Ext.BLANK_IMAGE_URL = '/ext3.4.0/resources/images/default/s.gif';


var northTb = new Ext.create('Ext.toolbar.Toolbar', {
region: 'north',
xtype: 'button',
items: [
{
text: 'Button 1',
scale: 'medium',
width: 100
},
{
text: 'Button 2',
scale: 'medium',
width: 100
},
{
text: 'Button 3',
scale: 'medium',
width: 100
},
{
text: 'Button 4',
scale: 'medium',
width: 100
},
{
text: 'Button 5',
scale: 'medium',
width: 100
},
{
text: 'Button 6',
scale: 'medium',
width: 100
},
{
text: 'Button 7',
scale: 'medium',
width: 100
}
]
})




var tstore1 = Ext.create('Ext.data.TreeStore', {
proxy: {
type: 'ajax',
url: '/ext4.1pr1/examples/tree/check-nodes.json'
},
sorters: [{
property: 'leaf',
direction: 'ASC'
}, {
property: 'text',
direction: 'ASC'
}]
});

var tree1 = Ext.create('Ext.tree.Panel', {
store: tstore1,
rootVisible: false,
useArrows: true,
frame: true,
title: 'Check Tree',
width: 200,
height: 250,
dockedItems: [{
xtype: 'toolbar',
items: {
text: 'Get checked nodes',
handler: function(){
var records = tree.getView().getChecked(),
names = [];

Ext.Array.each(records, function(rec){
names.push(rec.get('text'));
});

Ext.MessageBox.show({
title: 'Selected Nodes',
msg: names.join('<br />'),
icon: Ext.MessageBox.INFO
});
}
}
}]
});


var tstore2 = Ext.create('Ext.data.TreeStore', {
proxy: {
type: 'ajax',
url: '/ext4.1pr1/examples/tree/check-nodes.json'
},
sorters: [{
property: 'leaf',
direction: 'ASC'
}, {
property: 'text',
direction: 'ASC'
}]
});

var tree2 = Ext.create('Ext.tree.Panel', {
store: tstore2,
rootVisible: false,
useArrows: true,
frame: true,
title: 'Check Tree',
width: 200,
height: 250,
dockedItems: [{
xtype: 'toolbar',
items: {
text: 'Get checked nodes',
handler: function(){
var records = tree.getView().getChecked(),
names = [];

Ext.Array.each(records, function(rec){
names.push(rec.get('text'));
});

Ext.MessageBox.show({
title: 'Selected Nodes',
msg: names.join('<br />'),
icon: Ext.MessageBox.INFO
});
}
}
}]
});



var tstore3 = Ext.create('Ext.data.TreeStore', {
proxy: {
type: 'ajax',
url: '/ext4.1pr1/examples/tree/check-nodes.json'
},
sorters: [{
property: 'leaf',
direction: 'ASC'
}, {
property: 'text',
direction: 'ASC'
}]
});

var tree3 = Ext.create('Ext.tree.Panel', {
store: tstore3,
rootVisible: false,
useArrows: true,
frame: true,
title: 'Check Tree',
width: 200,
height: 250,
dockedItems: [{
xtype: 'toolbar',
items: {
text: 'Get checked nodes',
handler: function(){
var records = tree.getView().getChecked(),
names = [];

Ext.Array.each(records, function(rec){
names.push(rec.get('text'));
});

Ext.MessageBox.show({
title: 'Selected Nodes',
msg: names.join('<br />'),
icon: Ext.MessageBox.INFO
});
}
}
}]
});


var tstore4 = Ext.create('Ext.data.TreeStore', {
proxy: {
type: 'ajax',
url: '/ext4.1pr1/examples/tree/check-nodes.json'
},
sorters: [{
property: 'leaf',
direction: 'ASC'
}, {
property: 'text',
direction: 'ASC'
}]
});

var tree4 = Ext.create('Ext.tree.Panel', {
store: tstore4,
rootVisible: false,
useArrows: true,
frame: true,
title: 'Check Tree',
width: 200,
height: 250,
dockedItems: [{
xtype: 'toolbar',
items: {
text: 'Get checked nodes',
handler: function(){
var records = tree.getView().getChecked(),
names = [];

Ext.Array.each(records, function(rec){
names.push(rec.get('text'));
});

Ext.MessageBox.show({
title: 'Selected Nodes',
msg: names.join('<br />'),
icon: Ext.MessageBox.INFO
});
}
}
}]
});




var tstore5 = Ext.create('Ext.data.TreeStore', {
proxy: {
type: 'ajax',
url: '/ext4.1pr1/examples/tree/check-nodes.json'
},
sorters: [{
property: 'leaf',
direction: 'ASC'
}, {
property: 'text',
direction: 'ASC'
}]
});

var tree5 = Ext.create('Ext.tree.Panel', {
store: tstore5,
rootVisible: false,
useArrows: true,
frame: true,
title: 'Check Tree',
width: 200,
height: 250,
dockedItems: [{
xtype: 'toolbar',
items: {
text: 'Get checked nodes',
handler: function(){
var records = tree.getView().getChecked(),
names = [];

Ext.Array.each(records, function(rec){
names.push(rec.get('text'));
});

Ext.MessageBox.show({
title: 'Selected Nodes',
msg: names.join('<br />'),
icon: Ext.MessageBox.INFO
});
}
}
}]
});




Ext.define('Book1',{
extend: 'Ext.data.Model',
fields: [
// set up the fields mapping into the xml doc
// The first needs mapping, the others are very basic
{name: 'Author', mapping: 'ItemAttributes > Author'},
'Title', 'Manufacturer', 'ProductGroup'
]
});

// create the Data Store
var store1 = Ext.create('Ext.data.Store', {
model: 'Book1',
autoLoad: true,
proxy: {
// load using HTTP
type: 'ajax',
url: '/ext4.1pr1/examples/grid/sheldon.xml',
// the return will be XML, so lets set up a reader
reader: {
type: 'xml',
// records will have an "Item" tag
record: 'Item',
idProperty: 'ASIN',
totalRecords: '@total'
}
}
});

// create the grid
var grid1 = Ext.create('Ext.grid.Panel', {
store: store1,
height: 500,
columns: [
{text: "Author", flex: 1, dataIndex: 'Author', sortable: true},
{text: "Title", width: 180, dataIndex: 'Title', sortable: true},
{text: "Manufacturer", width: 115, dataIndex: 'Manufacturer', sortable: true},
{text: "Product Group", width: 100, dataIndex: 'ProductGroup', sortable: true}
]
});



Ext.define('Book2',{
extend: 'Ext.data.Model',
fields: [
// set up the fields mapping into the xml doc
// The first needs mapping, the others are very basic
{name: 'Author', mapping: 'ItemAttributes > Author'},
'Title', 'Manufacturer', 'ProductGroup'
]
});

// create the Data Store
var store2 = Ext.create('Ext.data.Store', {
model: 'Book2',
autoLoad: true,
proxy: {
// load using HTTP
type: 'ajax',
url: '/ext4.1pr1/examples/grid/sheldon.xml',
// the return will be XML, so lets set up a reader
reader: {
type: 'xml',
// records will have an "Item" tag
record: 'Item',
idProperty: 'ASIN',
totalRecords: '@total'
}
}
});

// create the grid
var grid2 = Ext.create('Ext.grid.Panel', {
store: store2,
height: 500,
columns: [
{text: "Author", flex: 1, dataIndex: 'Author', sortable: true},
{text: "Title", width: 180, dataIndex: 'Title', sortable: true},
{text: "Manufacturer", width: 115, dataIndex: 'Manufacturer', sortable: true},
{text: "Product Group", width: 100, dataIndex: 'ProductGroup', sortable: true}
]
});





Ext.define('Book3',{
extend: 'Ext.data.Model',
fields: [
// set up the fields mapping into the xml doc
// The first needs mapping, the others are very basic
{name: 'Author', mapping: 'ItemAttributes > Author'},
'Title', 'Manufacturer', 'ProductGroup'
]
});

// create the Data Store
var store3 = Ext.create('Ext.data.Store', {
model: 'Book3',
autoLoad: true,
proxy: {
// load using HTTP
type: 'ajax',
url: '/ext4.1pr1/examples/grid/sheldon.xml',
// the return will be XML, so lets set up a reader
reader: {
type: 'xml',
// records will have an "Item" tag
record: 'Item',
idProperty: 'ASIN',
totalRecords: '@total'
}
}
});

// create the grid
var grid3 = Ext.create('Ext.grid.Panel', {
store: store3,
height: 500,
columns: [
{text: "Author", flex: 1, dataIndex: 'Author', sortable: true},
{text: "Title", width: 180, dataIndex: 'Title', sortable: true},
{text: "Manufacturer", width: 115, dataIndex: 'Manufacturer', sortable: true},
{text: "Product Group", width: 100, dataIndex: 'ProductGroup', sortable: true}
]
});


Ext.define('Book4',{
extend: 'Ext.data.Model',
fields: [
// set up the fields mapping into the xml doc
// The first needs mapping, the others are very basic
{name: 'Author', mapping: 'ItemAttributes > Author'},
'Title', 'Manufacturer', 'ProductGroup'
]
});

// create the Data Store
var store4 = Ext.create('Ext.data.Store', {
model: 'Book4',
autoLoad: true,
proxy: {
// load using HTTP
type: 'ajax',
url: '/ext4.1pr1/examples/grid/sheldon.xml',
// the return will be XML, so lets set up a reader
reader: {
type: 'xml',
// records will have an "Item" tag
record: 'Item',
idProperty: 'ASIN',
totalRecords: '@total'
}
}
});

// create the grid
var grid4 = Ext.create('Ext.grid.Panel', {
store: store4,
height: 500,
columns: [
{text: "Author", flex: 1, dataIndex: 'Author', sortable: true},
{text: "Title", width: 180, dataIndex: 'Title', sortable: true},
{text: "Manufacturer", width: 115, dataIndex: 'Manufacturer', sortable: true},
{text: "Product Group", width: 100, dataIndex: 'ProductGroup', sortable: true}
]
});






var bd = Ext.getBody();
// sample static data for the store
var myData = [
['3m Co', 71.72, 0.02, 0.03, '9/1 12:00am'],
['Alcoa Inc', 29.01, 0.42, 1.47, '9/1 12:00am'],
['Altria Group Inc', 83.81, 0.28, 0.34, '9/1 12:00am'],
['American Express Company', 52.55, 0.01, 0.02, '9/1 12:00am'],
['American International Group, Inc.', 64.13, 0.31, 0.49, '9/1 12:00am'],
['AT&T Inc.', 31.61, -0.48, -1.54, '9/1 12:00am'],
['Boeing Co.', 75.43, 0.53, 0.71, '9/1 12:00am'],
['Caterpillar Inc.', 67.27, 0.92, 1.39, '9/1 12:00am'],
['Citigroup, Inc.', 49.37, 0.02, 0.04, '9/1 12:00am'],
['E.I. du Pont de Nemours and Company', 40.48, 0.51, 1.28, '9/1 12:00am'],
['Exxon Mobil Corp', 68.1, -0.43, -0.64, '9/1 12:00am'],
['General Electric Company', 34.14, -0.08, -0.23, '9/1 12:00am'],
['General Motors Corporation', 30.27, 1.09, 3.74, '9/1 12:00am'],
['Hewlett-Packard Co.', 36.53, -0.03, -0.08, '9/1 12:00am'],
['Honeywell Intl Inc', 38.77, 0.05, 0.13, '9/1 12:00am'],
['Intel Corporation', 19.88, 0.31, 1.58, '9/1 12:00am'],
['International Business Machines', 81.41, 0.44, 0.54, '9/1 12:00am'],
['Johnson & Johnson', 64.72, 0.06, 0.09, '9/1 12:00am'],
['JP Morgan & Chase & Co', 45.73, 0.07, 0.15, '9/1 12:00am'],
['McDonald\'s Corporation', 36.76, 0.86, 2.40, '9/1 12:00am'],
['Merck & Co., Inc.', 40.96, 0.41, 1.01, '9/1 12:00am'],
['Microsoft Corporation', 25.84, 0.14, 0.54, '9/1 12:00am'],
['Pfizer Inc', 27.96, 0.4, 1.45, '9/1 12:00am'],
['The Coca-Cola Company', 45.07, 0.26, 0.58, '9/1 12:00am'],
['The Home Depot, Inc.', 34.64, 0.35, 1.02, '9/1 12:00am'],
['The Procter & Gamble Company', 61.91, 0.01, 0.02, '9/1 12:00am'],
['United Technologies Corporation', 63.26, 0.55, 0.88, '9/1 12:00am'],
['Verizon Communications', 35.57, 0.39, 1.11, '9/1 12:00am'],
['Wal-Mart Stores, Inc.', 45.45, 0.73, 1.63, '9/1 12:00am']
];

var ds = Ext.create('Ext.data.ArrayStore', {
fields: [
{name: 'company'},
{name: 'price', type: 'float'},
{name: 'change', type: 'float'},
{name: 'pctChange', type: 'float'},
{name: 'lastChange', type: 'date', dateFormat: 'n/j h:ia'},
// Rating dependent upon performance 0 = best, 2 = worst
{name: 'rating', type: 'int', convert: function(value, record) {
var pct = record.get('pctChange');
if (pct < 0) return 2;
if (pct < 1) return 1;
return 0;
}}
],
data: myData
});


// example of custom renderer function
function change(val){
if(val > 0){
return '<span style="color:green;">' + val + '</span>';
}else if(val < 0){
return '<span style="color:red;">' + val + '</span>';
}
return val;
}
// example of custom renderer function
function pctChange(val){
if(val > 0){
return '<span style="color:green;">' + val + '%</span>';
}else if(val < 0){
return '<span style="color:red;">' + val + '%</span>';
}
return val;
}

// render rating as "A", "B" or "C" depending upon numeric value.
function rating(v) {
if (v == 0) return "A";
if (v == 1) return "B";
if (v == 2) return "C";
}


bd.createChild({tag: 'h2', html: 'Using a Grid with a Form'});

/*
* Here is where we create the Form
*/
var gridForm = Ext.create('Ext.form.Panel', {
id: 'company-form',
frame: true,
title: 'Company data',
bodyPadding: 5,
width: 750,
layout: 'column', // Specifies that the items will now be arranged in columns

fieldDefaults: {
labelAlign: 'left',
msgTarget: 'side'
},

items: [{
columnWidth: 0.60,
xtype: 'gridpanel',
store: ds,
height: 400,
title:'Company Data',

columns: [
{
id :'company',
text : 'Company',
flex: 1,
sortable : true,
dataIndex: 'company'
},
{
text : 'Price',
width : 75,
sortable : true,
dataIndex: 'price'
},
{
text : 'Change',
width : 75,
sortable : true,
renderer : change,
dataIndex: 'change'
},
{
text : '% Change',
width : 75,
sortable : true,
renderer : pctChange,
dataIndex: 'pctChange'
},
{
text : 'Last Updated',
width : 85,
sortable : true,
renderer : Ext.util.Format.dateRenderer('m/d/Y'),
dataIndex: 'lastChange'
},
{
text: 'Rating',
width: 30,
sortable: true,
renderer: rating,
dataIndex: 'rating'
}
],

listeners: {
selectionchange: function(model, records) {
if (records[0]) {
this.up('form').getForm().loadRecord(records[0]);
}
}
}
}, {
columnWidth: 0.4,
margin: '0 0 0 10',
xtype: 'fieldset',
title:'Company details',
defaults: {
width: 240,
labelWidth: 90
},
defaultType: 'textfield',
items: [{
fieldLabel: 'Name',
name: 'company'
},{
fieldLabel: 'Price',
name: 'price'
},{
fieldLabel: '% Change',
name: 'pctChange'
},{
xtype: 'datefield',
fieldLabel: 'Last Updated',
name: 'lastChange'
}, {
xtype: 'radiogroup',
fieldLabel: 'Rating',
columns: 3,
defaults: {
name: 'rating' //Each radio has the same name so the browser will make sure only one is checked at once
},
items: [{
inputValue: '0',
boxLabel: 'A'
}, {
inputValue: '1',
boxLabel: 'B'
}, {
inputValue: '2',
boxLabel: 'C'
}]
}]
}]

});












Ext.define('example.contact1', {
extend: 'Ext.data.Model',
fields: [
{name: 'first', mapping: 'name > first'},
{name: 'last', mapping: 'name > last'},
'company', 'email', 'state',
{name: 'dob', type: 'date', dateFormat: 'm/d/Y'}
]
});

Ext.define('example.fielderror1', {
extend: 'Ext.data.Model',
fields: ['id', 'msg']
});

var formPanel1 = Ext.create('Ext.form.Panel', {
frame: true,
title:'XML Form',
width: 340,
bodyPadding: 5,
waitMsgTarget: true,

fieldDefaults: {
labelAlign: 'right',
labelWidth: 85,
msgTarget: 'side'
},

// configure how to read the XML data
reader : Ext.create('Ext.data.reader.Xml', {
model: 'example.contact1',
record : 'contact',
successProperty: '@success'
}),

// configure how to read the XML errors
errorReader: Ext.create('Ext.data.reader.Xml', {
model: 'example.fielderror1',
record : 'field',
successProperty: '@success'
}),

items: [{
xtype: 'fieldset',
title: 'Contact Information',
defaultType: 'textfield',
defaults: {
width: 280
},
items: [{
fieldLabel: 'First Name',
emptyText: 'First Name',
name: 'first'
}, {
fieldLabel: 'Last Name',
emptyText: 'Last Name',
name: 'last'
}, {
fieldLabel: 'Company',
name: 'company'
}, {
fieldLabel: 'Email',
name: 'email',
vtype:'email'
}, {
xtype: 'combobox',
fieldLabel: 'State',
name: 'state',
store: Ext.create('Ext.data.ArrayStore', {
fields: ['abbr', 'state'],
data : Ext.example.states // from states.js
}),
valueField: 'abbr',
displayField: 'state',
typeAhead: true,
queryMode: 'local',
emptyText: 'Select a state...'
}, {
xtype: 'datefield',
fieldLabel: 'Date of Birth',
name: 'dob',
allowBlank: false,
maxValue: new Date()
}
]
}],

buttons: [{
text: 'Load',
handler: function(){
formPanel1.getForm().load({
url: '/ext4.1pr1/examples/form/xml-form-data.xml',
waitMsg: 'Loading...'
});
}
}, {
text: 'Submit',
disabled: true,
formBind: true,
handler: function(){
this.up('form').getForm().submit({
url: 'xml-form-errors.xml',
submitEmptyText: false,
waitMsg: 'Saving Data...'
});
}
}]
});





Ext.define('example.contact2', {
extend: 'Ext.data.Model',
fields: [
{name: 'first', mapping: 'name > first'},
{name: 'last', mapping: 'name > last'},
'company', 'email', 'state',
{name: 'dob', type: 'date', dateFormat: 'm/d/Y'}
]
});

Ext.define('example.fielderror2', {
extend: 'Ext.data.Model',
fields: ['id', 'msg']
});

var formPanel2 = Ext.create('Ext.form.Panel', {
frame: true,
title:'XML Form',
width: 340,
bodyPadding: 5,
waitMsgTarget: true,

fieldDefaults: {
labelAlign: 'right',
labelWidth: 85,
msgTarget: 'side'
},

// configure how to read the XML data
reader : Ext.create('Ext.data.reader.Xml', {
model: 'example.contact2',
record : 'contact',
successProperty: '@success'
}),

// configure how to read the XML errors
errorReader: Ext.create('Ext.data.reader.Xml', {
model: 'example.fielderror2',
record : 'field',
successProperty: '@success'
}),

items: [{
xtype: 'fieldset',
title: 'Contact Information',
defaultType: 'textfield',
defaults: {
width: 280
},
items: [{
fieldLabel: 'First Name',
emptyText: 'First Name',
name: 'first'
}, {
fieldLabel: 'Last Name',
emptyText: 'Last Name',
name: 'last'
}, {
fieldLabel: 'Company',
name: 'company'
}, {
fieldLabel: 'Email',
name: 'email',
vtype:'email'
}, {
xtype: 'combobox',
fieldLabel: 'State',
name: 'state',
store: Ext.create('Ext.data.ArrayStore', {
fields: ['abbr', 'state'],
data : Ext.example.states // from states.js
}),
valueField: 'abbr',
displayField: 'state',
typeAhead: true,
queryMode: 'local',
emptyText: 'Select a state...'
}, {
xtype: 'datefield',
fieldLabel: 'Date of Birth',
name: 'dob',
allowBlank: false,
maxValue: new Date()
}
]
}],

buttons: [{
text: 'Load',
handler: function(){
formPanel2.getForm().load({
url: '/ext4.1pr1/examples/form/xml-form-data.xml',
waitMsg: 'Loading...'
});
}
}, {
text: 'Submit',
disabled: true,
formBind: true,
handler: function(){
this.up('form').getForm().submit({
url: 'xml-form-errors.xml',
submitEmptyText: false,
waitMsg: 'Saving Data...'
});
}
}]
});








var viewport = Ext.create('Ext.Viewport', {
id: 'border-example',
layout: 'border',
items: [
{
region: 'north',
height: 38,
items:[
northTb
]
}, {
// lazily created panel (xtype:'panel' is default)
region: 'south',
split: true,
height: 100,
minSize: 100,
maxSize: 200,
collapsible: true,
collapsed: true,
title: 'South',
margins: '0 0 0 0'
}, {
xtype: 'tabpanel',
region: 'east',
title: 'East Side',
dockedItems: [{
dock: 'top',
xtype: 'toolbar',
items: [ '->', {
xtype: 'button',
text: 'test',
tooltip: 'Test Button'
}]
}],
animCollapse: true,
collapsible: true,
split: true,
width: 225, // give east and west regions a width
minSize: 175,
maxSize: 400,
margins: '0 5 0 0',
activeTab: 2,
tabPosition: 'bottom',
items: [{
html: '<p>A TabPanel component can be a region.</p>',
title: 'A Tab',
autoScroll: true
},{
html: '<p>A TabPanel component can be a region.</p>',
title: 'A Tab',
autoScroll: true
}, Ext.create('Ext.grid.PropertyGrid', {
title: 'Property Grid',
closable: true,
source: {
"(name)": "Properties Grid",
"grouping": false,
"autoFitColumns": true,
"productionQuality": false,
"created": Ext.Date.parse('10/15/2006', 'm/d/Y'),
"tested": false,
"version": 0.01,
"borderWidth": 1
}
})]
}, {
region: 'west',
stateId: 'navigation-panel',
id: 'west-panel', // see Ext.getCmp() below
title: 'West',
split: true,
width: 200,
minWidth: 175,
maxWidth: 400,
collapsible: true,
animCollapse: true,
margins: '0 0 0 5',
layout: 'accordion',
items: [{
title: 'Navigation',
iconCls: 'nav',
items:[
tree1
]
}, {
title: 'Settings',
iconCls: 'settings',
items:[
tree2
]
}, {
title: 'Advanced',
iconCls: 'settings',
items:[
tree3
]
}, {
title: 'Misc',
iconCls: 'settings',
items:[
tree4
]
}, {
title: 'Admin',
iconCls: 'settings',
items:[
tree5
]
}

]
},
// in this instance the TabPanel is not wrapped by another panel
// since no title is needed, this Panel is added directly
// as a Container
Ext.create('Ext.tab.Panel', {
region: 'center', // a center region is ALWAYS required for border layout
deferredRender: false,
activeTab: 0, // first tab initially active
items: [
{
title: 'Close Me',
closable: true,
autoScroll: true,
items:[
gridForm
]
},
{
title: 'Center Panel 1',
autoScroll: true,
items:[
grid1
]
},
{
title: 'Center Panel 2',
autoScroll: true,
items:[
formPanel1
]
},
{
title: 'Center Panel 3',
autoScroll: true,
items:[
grid2
]
},
{
title: 'Center Panel 4',
autoScroll: true,
items:[
grid3
]
},
{
title: 'Center Panel 5',
autoScroll: true,
items:[
grid4
]
},
{
title: 'Center Panel 6',
autoScroll: true,
items:[
formPanel2
]
},
{
title: 'Center Panel 7',
autoScroll: true,
items:[
{
contentEl: 'center7'
}
]
}
]
})]
});

var end = new Date();
var endhours = now.getHours();
var endminutes = end.getMinutes();
var endseconds = end.getSeconds();
var endmilli = end.getMilliseconds();
var date2 = new Date(2011,06,05,endhours,endminutes,endseconds,endmilli)
var diffDays = Math.abs((date1.getTime() - date2.getTime())/1000);
alert("Total Load and layout Time"+' ' +diffDays);


});
</script>
</head>
<body>
<div id="center7" class="x-hide-display">
<a id="hideit" href="#">Toggle the west region</a>
<p>My closable attribute is set to false so you can't close me. The other center panels can be closed.</p>
<p>The center panel automatically grows to fit the remaining space in the container that isn't taken up by the border regions.</p>
<hr>
<p>Lorem ipsum dolor sit amet, consectetuer adipiscing elit. Sed metus nibh, sodales a, porta at, vulputate eget, dui. Pellentesque ut nisl. Maecenas tortor turpis, interdum non, sodales non, iaculis ac, lacus. Vestibulum auctor, tortor quis iaculis malesuada, libero lectus bibendum purus, sit amet tincidunt quam turpis vel lacus. In pellentesque nisl non sem. Suspendisse nunc sem, pretium eget, cursus a, fringilla vel, urna. Aliquam commodo ullamcorper erat. Nullam vel justo in neque porttitor laoreet. Aenean lacus dui, consequat eu, adipiscing eget, nonummy non, nisi. Morbi nunc est, dignissim non, ornare sed, luctus eu, massa. Vivamus eget quam. Vivamus tincidunt diam nec urna. Curabitur velit. Quisque dolor magna, ornare sed, elementum porta, luctus in, leo.</p>
<p>Donec quis dui. Sed imperdiet. Nunc consequat, est eu sollicitudin gravida, mauris ligula lacinia mauris, eu porta dui nisl in velit. Nam congue, odio id auctor nonummy, augue lectus euismod nunc, in tristique turpis dolor sed urna. Donec sit amet quam eget diam fermentum pharetra. Integer tincidunt arcu ut purus. Cum sociis natoque penatibus et magnis dis parturient montes, nascetur ridiculus mus. Nulla blandit malesuada odio. Nam augue. Aenean molestie sapien in mi. Suspendisse tincidunt. Pellentesque tempus dui vitae sapien. Donec aliquam ipsum sit amet pede. Sed scelerisque mi a erat. Curabitur rutrum ullamcorper risus. Maecenas et lorem ut felis dictum viverra. Fusce sem. Donec pharetra nibh sit amet sapien.</p>
<p>Aenean ut orci sed ligula consectetuer pretium. Aliquam odio. Nam pellentesque enim. Nam tincidunt condimentum nisi. Maecenas convallis luctus ligula. Donec accumsan ornare risus. Vestibulum id magna a nunc posuere laoreet. Integer iaculis leo vitae nibh. Nam vulputate, mauris vitae luctus pharetra, pede neque bibendum tellus, facilisis commodo diam nisi eget lacus. Duis consectetuer pulvinar nisi. Cras interdum ultricies sem. Nullam tristique. Suspendisse elementum purus eu nisl. Nulla facilisi. Phasellus ultricies ullamcorper lorem. Sed euismod ante vitae lacus. Nam nunc leo, congue vehicula, luctus ac, tempus non, ante. Morbi suscipit purus a nulla. Sed eu diam.</p>
<p>Vestibulum ante ipsum primis in faucibus orci luctus et ultrices posuere cubilia Curae; Cras imperdiet felis id velit. Ut non quam at sem dictum ullamcorper. Vestibulum pharetra purus sed pede. Aliquam ultrices, nunc in varius mattis, felis justo pretium magna, eget laoreet justo eros id eros. Aliquam elementum diam fringilla nulla. Praesent laoreet sapien vel metus. Cras tempus, sapien condimentum dictum dapibus, lorem augue fringilla orci, ut tincidunt eros nisi eget turpis. Nullam nunc nunc, eleifend et, dictum et, pharetra a, neque. Ut feugiat. Aliquam erat volutpat. Donec pretium odio nec felis. Phasellus sagittis lacus eget sapien. Donec est. Vestibulum ante ipsum primis in faucibus orci luctus et ultrices posuere cubilia Curae;</p>
<p>Vestibulum semper. Nullam non odio. Aliquam quam. Mauris eu lectus non nunc auctor ullamcorper. Sed tincidunt molestie enim. Phasellus lobortis justo sit amet quam. Duis nulla erat, varius a, cursus in, tempor sollicitudin, mauris. Aliquam mi velit, consectetuer mattis, consequat tristique, pulvinar ac, nisl. Aliquam mattis vehicula elit. Proin quis leo sed tellus scelerisque molestie. Quisque luctus. Integer mattis. Donec id augue sed leo aliquam egestas. Quisque in sem. Donec dictum enim in dolor. Praesent non erat. Nulla ultrices vestibulum quam.</p>
<p>Duis hendrerit, est vel lobortis sagittis, tortor erat scelerisque tortor, sed pellentesque sem enim id metus. Maecenas at pede. Nulla velit libero, dictum at, mattis quis, sagittis vel, ante. Phasellus faucibus rutrum dui. Cras mauris elit, bibendum at, feugiat non, porta id, neque. Nulla et felis nec odio mollis vehicula. Donec elementum tincidunt mauris. Duis vel dui. Fusce iaculis enim ac nulla. In risus.</p>
<p>Donec gravida. Donec et enim. Morbi sollicitudin, lacus a facilisis pulvinar, odio turpis dapibus elit, in tincidunt turpis felis nec libero. Nam vestibulum tempus ipsum. In hac habitasse platea dictumst. Nulla facilisi. Donec semper ligula. Donec commodo tortor in quam. Etiam massa. Ut tempus ligula eget tellus. Curabitur id velit ut velit varius commodo. Vestibulum ante ipsum primis in faucibus orci luctus et ultrices posuere cubilia Curae; Nulla facilisi. Fusce ornare pellentesque libero. Nunc rhoncus. Suspendisse potenti. Ut consequat, leo eu accumsan vehicula, justo sem lobortis elit, ac sollicitudin ipsum neque nec ante.</p>
<p>Aliquam elementum mauris id sem. Vivamus varius, est ut nonummy consectetuer, nulla quam bibendum velit, ac gravida nisi felis sit amet urna. Aliquam nec risus. Maecenas lacinia purus ut velit. Vestibulum ante ipsum primis in faucibus orci luctus et ultrices posuere cubilia Curae; Suspendisse sit amet dui vitae lacus fermentum sodales. Donec varius dapibus nisl. Praesent at velit id risus convallis bibendum. Aliquam felis nibh, rutrum nec, blandit non, mattis sit amet, magna. Lorem ipsum dolor sit amet, consectetuer adipiscing elit. Pellentesque habitant morbi tristique senectus et netus et malesuada fames ac turpis egestas. Etiam varius dignissim nibh. Quisque id orci ac ante hendrerit molestie. Aliquam malesuada enim non neque.</p>
</div>

</body>
</html>

dongryphon
5 Nov 2011, 10:30 PM
@MrSparks

Thanks for the example. My hope in asking was to see how apps compose and configure the components and containers because this plays a huge part in overall performance. There are many other things as well, of course, but some combinations can be pathological (especially in 4.0). So if the example code you posted is more similar to your app than is our stock examples, I think we have gained a helpful data point.

Again, thanks! I will let you know what I see ... once my branch is back to working :)

MrSparks
6 Nov 2011, 2:53 AM
@Don,

I had tried to make the example a little more realistic. i.e. nested / sub border layouts within the tab areas. However 4.1 PR1 doesn't work well with that kind of config at the moment.

dongryphon
6 Nov 2011, 8:14 PM
@MrSparks,

NP if it doesn't work in 4.1 - then it will be a good correctness/compat test case as well :) I would love to have something that got close to the 20+ seconds load times that you were seeing in 4.0 (iirc)... to help us set the bar where it needs to be.

Thanks again!

Gummy
6 Nov 2011, 8:59 PM
@Gummy & @ftrack. I think this is a great idea. I've started a thread here to try to gather performance tips from the community:

http://www.sencha.com/forum/showthread.php?153565
Nice, there are many advices already, thanks :)

MrSparks
7 Nov 2011, 4:02 AM
@Don,

Ok not problem. I'll produce a more complex example that works under 4.0.7
Will have that done for the end of today.

MrSparks
7 Nov 2011, 11:03 AM
@Don,

As promised, here an example app that performs as follows.

FYI: I managed to get the layouts working under 4.1 PR1, so its safe to profile against that framework

IE 8 - EXT JS 3.4.0 - 4.078 Seconds
Chrome 15 - EXT JS 3.4.0 - 1.227 Seconds

IE 8 - EXT JS 4.1 PR1 - 22.406 Seconds
Chrome 15 - EXT JS 4.1 PR 1 - 2.731 Seconds

EXT JS 3.4.0


<html>
<head>
<title>Simple App EXTJS 3.4.0</title>
<script>
//alert("start");
var oneDay = 24*60*60*1000; // hours*minutes*seconds*milliseconds
var now = new Date();
var starthours = now.getHours();
var startminutes = now.getMinutes();
var startseconds = now.getSeconds();
var startmilli = now.getMilliseconds();
var date1 = new Date(2011,06,05,starthours,startminutes,startseconds,startmilli)
</script>
<link rel="stylesheet" type="text/css" href="/ext3.4.0/resources/css/ext-all.css" />

<style type="text/css">
html, body {
font:normal 12px verdana;
margin:0;
padding:0;
border:0 none;
overflow:hidden;
height:100%;
}
p {
margin:5px;
}
.settings {
background-image:url(/ext3.4.0/examples/shared/icons/fam/folder_wrench.png);
}
.nav {
background-image:url(/ext3.4.0/examples/shared/icons/fam/folder_go.png);
}
</style>


<!-- GC -->
<!-- LIBS -->
<script type="text/javascript" src="/ext3.4.0/adapter/ext/ext-base.js"></script>
<!-- ENDLIBS -->


<script type="text/javascript" src="/ext3.4.0/ext-all.js"></script>


<!-- EXAMPLES -->
<script type="text/javascript" src="/ext3.4.0/examples/ux/SearchField.js"></script>
<script type="text/javascript" src="/ext3.4.0/examples/form/states.js"></script>

<script type="text/javascript">
Ext.onReady(function(){

// NOTE: This is an example showing simple state management. During development,
// it is generally best to disable state management as dynamically-generated ids
// can change across page loads, leading to unpredictable results. The developer
// should ensure that stable state ids are set for stateful components in real apps.
Ext.state.Manager.setProvider(new Ext.state.CookieProvider());
Ext.BLANK_IMAGE_URL = '/ext3.4.0/resources/images/default/s.gif';
Ext.QuickTips.init();

northTb = new Ext.Toolbar ({
region: 'north',
xtype: 'button',
items: [
{
text: 'Button 1',
scale: 'medium',
width: 100,
handler: function(){
Ext.getCmp('card-panel').getLayout().setActiveItem('tabPanel1');
}
},
{
text: 'Button 2',
scale: 'medium',
width: 100,
handler: function(){
Ext.getCmp('card-panel').getLayout().setActiveItem('tabPanel2');
}
},
{
text: 'Button 3',
scale: 'medium',
width: 100,
handler: function(){
Ext.getCmp('card-panel').getLayout().setActiveItem('tabPanel3');
}
},
{
text: 'Button 4',
scale: 'medium',
width: 100,
handler: function(){
Ext.getCmp('card-panel').getLayout().setActiveItem('tabPanel4');
}
},
{
text: 'Button 5',
scale: 'medium',
width: 100,
handler: function(){
Ext.getCmp('card-panel').getLayout().setActiveItem('tabPanel5');
}
},
{
text: 'Button 6',
scale: 'medium',
width: 100,
handler: function(){
Ext.getCmp('card-panel').getLayout().setActiveItem('tabPanel6');
}
},
{
text: 'Button 7',
scale: 'medium',
width: 100,
handler: function(){
Ext.getCmp('card-panel').getLayout().setActiveItem('tabPanel7');
}
}
]
})



var tree1 = new Ext.tree.TreePanel({
title: 'My Task List 1',
useArrows:true,
autoScroll:true,
animate:true,
enableDD:true,
containerScroll: true,
rootVisible: false,
frame: true,
root: {
nodeType: 'async'
},

// auto create TreeLoader
dataUrl: '/ext3.4.0/examples/tree/check-nodes.json',

listeners: {
'checkchange': function(node, checked){
if(checked){
node.getUI().addClass('complete');
}else{
node.getUI().removeClass('complete');
}
}
},

buttons: [{
text: 'Get Completed Tasks',
handler: function(){
var msg = '', selNodes = tree1.getChecked();
Ext.each(selNodes, function(node){
if(msg.length > 0){
msg += ', ';
}
msg += node.text;
});
Ext.Msg.show({
title: 'Completed Tasks',
msg: msg.length > 0 ? msg : 'None',
icon: Ext.Msg.INFO,
minWidth: 200,
buttons: Ext.Msg.OK
});
}
}]
});

var tree2 = new Ext.tree.TreePanel({
title: 'My Task List 2',
useArrows:true,
autoScroll:true,
animate:true,
enableDD:true,
containerScroll: true,
rootVisible: false,
frame: true,
root: {
nodeType: 'async'
},

// auto create TreeLoader
dataUrl: '/ext3.4.0/examples/tree/check-nodes.json',

listeners: {
'checkchange': function(node, checked){
if(checked){
node.getUI().addClass('complete');
}else{
node.getUI().removeClass('complete');
}
}
},

buttons: [{
text: 'Get Completed Tasks',
handler: function(){
var msg = '', selNodes = tree2.getChecked();
Ext.each(selNodes, function(node){
if(msg.length > 0){
msg += ', ';
}
msg += node.text;
});
Ext.Msg.show({
title: 'Completed Tasks',
msg: msg.length > 0 ? msg : 'None',
icon: Ext.Msg.INFO,
minWidth: 200,
buttons: Ext.Msg.OK
});
}
}]
});

var tree3 = new Ext.tree.TreePanel({
title: 'My Task List 3',
useArrows:true,
autoScroll:true,
animate:true,
enableDD:true,
containerScroll: true,
rootVisible: false,
frame: true,
root: {
nodeType: 'async'
},

// auto create TreeLoader
dataUrl: '/ext3.4.0/examples/tree/check-nodes.json',

listeners: {
'checkchange': function(node, checked){
if(checked){
node.getUI().addClass('complete');
}else{
node.getUI().removeClass('complete');
}
}
},

buttons: [{
text: 'Get Completed Tasks',
handler: function(){
var msg = '', selNodes = tree3.getChecked();
Ext.each(selNodes, function(node){
if(msg.length > 0){
msg += ', ';
}
msg += node.text;
});
Ext.Msg.show({
title: 'Completed Tasks',
msg: msg.length > 0 ? msg : 'None',
icon: Ext.Msg.INFO,
minWidth: 200,
buttons: Ext.Msg.OK
});
}
}]
});



var tree4 = new Ext.tree.TreePanel({
title: 'My Task List 4',
useArrows:true,
autoScroll:true,
animate:true,
enableDD:true,
containerScroll: true,
rootVisible: false,
frame: true,
root: {
nodeType: 'async'
},

// auto create TreeLoader
dataUrl: '/ext3.4.0/examples/tree/check-nodes.json',

listeners: {
'checkchange': function(node, checked){
if(checked){
node.getUI().addClass('complete');
}else{
node.getUI().removeClass('complete');
}
}
},

buttons: [{
text: 'Get Completed Tasks',
handler: function(){
var msg = '', selNodes = tree4.getChecked();
Ext.each(selNodes, function(node){
if(msg.length > 0){
msg += ', ';
}
msg += node.text;
});
Ext.Msg.show({
title: 'Completed Tasks',
msg: msg.length > 0 ? msg : 'None',
icon: Ext.Msg.INFO,
minWidth: 200,
buttons: Ext.Msg.OK
});
}
}]
});

var tree5 = new Ext.tree.TreePanel({
title: 'My Task List 5',
useArrows:true,
autoScroll:true,
animate:true,
enableDD:true,
containerScroll: true,
rootVisible: false,
frame: true,
root: {
nodeType: 'async'
},

// auto create TreeLoader
dataUrl: '/ext3.4.0/examples/tree/check-nodes.json',

listeners: {
'checkchange': function(node, checked){
if(checked){
node.getUI().addClass('complete');
}else{
node.getUI().removeClass('complete');
}
}
},

buttons: [{
text: 'Get Completed Tasks',
handler: function(){
var msg = '', selNodes = tree5.getChecked();
Ext.each(selNodes, function(node){
if(msg.length > 0){
msg += ', ';
}
msg += node.text;
});
Ext.Msg.show({
title: 'Completed Tasks',
msg: msg.length > 0 ? msg : 'None',
icon: Ext.Msg.INFO,
minWidth: 200,
buttons: Ext.Msg.OK
});
}
}]
});



var store1 = new Ext.data.Store({
// load using HTTP
url: '/ext3.4.0/examples/grid/sheldon.xml',

// the return will be XML, so lets set up a reader
reader: new Ext.data.XmlReader({
// records will have an "Item" tag
record: 'Item',
id: 'ASIN',
totalRecords: '@total'
}, [
// set up the fields mapping into the xml doc
// The first needs mapping, the others are very basic
{name: 'Author', mapping: 'ItemAttributes > Author'},
'Title', 'Manufacturer', 'ProductGroup'
])
});

// create the grid
var grid1 = new Ext.grid.GridPanel({
store: store1,
height: 500,
columns: [
{header: "Author", width: 120, dataIndex: 'Author', sortable: true},
{header: "Title", width: 180, dataIndex: 'Title', sortable: true},
{header: "Manufacturer", width: 115, dataIndex: 'Manufacturer', sortable: true},
{header: "Product Group", width: 100, dataIndex: 'ProductGroup', sortable: true}
]
});
store1.load();

var store2 = new Ext.data.Store({
// load using HTTP
url: '/ext3.4.0/examples/grid/sheldon.xml',

// the return will be XML, so lets set up a reader
reader: new Ext.data.XmlReader({
// records will have an "Item" tag
record: 'Item',
id: 'ASIN',
totalRecords: '@total'
}, [
// set up the fields mapping into the xml doc
// The first needs mapping, the others are very basic
{name: 'Author', mapping: 'ItemAttributes > Author'},
'Title', 'Manufacturer', 'ProductGroup'
])
});

// create the grid
var grid2 = new Ext.grid.GridPanel({
store: store2,
height: 500,
columns: [
{header: "Author", width: 120, dataIndex: 'Author', sortable: true},
{header: "Title", width: 180, dataIndex: 'Title', sortable: true},
{header: "Manufacturer", width: 115, dataIndex: 'Manufacturer', sortable: true},
{header: "Product Group", width: 100, dataIndex: 'ProductGroup', sortable: true}
]
});
store2.load();


var store3 = new Ext.data.Store({
// load using HTTP
url: '/ext3.4.0/examples/grid/sheldon.xml',

// the return will be XML, so lets set up a reader
reader: new Ext.data.XmlReader({
// records will have an "Item" tag
record: 'Item',
id: 'ASIN',
totalRecords: '@total'
}, [
// set up the fields mapping into the xml doc
// The first needs mapping, the others are very basic
{name: 'Author', mapping: 'ItemAttributes > Author'},
'Title', 'Manufacturer', 'ProductGroup'
])
});

// create the grid
var grid3 = new Ext.grid.GridPanel({
store: store3,
height: 500,
columns: [
{header: "Author", width: 120, dataIndex: 'Author', sortable: true},
{header: "Title", width: 180, dataIndex: 'Title', sortable: true},
{header: "Manufacturer", width: 115, dataIndex: 'Manufacturer', sortable: true},
{header: "Product Group", width: 100, dataIndex: 'ProductGroup', sortable: true}
]
});
store3.load();


var store4 = new Ext.data.Store({
// load using HTTP
url: '/ext3.4.0/examples/grid/sheldon.xml',

// the return will be XML, so lets set up a reader
reader: new Ext.data.XmlReader({
// records will have an "Item" tag
record: 'Item',
id: 'ASIN',
totalRecords: '@total'
}, [
// set up the fields mapping into the xml doc
// The first needs mapping, the others are very basic
{name: 'Author', mapping: 'ItemAttributes > Author'},
'Title', 'Manufacturer', 'ProductGroup'
])
});

// create the grid
var grid4 = new Ext.grid.GridPanel({
store: store4,
height: 500,
columns: [
{header: "Author", width: 120, dataIndex: 'Author', sortable: true},
{header: "Title", width: 180, dataIndex: 'Title', sortable: true},
{header: "Manufacturer", width: 115, dataIndex: 'Manufacturer', sortable: true},
{header: "Product Group", width: 100, dataIndex: 'ProductGroup', sortable: true}
]
});
store4.load();


// turn on validation errors beside the field globally
Ext.form.Field.prototype.msgTarget = 'side';

var bd = Ext.getBody();

// Define the Grid data and create the Grid
var myData = [
['3m Co',71.72,0.02,0.03,'9/1 12:00am'],
['Alcoa Inc',29.01,0.42,1.47,'9/1 12:00am'],
['Altria Group Inc',83.81,0.28,0.34,'9/1 12:00am'],
['American Express Company',52.55,0.01,0.02,'9/1 12:00am'],
['American International Group, Inc.',64.13,0.31,0.49,'9/1 12:00am'],
['AT&T Inc.',31.61,-0.48,-1.54,'9/1 12:00am'],
['Boeing Co.',75.43,0.53,0.71,'9/1 12:00am'],
['Caterpillar Inc.',67.27,0.92,1.39,'9/1 12:00am'],
['Citigroup, Inc.',49.37,0.02,0.04,'9/1 12:00am'],
['E.I. du Pont de Nemours and Company',40.48,0.51,1.28,'9/1 12:00am'],
['Exxon Mobil Corp',68.1,-0.43,-0.64,'9/1 12:00am'],
['General Electric Company',34.14,-0.08,-0.23,'9/1 12:00am'],
['General Motors Corporation',30.27,1.09,3.74,'9/1 12:00am'],
['Hewlett-Packard Co.',36.53,-0.03,-0.08,'9/1 12:00am'],
['Honeywell Intl Inc',38.77,0.05,0.13,'9/1 12:00am'],
['Intel Corporation',19.88,0.31,1.58,'9/1 12:00am'],
['International Business Machines',81.41,0.44,0.54,'9/1 12:00am'],
['Johnson & Johnson',64.72,0.06,0.09,'9/1 12:00am'],
['JP Morgan & Chase & Co',45.73,0.07,0.15,'9/1 12:00am'],
['McDonald\'s Corporation',36.76,0.86,2.40,'9/1 12:00am'],
['Merck & Co., Inc.',40.96,0.41,1.01,'9/1 12:00am'],
['Microsoft Corporation',25.84,0.14,0.54,'9/1 12:00am'],
['Pfizer Inc',27.96,0.4,1.45,'9/1 12:00am'],
['The Coca-Cola Company',45.07,0.26,0.58,'9/1 12:00am'],
['The Home Depot, Inc.',34.64,0.35,1.02,'9/1 12:00am'],
['The Procter & Gamble Company',61.91,0.01,0.02,'9/1 12:00am'],
['United Technologies Corporation',63.26,0.55,0.88,'9/1 12:00am'],
['Verizon Communications',35.57,0.39,1.11,'9/1 12:00am'],
['Wal-Mart Stores, Inc.',45.45,0.73,1.63,'9/1 12:00am']
];

var ds = new Ext.data.Store({
reader: new Ext.data.ArrayReader({}, [
{name: 'company'},
{name: 'price', type: 'float'},
{name: 'change', type: 'float'},
{name: 'pctChange', type: 'float'},
{name: 'lastChange', type: 'date', dateFormat: 'n/j h:ia'},

// Rating dependent upon performance 0 = best, 2 = worst
{name: 'rating', type: 'int', convert: function(v, rec) {
if (rec[3] < 0) return 2;
if (rec[3] < 1) return 1;
return 0;
}
}
])
});
ds.loadData(myData);

// example of custom renderer function
function italic(value){
return '<i>' + value + '</i>';
}

// example of custom renderer function
function change(val){
if(val > 0){
return '<span style="color:green;">' + val + '</span>';
}else if(val < 0){
return '<span style="color:red;">' + val + '</span>';
}
return val;
}
// example of custom renderer function
function pctChange(val){
if(val > 0){
return '<span style="color:green;">' + val + '%</span>';
}else if(val < 0){
return '<span style="color:red;">' + val + '%</span>';
}
return val;
}

// render rating as "A", "B" or "C" depending upon numeric value.
function rating(v) {
if (v == 0) return "A"
if (v == 1) return "B"
if (v == 2) return "C"
}

// the DefaultColumnModel expects this blob to define columns. It can be extended to provide
// custom or reusable ColumnModels
var colModel = new Ext.grid.ColumnModel([
{id:'company',header: "Company", width: 160, sortable: true, locked:false, dataIndex: 'company'},
{header: "Price", width: 55, sortable: true, renderer: Ext.util.Format.usMoney, dataIndex: 'price'},
{header: "Change", width: 55, sortable: true, renderer: change, dataIndex: 'change'},
{header: "% Change", width: 65, sortable: true, renderer: pctChange, dataIndex: 'pctChange'},
{header: "Last Updated", width: 80, sortable: true, renderer: Ext.util.Format.dateRenderer('m/d/Y'), dataIndex: 'lastChange'},
{header: "Rating", width: 40, sortable: true, renderer: rating, dataIndex: 'rating'}
]);

bd.createChild({tag: 'h2', html: 'Using a Grid with a Form'});

/*
* Here is where we create the Form
*/
var gridForm = new Ext.FormPanel({
id: 'company-form',
frame: true,
labelAlign: 'left',
title: 'Company data',
bodyStyle:'padding:5px',
width: 750,
layout: 'column', // Specifies that the items will now be arranged in columns
items: [{
columnWidth: 0.60,
layout: 'fit',
items: {
xtype: 'grid',
ds: ds,
cm: colModel,
sm: new Ext.grid.RowSelectionModel({
singleSelect: true,
listeners: {
rowselect: function(sm, row, rec) {
Ext.getCmp("company-form").getForm().loadRecord(rec);
}
}
}),
autoExpandColumn: 'company',
height: 350,
title:'Company Data',
border: true,
listeners: {
viewready: function(g) {
g.getSelectionModel().selectRow(0);
} // Allow rows to be rendered.
}
}
},{
columnWidth: 0.4,
xtype: 'fieldset',
labelWidth: 90,
title:'Company details',
defaults: {width: 140, border:false}, // Default config options for child items
defaultType: 'textfield',
autoHeight: true,
bodyStyle: Ext.isIE ? 'padding:0 0 5px 15px;' : 'padding:10px 15px;',
border: false,
style: {
"margin-left": "10px", // when you add custom margin in IE 6...
"margin-right": Ext.isIE6 ? (Ext.isStrict ? "-10px" : "-13px") : "0" // you have to adjust for it somewhere else
},
items: [{
fieldLabel: 'Name',
name: 'company'
},{
fieldLabel: 'Price',
name: 'price'
},{
fieldLabel: '% Change',
name: 'pctChange'
},{
xtype: 'datefield',
fieldLabel: 'Last Updated',
name: 'lastChange'
}, {
xtype: 'radiogroup',
columns: 'auto',
fieldLabel: 'Rating',
// A radio group: A setValue on any of the following 'radio' inputs using the numeric
// 'rating' field checks the radio instance which has the matching inputValue.
items: [{
name: 'rating',
inputValue: 0,
boxLabel: 'A'
}, {
name: 'rating',
inputValue: 1,
boxLabel: 'B'
}, {
name: 'rating',
inputValue: 2,
boxLabel: 'C'
}]
}]
}]
});


// turn on validation errors beside the field globally
Ext.form.Field.prototype.msgTarget = 'side';

var fs1 = new Ext.FormPanel({
frame: true,
title:'XML Form',
labelAlign: 'right',
labelWidth: 85,
width:340,
waitMsgTarget: true,

// configure how to read the XML Data
reader : new Ext.data.XmlReader({
record : 'contact',
success: '@success'
}, [
{name: 'first', mapping:'name/first'}, // custom mapping
{name: 'last', mapping:'name/last'},
'company', 'email', 'state',
{name: 'dob', type:'date', dateFormat:'m/d/Y'} // custom data types
]),

// reusable eror reader class defined at the end of this file
errorReader: new Ext.form.XmlErrorReader(),

items: [
new Ext.form.FieldSet({
title: 'Contact Information',
autoHeight: true,
defaultType: 'textfield',
items: [{
fieldLabel: 'First Name',
emptyText: 'First Name',
name: 'first',
width:190
}, {
fieldLabel: 'Last Name',
emptyText: 'Last Name',
name: 'last',
width:190
}, {
fieldLabel: 'Company',
name: 'company',
width:190
}, {
fieldLabel: 'Email',
name: 'email',
vtype:'email',
width:190
},

new Ext.form.ComboBox({
fieldLabel: 'State',
hiddenName:'state',
store: new Ext.data.ArrayStore({
fields: ['abbr', 'state'],
data : Ext.exampledata.states // from states.js
}),
valueField:'abbr',
displayField:'state',
typeAhead: true,
mode: 'local',
triggerAction: 'all',
emptyText:'Select a state...',
selectOnFocus:true,
width:190
}),

new Ext.form.DateField({
fieldLabel: 'Date of Birth',
name: 'dob',
width:190,
allowBlank:false
})
]
})
]
});

// simple button add
fs1.addButton('Load', function(){
fs1.getForm().load({url:'/ext3.4.0/examples/form/xml-form.xml', waitMsg:'Loading'});
});

// explicit add
var submit = fs1.addButton({
text: 'Submit',
disabled:true,
handler: function(){
fs1.getForm().submit({url:'xml-errors.xml', waitMsg:'Saving Data...', submitEmptyText: false});
}
});

fs1.on({
actioncomplete: function(form, action){
if(action.type == 'load'){
submit.enable();
}
}
});



// turn on validation errors beside the field globally
Ext.form.Field.prototype.msgTarget = 'side';
var fs2 = new Ext.FormPanel({
frame: true,
title:'XML Form',
labelAlign: 'right',
labelWidth: 85,
width:340,
waitMsgTarget: true,

// configure how to read the XML Data
reader : new Ext.data.XmlReader({
record : 'contact',
success: '@success'
}, [
{name: 'first', mapping:'name/first'}, // custom mapping
{name: 'last', mapping:'name/last'},
'company', 'email', 'state',
{name: 'dob', type:'date', dateFormat:'m/d/Y'} // custom data types
]),

// reusable eror reader class defined at the end of this file
errorReader: new Ext.form.XmlErrorReader(),

items: [
new Ext.form.FieldSet({
title: 'Contact Information',
autoHeight: true,
defaultType: 'textfield',
items: [{
fieldLabel: 'First Name',
emptyText: 'First Name',
name: 'first',
width:190
}, {
fieldLabel: 'Last Name',
emptyText: 'Last Name',
name: 'last',
width:190
}, {
fieldLabel: 'Company',
name: 'company',
width:190
}, {
fieldLabel: 'Email',
name: 'email',
vtype:'email',
width:190
},

new Ext.form.ComboBox({
fieldLabel: 'State',
hiddenName:'state',
store: new Ext.data.ArrayStore({
fields: ['abbr', 'state'],
data : Ext.exampledata.states // from states.js
}),
valueField:'abbr',
displayField:'state',
typeAhead: true,
mode: 'local',
triggerAction: 'all',
emptyText:'Select a state...',
selectOnFocus:true,
width:190
}),

new Ext.form.DateField({
fieldLabel: 'Date of Birth',
name: 'dob',
width:190,
allowBlank:false
})
]
})
]
});

// simple button add
fs2.addButton('Load', function(){
fs2.getForm().load({url:'/ext3.4.0/examples/form/xml-form.xml', waitMsg:'Loading'});
});

// explicit add
var submit = fs2.addButton({
text: 'Submit',
disabled:true,
handler: function(){
fs2.getForm().submit({url:'xml-errors.xml', waitMsg:'Saving Data...', submitEmptyText: false});
}
});


fs2.on({
actioncomplete: function(form, action){
if(action.type == 'load'){
submit.enable();
}
}
});

var tabPanel1 = new Ext.TabPanel({
id: 'tabPanel1',
html: 'Panel 1',
deferredRender: false,
activeTab: 0, // first tab initially active
items: [
{
title: 'Close Me',
closable: true,
html: 'Panel 1',
autoScroll: true,
items:[
gridForm
]
},
{
title: 'Center Panel 1',
autoScroll: true,
items:[
grid1
]
},
{
title: 'Center Panel 2',
autoScroll: true,
items:[
//fs1
]
},
{
title: 'Center Panel 3',
autoScroll: true,
items:[
grid2
]
},
{
title: 'Center Panel 4',
autoScroll: true,
items:[
grid3
]
},
{
title: 'Center Panel 5',
autoScroll: true,
items:[
grid4
]
},
{
title: 'Center Panel 6',
autoScroll: true,
items:[
//fs2
]
},
{
title: 'Center Panel 7',
autoScroll: true,
items:[
{
contentEl: 'center7'
}
]
}
]
});

var tabPanel2 = new Ext.TabPanel({
id: 'tabPanel2',
deferredRender: false,
activeTab: 0, // first tab initially active
items: [
{
title: 'Close Me',
closable: true,
layout: 'border',
html: 'Panel 2',
autoScroll: true,
items:[
{
xtype: 'panel',
region: 'north',
html: 'north'
},
{
xtype: 'panel',
title: 'test',
region: 'center',
html: 'center p 2'

},
{
xtype: 'panel',
region: 'south',
html: 'south'
}
]
},
{
title: 'Center Panel 1',
autoScroll: true,
items:[
{
xtype: 'panel',
region: 'north',
html: 'north'
},
{
xtype: 'panel',
title: 'test',
region: 'center',
html: 'center'

},
{
xtype: 'panel',
region: 'south',
html: 'south'
}

]
},
{
title: 'Center Panel 2',
autoScroll: true,
items:[
{
xtype: 'panel',
region: 'north',
html: 'north'
},
{
xtype: 'panel',
title: 'test',
region: 'center',
html: 'center'

},
{
xtype: 'panel',
region: 'south',
html: 'south'
}

]
},
{
title: 'Center Panel 3',
autoScroll: true,
items:[
{
xtype: 'panel',
region: 'north',
html: 'north'
},
{
xtype: 'panel',
title: 'test',
region: 'center',
html: 'center'

},
{
xtype: 'panel',
region: 'south',
html: 'south'
}

]
},
{
title: 'Center Panel 4',
autoScroll: true,
items:[
{
xtype: 'panel',
region: 'north',
html: 'north'
},
{
xtype: 'panel',
title: 'test',
region: 'center',
html: 'center'

},
{
xtype: 'panel',
region: 'south',
html: 'south'
}

]
},
{
title: 'Center Panel 5',
autoScroll: true,
items:[
{
xtype: 'panel',
region: 'north',
html: 'north'
},
{
xtype: 'panel',
title: 'test',
region: 'center',
html: 'center'

},
{
xtype: 'panel',
region: 'south',
html: 'south'
}

]
},
{
title: 'Center Panel 6',
autoScroll: true,
items:[
{
xtype: 'panel',
region: 'north',
html: 'north'
},
{
xtype: 'panel',
title: 'test',
region: 'center',
html: 'center'

},
{
xtype: 'panel',
region: 'south',
html: 'south'
}

]
},
{
title: 'Center Panel 7',
autoScroll: true,
items:[
{
xtype: 'panel',
region: 'north',
html: 'north'
},
{
xtype: 'panel',
title: 'test',
region: 'center',
html: 'center'

},
{
xtype: 'panel',
region: 'south',
html: 'south'
}
]
}
]
});


var tabPanel3 = new Ext.TabPanel({
id: 'tabPanel3',
deferredRender: false,
activeTab: 0, // first tab initially active
items: [
{
title: 'Close Me',
closable: true,
html: 'Panel 3',
autoScroll: true,
items:[
{
xtype: 'panel',
region: 'north',
html: 'north'
},
{
xtype: 'panel',
title: 'test',
region: 'center',
html: 'center p 3'

},
{
xtype: 'panel',
region: 'south',
html: 'south'
}

]
},
{
title: 'Center Panel 1',
autoScroll: true,
items:[
{
xtype: 'panel',
region: 'north',
html: 'north'
},
{
xtype: 'panel',
title: 'test',
region: 'center',
html: 'center'

},
{
xtype: 'panel',
region: 'south',
html: 'south'
}

]
},
{
title: 'Center Panel 2',
autoScroll: true,
items:[
{
xtype: 'panel',
region: 'north',
html: 'north'
},
{
xtype: 'panel',
title: 'test',
region: 'center',
html: 'center'

},
{
xtype: 'panel',
region: 'south',
html: 'south'
}

]
},
{
title: 'Center Panel 3',
autoScroll: true,
items:[
{
xtype: 'panel',
region: 'north',
html: 'north'
},
{
xtype: 'panel',
title: 'test',
region: 'center',
html: 'center'

},
{
xtype: 'panel',
region: 'south',
html: 'south'
}

]
},
{
title: 'Center Panel 4',
autoScroll: true,
items:[
{
xtype: 'panel',
region: 'north',
html: 'north'
},
{
xtype: 'panel',
title: 'test',
region: 'center',
html: 'center'

},
{
xtype: 'panel',
region: 'south',
html: 'south'
}

]
},
{
title: 'Center Panel 5',
autoScroll: true,
items:[
{




xtype: 'panel',
region: 'north',
html: 'north'
},
{
xtype: 'panel',
title: 'test',
region: 'center',
html: 'center'

},
{
xtype: 'panel',
region: 'south',
html: 'south'
}

]
},
{
title: 'Center Panel 6',
autoScroll: true,
items:[
{
xtype: 'panel',
region: 'north',
html: 'north'
},
{
xtype: 'panel',
title: 'test',
region: 'center',
html: 'center'

},
{
xtype: 'panel',
region: 'south',
html: 'south'
}

]
},
{
title: 'Center Panel 7',
autoScroll: true,
items:[
{
xtype: 'panel',
region: 'north',
html: 'north'
},
{
xtype: 'panel',
title: 'test',
region: 'center',
html: 'center'

},
{
xtype: 'panel',
region: 'south',
html: 'south'
}

]
}
]
});

var tabPanel4 = new Ext.TabPanel({
id: 'tabPanel4',
deferredRender: false,
activeTab: 0, // first tab initially active
items: [
{
title: 'Close Me',
closable: true,
html: 'Panel 4',
autoScroll: true,
items:[
{
xtype: 'panel',
region: 'north',
html: 'north'
},
{
xtype: 'panel',
title: 'test',
region: 'center',
html: 'center p 4'

},
{
xtype: 'panel',
region: 'south',
html: 'south'
}

]
},
{
title: 'Center Panel 1',
autoScroll: true,
items:[
{
xtype: 'panel',
region: 'north',
html: 'north'
},
{
xtype: 'panel',
title: 'test',
region: 'center',
html: 'center'

},
{
xtype: 'panel',
region: 'south',
html: 'south'
}

]
},
{
title: 'Center Panel 2',
autoScroll: true,
items:[
{
xtype: 'panel',
region: 'north',
html: 'north'
},
{
xtype: 'panel',
title: 'test',
region: 'center',
html: 'center'

},
{
xtype: 'panel',
region: 'south',
html: 'south'
}

]
},
{
title: 'Center Panel 3',
autoScroll: true,
items:[
{
xtype: 'panel',
region: 'north',
html: 'north'
},
{
xtype: 'panel',
title: 'test',
region: 'center',
html: 'center'

},
{
xtype: 'panel',
region: 'south',
html: 'south'
}

]
},
{
title: 'Center Panel 4',
autoScroll: true,
items:[
{
xtype: 'panel',
region: 'north',
html: 'north'
},
{
xtype: 'panel',
title: 'test',
region: 'center',
html: 'center'

},
{
xtype: 'panel',
region: 'south',
html: 'south'
}

]
},
{
title: 'Center Panel 5',
autoScroll: true,
items:[
{
xtype: 'panel',
region: 'north',
html: 'north'
},
{
xtype: 'panel',


title: 'test',
region: 'center',
html: 'center'

},
{
xtype: 'panel',
region: 'south',
html: 'south'
}

]
},
{
title: 'Center Panel 6',
autoScroll: true,
items:[
{
xtype: 'panel',
region: 'north',
html: 'north'
},
{
xtype: 'panel',
title: 'test',
region: 'center',
html: 'center'

},
{
xtype: 'panel',
region: 'south',
html: 'south'
}

]
},
{
title: 'Center Panel 7',
autoScroll: true,
items:[
{
xtype: 'panel',
region: 'north',
html: 'north'
},
{
xtype: 'panel',
title: 'test',
region: 'center',
html: 'center'

},
{
xtype: 'panel',
region: 'south',
html: 'south'
}
]
}
]
});

var tabPanel5 = new Ext.TabPanel({
id: 'tabPanel5',
deferredRender: false,
activeTab: 0, // first tab initially active
items: [
{
title: 'Close Me',
closable: true,
html: 'Panel 5',
autoScroll: true,
items:[
{
xtype: 'panel',
region: 'north',
html: 'north'
},
{
xtype: 'panel',
title: 'test',
region: 'center',
html: 'center p 5'

},
{
xtype: 'panel',
region: 'south',
html: 'south'
}

]
},
{
title: 'Center Panel 1',
autoScroll: true,
items:[
{
xtype: 'panel',
region: 'north',
html: 'north'
},
{
xtype: 'panel',
title: 'test',
region: 'center',
html: 'center'

},
{
xtype: 'panel',
region: 'south',
html: 'south'
}

]
},
{
title: 'Center Panel 2',
autoScroll: true,
items:[
{
xtype: 'panel',
region: 'north',
html: 'north'
},
{
xtype: 'panel',
title: 'test',
region: 'center',
html: 'center'

},
{
xtype: 'panel',
region: 'south',
html: 'south'
}

]
},
{
title: 'Center Panel 3',
autoScroll: true,
items:[
{
xtype: 'panel',
region: 'north',
html: 'north'
},
{
xtype: 'panel',
title: 'test',
region: 'center',
html: 'center'

},
{
xtype: 'panel',
region: 'south',
html: 'south'
}

]
},
{
title: 'Center Panel 4',
autoScroll: true,
items:[
{
xtype: 'panel',
region: 'north',
html: 'north'
},
{
xtype: 'panel',
title: 'test',
region: 'center',
html: 'center'

},
{
xtype: 'panel',
region: 'south',
html: 'south'
}

]
},
{
title: 'Center Panel 5',
autoScroll: true,
items:[
{
xtype: 'panel',
region: 'north',
html: 'north'
},
{
xtype: 'panel',
title: 'test',
region: 'center',
html: 'center'

},
{
xtype: 'panel',
region: 'south',
html: 'south'
}

]
},
{
title: 'Center Panel 6',
autoScroll: true,
items:[
{
xtype: 'panel',
region: 'north',
html: 'north'
},
{
xtype: 'panel',
title: 'test',
region: 'center',
html: 'center'

},
{
xtype: 'panel',
region: 'south',
html: 'south'
}
]
},
{
title: 'Center Panel 7',
autoScroll: true,
items:[
{
xtype: 'panel',
region: 'north',
html: 'north'
},
{
xtype: 'panel',
title: 'test',
region: 'center',
html: 'center'

},
{
xtype: 'panel',
region: 'south',
html: 'south'
}
]
}
]
});

var tabPanel6 = new Ext.TabPanel({
id: 'tabPanel6',
deferredRender: false,
activeTab: 0, // first tab initially active
items: [
{
title: 'Close Me',
closable: true,
html: 'Panel 6',
autoScroll: true,
items:[
{
xtype: 'panel',
region: 'north',
html: 'north'
},
{
xtype: 'panel',
title: 'test',
region: 'center',
html: 'center p 6'

},
{
xtype: 'panel',
region: 'south',
html: 'south'
}
]
},
{
title: 'Center Panel 1',
autoScroll: true,
items:[
{
xtype: 'panel',
region: 'north',
html: 'north'
},
{
xtype: 'panel',
title: 'test',
region: 'center',
html: 'center'

},
{
xtype: 'panel',
region: 'south',
html: 'south'
}
]
},
{
title: 'Center Panel 2',
autoScroll: true,
items:[
{
xtype: 'panel',
region: 'north',
html: 'north'
},
{
xtype: 'panel',
title: 'test',
region: 'center',
html: 'center'

},
{
xtype: 'panel',
region: 'south',
html: 'south'
}
]
},
{
title: 'Center Panel 3',
autoScroll: true,
items:[
{
xtype: 'panel',
region: 'north',
html: 'north'
},
{
xtype: 'panel',
title: 'test',
region: 'center',
html: 'center'

},
{
xtype: 'panel',
region: 'south',
html: 'south'
}
]
},
{
title: 'Center Panel 4',
autoScroll: true,
items:[
{
xtype: 'panel',
region: 'north',
html: 'north'
},
{
xtype: 'panel',
title: 'test',
region: 'center',
html: 'center'

},
{
xtype: 'panel',
region: 'south',
html: 'south'
}
]
},
{
title: 'Center Panel 5',
autoScroll: true,
items:[
{
xtype: 'panel',
region: 'north',
html: 'north'
},
{
xtype: 'panel',
title: 'test',
region: 'center',
html: 'center'

},
{
xtype: 'panel',
region: 'south',
html: 'south'
}
]
},
{
title: 'Center Panel 6',
autoScroll: true,
items:[
{
xtype: 'panel',
region: 'north',
html: 'north'
},
{
xtype: 'panel',
title: 'test',
region: 'center',
html: 'center'

},
{
xtype: 'panel',
region: 'south',
html: 'south'
}
]
},
{
title: 'Center Panel 7',
autoScroll: true,
items:[
{
xtype: 'panel',
region: 'north',
html: 'north'
},
{
xtype: 'panel',
title: 'test',
region: 'center',
html: 'center'

},
{
xtype: 'panel',
region: 'south',
html: 'south'
}
]
}
]
});

var tabPanel7 = new Ext.TabPanel({
id: 'tabPanel7',
deferredRender: false,
activeTab: 0, // first tab initially active
items: [
{
title: 'Close Me',
closable: true,
html: 'Panel 7',
autoScroll: true,
items:[
{
xtype: 'panel',
region: 'north',
html: 'north'
},
{
xtype: 'panel',
title: 'test',
region: 'center',
html: 'center p 7'

},
{
xtype: 'panel',
region: 'south',
html: 'south'
}
]
},
{
title: 'Center Panel 1',
autoScroll: true,
items:[
{
xtype: 'panel',
region: 'north',
html: 'north'
},
{
xtype: 'panel',
title: 'test',
region: 'center',
html: 'center'

},
{
xtype: 'panel',
region: 'south',
html: 'south'
}
]
},
{
title: 'Center Panel 2',
autoScroll: true,
items:[
{
xtype: 'panel',
region: 'north',
html: 'north'
},
{
xtype: 'panel',
title: 'test',
region: 'center',
html: 'center'

},
{
xtype: 'panel',
region: 'south',
html: 'south'
}
]
},
{
title: 'Center Panel 3',
autoScroll: true,
items:[
{
xtype: 'panel',
region: 'north',
html: 'north'
},
{
xtype: 'panel',
title: 'test',
region: 'center',
html: 'center'

},
{
xtype: 'panel',
region: 'south',
html: 'south'
}
]
},
{
title: 'Center Panel 4',
autoScroll: true,
items:[
{
xtype: 'panel',
region: 'north',
html: 'north'
},
{
xtype: 'panel',
title: 'test',
region: 'center',
html: 'center'

},
{
xtype: 'panel',
region: 'south',
html: 'south'
}
]
},
{
title: 'Center Panel 5',
autoScroll: true,
items:[
{
xtype: 'panel',
region: 'north',
html: 'north'
},
{
xtype: 'panel',
title: 'test',
region: 'center',
html: 'center'

},
{
xtype: 'panel',
region: 'south',
html: 'south'
}
]
},
{
title: 'Center Panel 6',
autoScroll: true,
items:[
{
xtype: 'panel',
region: 'north',
html: 'north'
},
{
xtype: 'panel',
title: 'test',
region: 'center',
html: 'center'

},
{
xtype: 'panel',
region: 'south',
html: 'south'
}
]
},
{
title: 'Center Panel 7',
autoScroll: true,
items:[
{
xtype: 'panel',
region: 'north',
html: 'north'
},
{
xtype: 'panel',
title: 'test',
region: 'center',
html: 'center'

},
{
xtype: 'panel',
region: 'south',
html: 'south'
}
]
}
]
});


var cardPanel = new Ext.Panel({
region: 'center',
id: 'card-panel',
layout: 'card',
border: false,
margins: '0 0 0 2',
activeItem: 0,
layout: 'card',
name: 'test',
items:[
tabPanel1,
tabPanel2,
tabPanel3,
tabPanel4,
tabPanel5,
tabPanel6,
tabPanel7
]
})




var viewport = new Ext.Viewport({
layout: 'border',
items: [
{
region: 'north',
height: 35,
items:[
northTb
]
}, {
// lazily created panel (xtype:'panel' is default)
region: 'south',
split: true,
height: 100,
minSize: 100,
maxSize: 200,
collapsible: true,
title: 'South',
margins: '0 0 0 0'
}, {
region: 'east',
title: 'East Side',
collapsible: true,
split: true,
width: 225, // give east and west regions a width
minSize: 175,
maxSize: 400,
margins: '0 5 0 0',
layout: 'fit', // specify layout manager for items
items: // this TabPanel is wrapped by another Panel so the title will be applied
new Ext.TabPanel({
border: false, // already wrapped so don't add another border
activeTab: 2, // second tab initially active
tabPosition: 'bottom',
items: [
{
html: '<p>A TabPanel component can be a region.</p>',
title: 'A Tab',
autoScroll: true
},
{
html: '<p>A TabPanel component can be a region.</p>',
title: 'A Tab',
autoScroll: true
},
new Ext.grid.PropertyGrid({
title: 'Property Grid',
closable: true,
source: {
"(name)": "Properties Grid",
"grouping": false,
"autoFitColumns": true,
"productionQuality": false,
"created": new Date(Date.parse('10/15/2006')),
"tested": false,
"version": 0.01,
"borderWidth": 1
}
}

)]
})
}, {
region: 'west',
id: 'west-panel', // see Ext.getCmp() below
title: 'West',
split: true,
width: 200,
minSize: 175,
maxSize: 400,
collapsible: true,
margins: '0 0 0 5',
layout: {
type: 'accordion',
animate: true
},
items: [{
title: 'Navigation',
border: false,
iconCls: 'nav',
items: [
tree1
]
},{
title: 'Settings',
border: false,
iconCls: 'settings',
items: [
tree2
]
},{
title: 'Advanced',
border: false,
iconCls: 'settings',
items: [
tree3
]
},{
title: 'Misc',
border: false,
iconCls: 'settings',
items: [
tree4
]
},{
title: 'Admin',
border: false,
iconCls: 'settings',
items: [
tree5
]
}]
},
cardPanel
]
});


var end = new Date();
var endhours = now.getHours();
var endminutes = end.getMinutes();
var endseconds = end.getSeconds();
var endmilli = end.getMilliseconds();
var date2 = new Date(2011,06,05,endhours,endminutes,endseconds,endmilli)
var diffDays = Math.abs((date1.getTime() - date2.getTime())/1000);
alert("Total Load and layout Time"+' ' +diffDays);


});
// A reusable error reader class for XML forms
Ext.form.XmlErrorReader = function(){
Ext.form.XmlErrorReader.superclass.constructor.call(this, {
record : 'field',
success: '@success'
}, [
'id', 'msg'
]
);
};
Ext.extend(Ext.form.XmlErrorReader, Ext.data.XmlReader);
</script>
</head>
<body>
<div id="center7" class="x-hide-display">
<a id="hideit" href="#">Toggle the west region</a>
<p>My closable attribute is set to false so you can't close me. The other center panels can be closed.</p>
<p>The center panel automatically grows to fit the remaining space in the container that isn't taken up by the border regions.</p>
<hr>
<p>Lorem ipsum dolor sit amet, consectetuer adipiscing elit. Sed metus nibh, sodales a, porta at, vulputate eget, dui. Pellentesque ut nisl. Maecenas tortor turpis, interdum non, sodales non, iaculis ac, lacus. Vestibulum auctor, tortor quis iaculis malesuada, libero lectus bibendum purus, sit amet tincidunt quam turpis vel lacus. In pellentesque nisl non sem. Suspendisse nunc sem, pretium eget, cursus a, fringilla vel, urna. Aliquam commodo ullamcorper erat. Nullam vel justo in neque porttitor laoreet. Aenean lacus dui, consequat eu, adipiscing eget, nonummy non, nisi. Morbi nunc est, dignissim non, ornare sed, luctus eu, massa. Vivamus eget quam. Vivamus tincidunt diam nec urna. Curabitur velit. Quisque dolor magna, ornare sed, elementum porta, luctus in, leo.</p>
<p>Donec quis dui. Sed imperdiet. Nunc consequat, est eu sollicitudin gravida, mauris ligula lacinia mauris, eu porta dui nisl in velit. Nam congue, odio id auctor nonummy, augue lectus euismod nunc, in tristique turpis dolor sed urna. Donec sit amet quam eget diam fermentum pharetra. Integer tincidunt arcu ut purus. Cum sociis natoque penatibus et magnis dis parturient montes, nascetur ridiculus mus. Nulla blandit malesuada odio. Nam augue. Aenean molestie sapien in mi. Suspendisse tincidunt. Pellentesque tempus dui vitae sapien. Donec aliquam ipsum sit amet pede. Sed scelerisque mi a erat. Curabitur rutrum ullamcorper risus. Maecenas et lorem ut felis dictum viverra. Fusce sem. Donec pharetra nibh sit amet sapien.</p>
<p>Aenean ut orci sed ligula consectetuer pretium. Aliquam odio. Nam pellentesque enim. Nam tincidunt condimentum nisi. Maecenas convallis luctus ligula. Donec accumsan ornare risus. Vestibulum id magna a nunc posuere laoreet. Integer iaculis leo vitae nibh. Nam vulputate, mauris vitae luctus pharetra, pede neque bibendum tellus, facilisis commodo diam nisi eget lacus. Duis consectetuer pulvinar nisi. Cras interdum ultricies sem. Nullam tristique. Suspendisse elementum purus eu nisl. Nulla facilisi. Phasellus ultricies ullamcorper lorem. Sed euismod ante vitae lacus. Nam nunc leo, congue vehicula, luctus ac, tempus non, ante. Morbi suscipit purus a nulla. Sed eu diam.</p>
<p>Vestibulum ante ipsum primis in faucibus orci luctus et ultrices posuere cubilia Curae; Cras imperdiet felis id velit. Ut non quam at sem dictum ullamcorper. Vestibulum pharetra purus sed pede. Aliquam ultrices, nunc in varius mattis, felis justo pretium magna, eget laoreet justo eros id eros. Aliquam elementum diam fringilla nulla. Praesent laoreet sapien vel metus. Cras tempus, sapien condimentum dictum dapibus, lorem augue fringilla orci, ut tincidunt eros nisi eget turpis. Nullam nunc nunc, eleifend et, dictum et, pharetra a, neque. Ut feugiat. Aliquam erat volutpat. Donec pretium odio nec felis. Phasellus sagittis lacus eget sapien. Donec est. Vestibulum ante ipsum primis in faucibus orci luctus et ultrices posuere cubilia Curae;</p>
<p>Vestibulum semper. Nullam non odio. Aliquam quam. Mauris eu lectus non nunc auctor ullamcorper. Sed tincidunt molestie enim. Phasellus lobortis justo sit amet quam. Duis nulla erat, varius a, cursus in, tempor sollicitudin, mauris. Aliquam mi velit, consectetuer mattis, consequat tristique, pulvinar ac, nisl. Aliquam mattis vehicula elit. Proin quis leo sed tellus scelerisque molestie. Quisque luctus. Integer mattis. Donec id augue sed leo aliquam egestas. Quisque in sem. Donec dictum enim in dolor. Praesent non erat. Nulla ultrices vestibulum quam.</p>
<p>Duis hendrerit, est vel lobortis sagittis, tortor erat scelerisque tortor, sed pellentesque sem enim id metus. Maecenas at pede. Nulla velit libero, dictum at, mattis quis, sagittis vel, ante. Phasellus faucibus rutrum dui. Cras mauris elit, bibendum at, feugiat non, porta id, neque. Nulla et felis nec odio mollis vehicula. Donec elementum tincidunt mauris. Duis vel dui. Fusce iaculis enim ac nulla. In risus.</p>
<p>Donec gravida. Donec et enim. Morbi sollicitudin, lacus a facilisis pulvinar, odio turpis dapibus elit, in tincidunt turpis felis nec libero. Nam vestibulum tempus ipsum. In hac habitasse platea dictumst. Nulla facilisi. Donec semper ligula. Donec commodo tortor in quam. Etiam massa. Ut tempus ligula eget tellus. Curabitur id velit ut velit varius commodo. Vestibulum ante ipsum primis in faucibus orci luctus et ultrices posuere cubilia Curae; Nulla facilisi. Fusce ornare pellentesque libero. Nunc rhoncus. Suspendisse potenti. Ut consequat, leo eu accumsan vehicula, justo sem lobortis elit, ac sollicitudin ipsum neque nec ante.</p>
<p>Aliquam elementum mauris id sem. Vivamus varius, est ut nonummy consectetuer, nulla quam bibendum velit, ac gravida nisi felis sit amet urna. Aliquam nec risus. Maecenas lacinia purus ut velit. Vestibulum ante ipsum primis in faucibus orci luctus et ultrices posuere cubilia Curae; Suspendisse sit amet dui vitae lacus fermentum sodales. Donec varius dapibus nisl. Praesent at velit id risus convallis bibendum. Aliquam felis nibh, rutrum nec, blandit non, mattis sit amet, magna. Lorem ipsum dolor sit amet, consectetuer adipiscing elit. Pellentesque habitant morbi tristique senectus et netus et malesuada fames ac turpis egestas. Etiam varius dignissim nibh. Quisque id orci ac ante hendrerit molestie. Aliquam malesuada enim non neque.</p>
</div>

</body>
</html>


EXT JS 4.1 PR1


<html>
<head>
<title>Simple App EXTJS 4.1 PR 1</title>
<script>
//alert("start");
var oneDay = 24*60*60*1000; // hours*minutes*seconds*milliseconds
var now = new Date();
var starthours = now.getHours();
var startminutes = now.getMinutes();
var startseconds = now.getSeconds();
var startmilli = now.getMilliseconds();
var date1 = new Date(2011,06,05,starthours,startminutes,startseconds,startmilli)
</script>


<link rel="stylesheet" type="text/css" href="/ext4.1pr1/resources/css/ext-all.css" />
<style type="text/css">
p {
margin:5px;
}
.settings {
background-image:url(/ext4.1pr1/examples/shared/icons/fam/folder_wrench.png);
}
.nav {
background-image:url(/ext4.1pr1/examples/shared/icons/fam/folder_go.png);
}
.info {
background-image:url(/ext4.1pr1/examples/shared/icons/fam/information.png);
}
</style>
<script type="text/javascript" src="/ext4.1pr1/ext-all.js"></script>
<script type="text/javascript" src="/ext4.1pr1/examples/shared/states.js"></script>


<script type="text/javascript">
Ext.require(['*']);


Ext.onReady(function() {


Ext.QuickTips.init();


// NOTE: This is an example showing simple state management. During development,
// it is generally best to disable state management as dynamically-generated ids
// can change across page loads, leading to unpredictable results. The developer
// should ensure that stable state ids are set for stateful components in real apps.
Ext.state.Manager.setProvider(Ext.create('Ext.state.CookieProvider'));
Ext.BLANK_IMAGE_URL = '/ext3.4.0/resources/images/default/s.gif';


var northTb = new Ext.create('Ext.toolbar.Toolbar', {
region: 'north',
xtype: 'button',
items: [
{
text: 'Button 1',
scale: 'medium',
width: 100,
handler: function(){
Ext.getCmp('card-panel').getLayout().setActiveItem('tabPanel1');
}
},
{
text: 'Button 2',
scale: 'medium',
width: 100,
handler: function(){
Ext.getCmp('card-panel').getLayout().setActiveItem('tabPanel2');
}
},
{
text: 'Button 3',
scale: 'medium',
width: 100,
handler: function(){
Ext.getCmp('card-panel').getLayout().setActiveItem('tabPanel3');
}
},
{
text: 'Button 4',
scale: 'medium',
width: 100,
handler: function(){
Ext.getCmp('card-panel').getLayout().setActiveItem('tabPanel4');
}
},
{
text: 'Button 5',
scale: 'medium',
width: 100,
handler: function(){
Ext.getCmp('card-panel').getLayout().setActiveItem('tabPanel5');
}
},
{
text: 'Button 6',
scale: 'medium',
width: 100,
handler: function(){
Ext.getCmp('card-panel').getLayout().setActiveItem('tabPanel6');
}
},
{
text: 'Button 7',
scale: 'medium',
width: 100,
handler: function(){
Ext.getCmp('card-panel').getLayout().setActiveItem('tabPanel7');
}
}
]
})




var tstore1 = Ext.create('Ext.data.TreeStore', {
proxy: {
type: 'ajax',
url: '/ext4.1pr1/examples/tree/check-nodes.json'
},
sorters: [{
property: 'leaf',
direction: 'ASC'
}, {
property: 'text',
direction: 'ASC'
}]
});

var tree1 = Ext.create('Ext.tree.Panel', {
store: tstore1,
rootVisible: false,
useArrows: true,
frame: true,
title: 'Check Tree',
width: 200,
height: 250,
dockedItems: [{
xtype: 'toolbar',
items: {
text: 'Get checked nodes',
handler: function(){
var records = tree.getView().getChecked(),
names = [];

Ext.Array.each(records, function(rec){
names.push(rec.get('text'));
});

Ext.MessageBox.show({
title: 'Selected Nodes',
msg: names.join('<br />'),
icon: Ext.MessageBox.INFO
});
}
}
}]
});


var tstore2 = Ext.create('Ext.data.TreeStore', {
proxy: {
type: 'ajax',
url: '/ext4.1pr1/examples/tree/check-nodes.json'
},
sorters: [{
property: 'leaf',
direction: 'ASC'
}, {
property: 'text',
direction: 'ASC'
}]
});

var tree2 = Ext.create('Ext.tree.Panel', {
store: tstore2,
rootVisible: false,
useArrows: true,
frame: true,
title: 'Check Tree',
width: 200,
height: 250,
dockedItems: [{
xtype: 'toolbar',
items: {
text: 'Get checked nodes',
handler: function(){
var records = tree.getView().getChecked(),
names = [];

Ext.Array.each(records, function(rec){
names.push(rec.get('text'));
});

Ext.MessageBox.show({
title: 'Selected Nodes',
msg: names.join('<br />'),
icon: Ext.MessageBox.INFO
});
}
}
}]
});



var tstore3 = Ext.create('Ext.data.TreeStore', {
proxy: {
type: 'ajax',
url: '/ext4.1pr1/examples/tree/check-nodes.json'
},
sorters: [{
property: 'leaf',
direction: 'ASC'
}, {
property: 'text',
direction: 'ASC'
}]
});

var tree3 = Ext.create('Ext.tree.Panel', {
store: tstore3,
rootVisible: false,
useArrows: true,
frame: true,
title: 'Check Tree',
width: 200,
height: 250,
dockedItems: [{
xtype: 'toolbar',
items: {
text: 'Get checked nodes',
handler: function(){
var records = tree.getView().getChecked(),
names = [];

Ext.Array.each(records, function(rec){
names.push(rec.get('text'));
});

Ext.MessageBox.show({
title: 'Selected Nodes',
msg: names.join('<br />'),
icon: Ext.MessageBox.INFO
});
}
}
}]
});


var tstore4 = Ext.create('Ext.data.TreeStore', {
proxy: {
type: 'ajax',
url: '/ext4.1pr1/examples/tree/check-nodes.json'
},
sorters: [{
property: 'leaf',
direction: 'ASC'
}, {
property: 'text',
direction: 'ASC'
}]
});

var tree4 = Ext.create('Ext.tree.Panel', {
store: tstore4,
rootVisible: false,
useArrows: true,
frame: true,
title: 'Check Tree',
width: 200,
height: 250,
dockedItems: [{
xtype: 'toolbar',
items: {
text: 'Get checked nodes',
handler: function(){
var records = tree.getView().getChecked(),
names = [];

Ext.Array.each(records, function(rec){
names.push(rec.get('text'));
});

Ext.MessageBox.show({
title: 'Selected Nodes',
msg: names.join('<br />'),
icon: Ext.MessageBox.INFO
});
}
}
}]
});




var tstore5 = Ext.create('Ext.data.TreeStore', {
proxy: {
type: 'ajax',
url: '/ext4.1pr1/examples/tree/check-nodes.json'
},
sorters: [{
property: 'leaf',
direction: 'ASC'
}, {
property: 'text',
direction: 'ASC'
}]
});

var tree5 = Ext.create('Ext.tree.Panel', {
store: tstore5,
rootVisible: false,
useArrows: true,
frame: true,
title: 'Check Tree',
width: 200,
height: 250,
dockedItems: [{
xtype: 'toolbar',
items: {
text: 'Get checked nodes',
handler: function(){
var records = tree.getView().getChecked(),
names = [];

Ext.Array.each(records, function(rec){
names.push(rec.get('text'));
});

Ext.MessageBox.show({
title: 'Selected Nodes',
msg: names.join('<br />'),
icon: Ext.MessageBox.INFO
});
}
}
}]
});




Ext.define('Book1',{
extend: 'Ext.data.Model',
fields: [
// set up the fields mapping into the xml doc
// The first needs mapping, the others are very basic
{name: 'Author', mapping: 'ItemAttributes > Author'},
'Title', 'Manufacturer', 'ProductGroup'
]
});

// create the Data Store
var store1 = Ext.create('Ext.data.Store', {
model: 'Book1',
autoLoad: true,
proxy: {
// load using HTTP
type: 'ajax',
url: '/ext4.1pr1/examples/grid/sheldon.xml',
// the return will be XML, so lets set up a reader
reader: {
type: 'xml',
// records will have an "Item" tag
record: 'Item',
idProperty: 'ASIN',
totalRecords: '@total'
}
}
});

// create the grid
var grid1 = Ext.create('Ext.grid.Panel', {
store: store1,
height: 500,
columns: [
{text: "Author", flex: 1, dataIndex: 'Author', sortable: true},
{text: "Title", width: 180, dataIndex: 'Title', sortable: true},
{text: "Manufacturer", width: 115, dataIndex: 'Manufacturer', sortable: true},
{text: "Product Group", width: 100, dataIndex: 'ProductGroup', sortable: true}
]
});



Ext.define('Book2',{
extend: 'Ext.data.Model',
fields: [
// set up the fields mapping into the xml doc
// The first needs mapping, the others are very basic
{name: 'Author', mapping: 'ItemAttributes > Author'},
'Title', 'Manufacturer', 'ProductGroup'
]
});

// create the Data Store
var store2 = Ext.create('Ext.data.Store', {
model: 'Book2',
autoLoad: true,
proxy: {
// load using HTTP
type: 'ajax',
url: '/ext4.1pr1/examples/grid/sheldon.xml',
// the return will be XML, so lets set up a reader
reader: {
type: 'xml',
// records will have an "Item" tag
record: 'Item',
idProperty: 'ASIN',
totalRecords: '@total'
}
}
});

// create the grid
var grid2 = Ext.create('Ext.grid.Panel', {
store: store2,
height: 500,
columns: [
{text: "Author", flex: 1, dataIndex: 'Author', sortable: true},
{text: "Title", width: 180, dataIndex: 'Title', sortable: true},
{text: "Manufacturer", width: 115, dataIndex: 'Manufacturer', sortable: true},
{text: "Product Group", width: 100, dataIndex: 'ProductGroup', sortable: true}
]
});





Ext.define('Book3',{
extend: 'Ext.data.Model',
fields: [
// set up the fields mapping into the xml doc
// The first needs mapping, the others are very basic
{name: 'Author', mapping: 'ItemAttributes > Author'},
'Title', 'Manufacturer', 'ProductGroup'
]
});

// create the Data Store
var store3 = Ext.create('Ext.data.Store', {
model: 'Book3',
autoLoad: true,
proxy: {
// load using HTTP
type: 'ajax',
url: '/ext4.1pr1/examples/grid/sheldon.xml',
// the return will be XML, so lets set up a reader
reader: {
type: 'xml',
// records will have an "Item" tag
record: 'Item',
idProperty: 'ASIN',
totalRecords: '@total'
}
}
});

// create the grid
var grid3 = Ext.create('Ext.grid.Panel', {
store: store3,
height: 500,
columns: [
{text: "Author", flex: 1, dataIndex: 'Author', sortable: true},
{text: "Title", width: 180, dataIndex: 'Title', sortable: true},
{text: "Manufacturer", width: 115, dataIndex: 'Manufacturer', sortable: true},
{text: "Product Group", width: 100, dataIndex: 'ProductGroup', sortable: true}
]
});


Ext.define('Book4',{
extend: 'Ext.data.Model',
fields: [
// set up the fields mapping into the xml doc
// The first needs mapping, the others are very basic
{name: 'Author', mapping: 'ItemAttributes > Author'},
'Title', 'Manufacturer', 'ProductGroup'
]
});

// create the Data Store
var store4 = Ext.create('Ext.data.Store', {
model: 'Book4',
autoLoad: true,
proxy: {
// load using HTTP
type: 'ajax',
url: '/ext4.1pr1/examples/grid/sheldon.xml',
// the return will be XML, so lets set up a reader
reader: {
type: 'xml',
// records will have an "Item" tag
record: 'Item',
idProperty: 'ASIN',
totalRecords: '@total'
}
}
});

// create the grid
var grid4 = Ext.create('Ext.grid.Panel', {
store: store4,
height: 500,
columns: [
{text: "Author", flex: 1, dataIndex: 'Author', sortable: true},
{text: "Title", width: 180, dataIndex: 'Title', sortable: true},
{text: "Manufacturer", width: 115, dataIndex: 'Manufacturer', sortable: true},
{text: "Product Group", width: 100, dataIndex: 'ProductGroup', sortable: true}
]
});






var bd = Ext.getBody();
// sample static data for the store
var myData = [
['3m Co', 71.72, 0.02, 0.03, '9/1 12:00am'],
['Alcoa Inc', 29.01, 0.42, 1.47, '9/1 12:00am'],
['Altria Group Inc', 83.81, 0.28, 0.34, '9/1 12:00am'],
['American Express Company', 52.55, 0.01, 0.02, '9/1 12:00am'],
['American International Group, Inc.', 64.13, 0.31, 0.49, '9/1 12:00am'],
['AT&T Inc.', 31.61, -0.48, -1.54, '9/1 12:00am'],
['Boeing Co.', 75.43, 0.53, 0.71, '9/1 12:00am'],
['Caterpillar Inc.', 67.27, 0.92, 1.39, '9/1 12:00am'],
['Citigroup, Inc.', 49.37, 0.02, 0.04, '9/1 12:00am'],
['E.I. du Pont de Nemours and Company', 40.48, 0.51, 1.28, '9/1 12:00am'],
['Exxon Mobil Corp', 68.1, -0.43, -0.64, '9/1 12:00am'],
['General Electric Company', 34.14, -0.08, -0.23, '9/1 12:00am'],
['General Motors Corporation', 30.27, 1.09, 3.74, '9/1 12:00am'],
['Hewlett-Packard Co.', 36.53, -0.03, -0.08, '9/1 12:00am'],
['Honeywell Intl Inc', 38.77, 0.05, 0.13, '9/1 12:00am'],
['Intel Corporation', 19.88, 0.31, 1.58, '9/1 12:00am'],
['International Business Machines', 81.41, 0.44, 0.54, '9/1 12:00am'],
['Johnson & Johnson', 64.72, 0.06, 0.09, '9/1 12:00am'],
['JP Morgan & Chase & Co', 45.73, 0.07, 0.15, '9/1 12:00am'],
['McDonald\'s Corporation', 36.76, 0.86, 2.40, '9/1 12:00am'],
['Merck & Co., Inc.', 40.96, 0.41, 1.01, '9/1 12:00am'],
['Microsoft Corporation', 25.84, 0.14, 0.54, '9/1 12:00am'],
['Pfizer Inc', 27.96, 0.4, 1.45, '9/1 12:00am'],
['The Coca-Cola Company', 45.07, 0.26, 0.58, '9/1 12:00am'],
['The Home Depot, Inc.', 34.64, 0.35, 1.02, '9/1 12:00am'],
['The Procter & Gamble Company', 61.91, 0.01, 0.02, '9/1 12:00am'],
['United Technologies Corporation', 63.26, 0.55, 0.88, '9/1 12:00am'],
['Verizon Communications', 35.57, 0.39, 1.11, '9/1 12:00am'],
['Wal-Mart Stores, Inc.', 45.45, 0.73, 1.63, '9/1 12:00am']
];

var ds = Ext.create('Ext.data.ArrayStore', {
fields: [
{name: 'company'},
{name: 'price', type: 'float'},
{name: 'change', type: 'float'},
{name: 'pctChange', type: 'float'},
{name: 'lastChange', type: 'date', dateFormat: 'n/j h:ia'},
// Rating dependent upon performance 0 = best, 2 = worst
{name: 'rating', type: 'int', convert: function(value, record) {
var pct = record.get('pctChange');
if (pct < 0) return 2;
if (pct < 1) return 1;
return 0;
}}
],
data: myData
});


// example of custom renderer function
function change(val){
if(val > 0){
return '<span style="color:green;">' + val + '</span>';
}else if(val < 0){
return '<span style="color:red;">' + val + '</span>';
}
return val;
}
// example of custom renderer function
function pctChange(val){
if(val > 0){
return '<span style="color:green;">' + val + '%</span>';
}else if(val < 0){
return '<span style="color:red;">' + val + '%</span>';
}
return val;
}

// render rating as "A", "B" or "C" depending upon numeric value.
function rating(v) {
if (v == 0) return "A";
if (v == 1) return "B";
if (v == 2) return "C";
}


bd.createChild({tag: 'h2', html: 'Using a Grid with a Form'});

/*
* Here is where we create the Form
*/
var gridForm = Ext.create('Ext.form.Panel', {
id: 'company-form',
frame: true,
title: 'Company data',
bodyPadding: 5,
width: 750,
layout: 'column', // Specifies that the items will now be arranged in columns

fieldDefaults: {
labelAlign: 'left',
msgTarget: 'side'
},

items: [{
columnWidth: 0.60,
xtype: 'gridpanel',
store: ds,
height: 400,
title:'Company Data',

columns: [
{
id :'company',
text : 'Company',
flex: 1,
sortable : true,
dataIndex: 'company'
},
{
text : 'Price',
width : 75,
sortable : true,
dataIndex: 'price'
},
{
text : 'Change',
width : 75,
sortable : true,
renderer : change,
dataIndex: 'change'
},
{
text : '% Change',
width : 75,
sortable : true,
renderer : pctChange,
dataIndex: 'pctChange'
},
{
text : 'Last Updated',
width : 85,
sortable : true,
renderer : Ext.util.Format.dateRenderer('m/d/Y'),
dataIndex: 'lastChange'
},
{
text: 'Rating',
width: 30,
sortable: true,
renderer: rating,
dataIndex: 'rating'
}
],

listeners: {
selectionchange: function(model, records) {
if (records[0]) {
this.up('form').getForm().loadRecord(records[0]);
}
}
}
}, {
columnWidth: 0.4,
margin: '0 0 0 10',
xtype: 'fieldset',
title:'Company details',
defaults: {
width: 240,
labelWidth: 90
},
defaultType: 'textfield',
items: [{
fieldLabel: 'Name',
name: 'company'
},{
fieldLabel: 'Price',
name: 'price'
},{
fieldLabel: '% Change',
name: 'pctChange'
},{
xtype: 'datefield',
fieldLabel: 'Last Updated',
name: 'lastChange'
}, {
xtype: 'radiogroup',
fieldLabel: 'Rating',
columns: 3,
defaults: {
name: 'rating' //Each radio has the same name so the browser will make sure only one is checked at once
},
items: [{
inputValue: '0',
boxLabel: 'A'
}, {
inputValue: '1',
boxLabel: 'B'
}, {
inputValue: '2',
boxLabel: 'C'
}]
}]
}]

});












Ext.define('example.contact1', {
extend: 'Ext.data.Model',
fields: [
{name: 'first', mapping: 'name > first'},
{name: 'last', mapping: 'name > last'},
'company', 'email', 'state',
{name: 'dob', type: 'date', dateFormat: 'm/d/Y'}
]
});

Ext.define('example.fielderror1', {
extend: 'Ext.data.Model',
fields: ['id', 'msg']
});

var formPanel1 = Ext.create('Ext.form.Panel', {
frame: true,
title:'XML Form',
width: 340,
bodyPadding: 5,
waitMsgTarget: true,

fieldDefaults: {
labelAlign: 'right',
labelWidth: 85,
msgTarget: 'side'
},

// configure how to read the XML data
reader : Ext.create('Ext.data.reader.Xml', {
model: 'example.contact1',
record : 'contact',
successProperty: '@success'
}),

// configure how to read the XML errors
errorReader: Ext.create('Ext.data.reader.Xml', {
model: 'example.fielderror1',
record : 'field',
successProperty: '@success'
}),

items: [{
xtype: 'fieldset',
title: 'Contact Information',
defaultType: 'textfield',
defaults: {
width: 280
},
items: [{
fieldLabel: 'First Name',
emptyText: 'First Name',
name: 'first'
}, {
fieldLabel: 'Last Name',
emptyText: 'Last Name',
name: 'last'
}, {
fieldLabel: 'Company',
name: 'company'
}, {
fieldLabel: 'Email',
name: 'email',
vtype:'email'
}, {
xtype: 'combobox',
fieldLabel: 'State',
name: 'state',
store: Ext.create('Ext.data.ArrayStore', {
fields: ['abbr', 'state'],
data : Ext.example.states // from states.js
}),
valueField: 'abbr',
displayField: 'state',
typeAhead: true,
queryMode: 'local',
emptyText: 'Select a state...'
}, {
xtype: 'datefield',
fieldLabel: 'Date of Birth',
name: 'dob',
allowBlank: false,
maxValue: new Date()
}
]
}],

buttons: [{
text: 'Load',
handler: function(){
formPanel1.getForm().load({
url: '/ext4.1pr1/examples/form/xml-form-data.xml',
waitMsg: 'Loading...'
});
}
}, {
text: 'Submit',
disabled: true,
formBind: true,
handler: function(){
this.up('form').getForm().submit({
url: 'xml-form-errors.xml',
submitEmptyText: false,
waitMsg: 'Saving Data...'
});
}
}]
});





Ext.define('example.contact2', {
extend: 'Ext.data.Model',
fields: [
{name: 'first', mapping: 'name > first'},
{name: 'last', mapping: 'name > last'},
'company', 'email', 'state',
{name: 'dob', type: 'date', dateFormat: 'm/d/Y'}
]
});

Ext.define('example.fielderror2', {
extend: 'Ext.data.Model',
fields: ['id', 'msg']
});

var formPanel2 = Ext.create('Ext.form.Panel', {
frame: true,
title:'XML Form',
width: 340,
bodyPadding: 5,
waitMsgTarget: true,

fieldDefaults: {
labelAlign: 'right',
labelWidth: 85,
msgTarget: 'side'
},

// configure how to read the XML data
reader : Ext.create('Ext.data.reader.Xml', {
model: 'example.contact2',
record : 'contact',
successProperty: '@success'
}),

// configure how to read the XML errors
errorReader: Ext.create('Ext.data.reader.Xml', {
model: 'example.fielderror2',
record : 'field',
successProperty: '@success'
}),

items: [{
xtype: 'fieldset',
title: 'Contact Information',
defaultType: 'textfield',
defaults: {
width: 280
},
items: [{
fieldLabel: 'First Name',
emptyText: 'First Name',
name: 'first'
}, {
fieldLabel: 'Last Name',
emptyText: 'Last Name',
name: 'last'
}, {
fieldLabel: 'Company',
name: 'company'
}, {
fieldLabel: 'Email',
name: 'email',
vtype:'email'
}, {
xtype: 'combobox',
fieldLabel: 'State',
name: 'state',
store: Ext.create('Ext.data.ArrayStore', {
fields: ['abbr', 'state'],
data : Ext.example.states // from states.js
}),
valueField: 'abbr',
displayField: 'state',
typeAhead: true,
queryMode: 'local',
emptyText: 'Select a state...'
}, {
xtype: 'datefield',
fieldLabel: 'Date of Birth',
name: 'dob',
allowBlank: false,
maxValue: new Date()
}
]
}],

buttons: [{
text: 'Load',
handler: function(){
formPanel2.getForm().load({
url: '/ext4.1pr1/examples/form/xml-form-data.xml',
waitMsg: 'Loading...'
});
}
}, {
text: 'Submit',
disabled: true,
formBind: true,
handler: function(){
this.up('form').getForm().submit({
url: 'xml-form-errors.xml',
submitEmptyText: false,
waitMsg: 'Saving Data...'
});
}
}]
});




var tabPanel1 = Ext.create('Ext.tab.Panel', {
id: 'tabPanel1',
html: 'Panel 1',
deferredRender: false,
activeTab: 0, // first tab initially active
items: [
{
title: 'Close Me',
closable: true,
html: 'Panel 1',
autoScroll: true,
items:[
gridForm
]
},
{
title: 'Center Panel 1',
autoScroll: true,
items:[
grid1
]
},
{
title: 'Center Panel 2',
autoScroll: true,
items:[
formPanel1
]
},
{
title: 'Center Panel 3',
autoScroll: true,
items:[
grid2
]
},
{
title: 'Center Panel 4',
autoScroll: true,
items:[
grid3
]
},
{
title: 'Center Panel 5',
autoScroll: true,
items:[
grid4
]
},
{
title: 'Center Panel 6',
autoScroll: true,
items:[
formPanel2
]
},
{
title: 'Center Panel 7',
autoScroll: true,
items:[
{
contentEl: 'center7'
}
]
}
]
});

var tabPanel2 = Ext.create('Ext.tab.Panel', {
id: 'tabPanel2',

deferredRender: false,
activeTab: 0, // first tab initially active
items: [
{
title: 'Close Me',
closable: true,
layout: 'border',
html: 'Panel 2',
autoScroll: true,
items:[
{
xtype: 'panel',
region: 'north',
html: 'north'
},
{
xtype: 'panel',
title: 'test',
region: 'center',
html: 'center p 2'

},
{
xtype: 'panel',
region: 'south',
html: 'south'
}
]
},
{
title: 'Center Panel 1',
autoScroll: true,
items:[
{
xtype: 'panel',
region: 'north',
html: 'north'
},
{
xtype: 'panel',
title: 'test',
region: 'center',
html: 'center'

},
{
xtype: 'panel',
region: 'south',
html: 'south'
}

]
},
{
title: 'Center Panel 2',
autoScroll: true,
items:[
{
xtype: 'panel',
region: 'north',
html: 'north'
},
{
xtype: 'panel',
title: 'test',
region: 'center',
html: 'center'

},
{
xtype: 'panel',
region: 'south',
html: 'south'
}

]
},
{
title: 'Center Panel 3',
autoScroll: true,
items:[
{
xtype: 'panel',
region: 'north',
html: 'north'
},
{
xtype: 'panel',
title: 'test',
region: 'center',
html: 'center'

},
{
xtype: 'panel',
region: 'south',
html: 'south'
}

]
},
{
title: 'Center Panel 4',
autoScroll: true,
items:[
{
xtype: 'panel',
region: 'north',
html: 'north'
},
{
xtype: 'panel',
title: 'test',
region: 'center',
html: 'center'

},
{
xtype: 'panel',
region: 'south',
html: 'south'
}

]
},
{
title: 'Center Panel 5',
autoScroll: true,
items:[
{
xtype: 'panel',
region: 'north',
html: 'north'
},
{
xtype: 'panel',
title: 'test',
region: 'center',
html: 'center'

},
{
xtype: 'panel',
region: 'south',
html: 'south'
}

]
},
{
title: 'Center Panel 6',
autoScroll: true,
items:[
{
xtype: 'panel',
region: 'north',
html: 'north'
},
{
xtype: 'panel',
title: 'test',
region: 'center',
html: 'center'

},
{
xtype: 'panel',
region: 'south',
html: 'south'
}

]
},
{
title: 'Center Panel 7',
autoScroll: true,
items:[
{
xtype: 'panel',
region: 'north',
html: 'north'
},
{
xtype: 'panel',
title: 'test',
region: 'center',
html: 'center'

},
{
xtype: 'panel',
region: 'south',
html: 'south'
}
]
}
]
});


var tabPanel3 = Ext.create('Ext.tab.Panel', {
id: 'tabPanel3',
deferredRender: false,
activeTab: 0, // first tab initially active
items: [
{
title: 'Close Me',
closable: true,
html: 'Panel 3',
autoScroll: true,
items:[
{
xtype: 'panel',
region: 'north',
html: 'north'
},
{
xtype: 'panel',
title: 'test',
region: 'center',
html: 'center p 3'

},
{
xtype: 'panel',
region: 'south',
html: 'south'
}

]
},
{
title: 'Center Panel 1',
autoScroll: true,
items:[
{
xtype: 'panel',
region: 'north',
html: 'north'
},
{
xtype: 'panel',
title: 'test',
region: 'center',
html: 'center'

},
{
xtype: 'panel',
region: 'south',
html: 'south'
}

]
},
{
title: 'Center Panel 2',
autoScroll: true,
items:[
{
xtype: 'panel',
region: 'north',
html: 'north'
},
{
xtype: 'panel',
title: 'test',
region: 'center',
html: 'center'

},
{
xtype: 'panel',
region: 'south',
html: 'south'
}

]
},
{
title: 'Center Panel 3',
autoScroll: true,
items:[
{
xtype: 'panel',
region: 'north',
html: 'north'
},
{
xtype: 'panel',
title: 'test',
region: 'center',
html: 'center'

},
{
xtype: 'panel',
region: 'south',
html: 'south'
}

]
},
{
title: 'Center Panel 4',
autoScroll: true,
items:[
{
xtype: 'panel',
region: 'north',
html: 'north'
},
{
xtype: 'panel',
title: 'test',
region: 'center',
html: 'center'

},
{
xtype: 'panel',
region: 'south',
html: 'south'
}

]
},
{
title: 'Center Panel 5',
autoScroll: true,
items:[
{
xtype: 'panel',
region: 'north',
html: 'north'
},
{
xtype: 'panel',
title: 'test',
region: 'center',
html: 'center'

},
{
xtype: 'panel',
region: 'south',
html: 'south'
}

]
},
{
title: 'Center Panel 6',
autoScroll: true,
items:[
{
xtype: 'panel',
region: 'north',
html: 'north'
},
{
xtype: 'panel',
title: 'test',
region: 'center',
html: 'center'

},
{
xtype: 'panel',
region: 'south',
html: 'south'
}

]
},
{
title: 'Center Panel 7',
autoScroll: true,
items:[
{
xtype: 'panel',
region: 'north',
html: 'north'
},
{
xtype: 'panel',
title: 'test',
region: 'center',
html: 'center'

},
{
xtype: 'panel',
region: 'south',
html: 'south'
}

]
}
]
});

var tabPanel4 = Ext.create('Ext.tab.Panel', {
id: 'tabPanel4',
deferredRender: false,
activeTab: 0, // first tab initially active
items: [
{
title: 'Close Me',
closable: true,
html: 'Panel 4',
autoScroll: true,
items:[
{
xtype: 'panel',
region: 'north',
html: 'north'
},
{
xtype: 'panel',
title: 'test',
region: 'center',
html: 'center p 4'

},
{
xtype: 'panel',
region: 'south',
html: 'south'
}

]
},
{
title: 'Center Panel 1',
autoScroll: true,
items:[
{
xtype: 'panel',
region: 'north',
html: 'north'
},
{
xtype: 'panel',
title: 'test',
region: 'center',
html: 'center'

},
{
xtype: 'panel',
region: 'south',
html: 'south'
}

]
},
{
title: 'Center Panel 2',
autoScroll: true,
items:[
{
xtype: 'panel',
region: 'north',
html: 'north'
},
{
xtype: 'panel',
title: 'test',
region: 'center',
html: 'center'

},
{
xtype: 'panel',
region: 'south',
html: 'south'
}

]
},
{
title: 'Center Panel 3',
autoScroll: true,
items:[
{
xtype: 'panel',
region: 'north',
html: 'north'
},
{
xtype: 'panel',
title: 'test',
region: 'center',
html: 'center'

},
{
xtype: 'panel',
region: 'south',
html: 'south'
}

]
},
{
title: 'Center Panel 4',
autoScroll: true,
items:[
{
xtype: 'panel',
region: 'north',
html: 'north'
},
{
xtype: 'panel',
title: 'test',
region: 'center',
html: 'center'

},
{
xtype: 'panel',
region: 'south',
html: 'south'
}

]
},
{
title: 'Center Panel 5',
autoScroll: true,
items:[
{
xtype: 'panel',
region: 'north',
html: 'north'
},
{
xtype: 'panel',
title: 'test',
region: 'center',
html: 'center'

},
{
xtype: 'panel',
region: 'south',
html: 'south'
}

]
},
{
title: 'Center Panel 6',
autoScroll: true,
items:[
{
xtype: 'panel',
region: 'north',
html: 'north'
},
{
xtype: 'panel',
title: 'test',
region: 'center',
html: 'center'

},
{
xtype: 'panel',
region: 'south',
html: 'south'
}

]
},
{
title: 'Center Panel 7',
autoScroll: true,
items:[
{
xtype: 'panel',
region: 'north',
html: 'north'
},
{
xtype: 'panel',
title: 'test',
region: 'center',
html: 'center'

},
{
xtype: 'panel',
region: 'south',
html: 'south'
}
]
}
]
});

var tabPanel5 = Ext.create('Ext.tab.Panel', {
id: 'tabPanel5',
deferredRender: false,
activeTab: 0, // first tab initially active
items: [
{
title: 'Close Me',
closable: true,
html: 'Panel 5',
autoScroll: true,
items:[
{
xtype: 'panel',
region: 'north',
html: 'north'
},
{
xtype: 'panel',
title: 'test',
region: 'center',
html: 'center p 5'

},
{
xtype: 'panel',
region: 'south',
html: 'south'
}

]
},
{
title: 'Center Panel 1',
autoScroll: true,
items:[
{
xtype: 'panel',
region: 'north',
html: 'north'
},
{
xtype: 'panel',
title: 'test',
region: 'center',
html: 'center'

},
{
xtype: 'panel',
region: 'south',
html: 'south'
}

]
},
{
title: 'Center Panel 2',
autoScroll: true,
items:[
{
xtype: 'panel',
region: 'north',
html: 'north'
},
{
xtype: 'panel',
title: 'test',
region: 'center',
html: 'center'

},
{
xtype: 'panel',
region: 'south',
html: 'south'
}

]
},
{
title: 'Center Panel 3',
autoScroll: true,
items:[
{
xtype: 'panel',
region: 'north',
html: 'north'
},
{
xtype: 'panel',
title: 'test',
region: 'center',
html: 'center'

},
{
xtype: 'panel',
region: 'south',
html: 'south'
}

]
},
{
title: 'Center Panel 4',
autoScroll: true,
items:[
{
xtype: 'panel',
region: 'north',
html: 'north'
},
{
xtype: 'panel',
title: 'test',
region: 'center',
html: 'center'

},
{
xtype: 'panel',
region: 'south',
html: 'south'
}

]
},
{
title: 'Center Panel 5',
autoScroll: true,
items:[
{
xtype: 'panel',
region: 'north',
html: 'north'
},
{
xtype: 'panel',
title: 'test',
region: 'center',
html: 'center'

},
{
xtype: 'panel',
region: 'south',
html: 'south'
}

]
},
{
title: 'Center Panel 6',
autoScroll: true,
items:[
{
xtype: 'panel',
region: 'north',
html: 'north'
},
{
xtype: 'panel',
title: 'test',
region: 'center',
html: 'center'

},
{
xtype: 'panel',
region: 'south',
html: 'south'
}
]
},
{
title: 'Center Panel 7',
autoScroll: true,
items:[
{
xtype: 'panel',
region: 'north',
html: 'north'
},
{
xtype: 'panel',
title: 'test',
region: 'center',
html: 'center'

},
{
xtype: 'panel',
region: 'south',
html: 'south'
}
]
}
]
});

var tabPanel6 = Ext.create('Ext.tab.Panel', {
id: 'tabPanel6',
deferredRender: false,
activeTab: 0, // first tab initially active
items: [
{
title: 'Close Me',
closable: true,
html: 'Panel 6',
autoScroll: true,
items:[
{
xtype: 'panel',
region: 'north',
html: 'north'
},
{
xtype: 'panel',
title: 'test',
region: 'center',
html: 'center p 6'

},
{
xtype: 'panel',
region: 'south',
html: 'south'
}
]
},
{
title: 'Center Panel 1',
autoScroll: true,
items:[
{
xtype: 'panel',
region: 'north',
html: 'north'
},
{
xtype: 'panel',
title: 'test',
region: 'center',
html: 'center'

},
{
xtype: 'panel',
region: 'south',
html: 'south'
}
]
},
{
title: 'Center Panel 2',
autoScroll: true,
items:[
{
xtype: 'panel',
region: 'north',
html: 'north'
},
{
xtype: 'panel',
title: 'test',
region: 'center',
html: 'center'

},
{
xtype: 'panel',
region: 'south',
html: 'south'
}
]
},
{
title: 'Center Panel 3',
autoScroll: true,
items:[
{
xtype: 'panel',
region: 'north',
html: 'north'
},
{
xtype: 'panel',
title: 'test',
region: 'center',
html: 'center'

},
{
xtype: 'panel',
region: 'south',
html: 'south'
}
]
},
{
title: 'Center Panel 4',
autoScroll: true,
items:[
{
xtype: 'panel',
region: 'north',
html: 'north'
},
{
xtype: 'panel',
title: 'test',
region: 'center',
html: 'center'

},
{
xtype: 'panel',
region: 'south',
html: 'south'
}
]
},
{
title: 'Center Panel 5',
autoScroll: true,
items:[
{
xtype: 'panel',
region: 'north',
html: 'north'
},
{
xtype: 'panel',
title: 'test',
region: 'center',
html: 'center'

},
{
xtype: 'panel',
region: 'south',
html: 'south'
}
]
},
{
title: 'Center Panel 6',
autoScroll: true,
items:[
{
xtype: 'panel',
region: 'north',
html: 'north'
},
{
xtype: 'panel',
title: 'test',
region: 'center',
html: 'center'

},
{
xtype: 'panel',
region: 'south',
html: 'south'
}
]
},
{
title: 'Center Panel 7',
autoScroll: true,
items:[
{
xtype: 'panel',
region: 'north',
html: 'north'
},
{
xtype: 'panel',
title: 'test',
region: 'center',
html: 'center'

},
{
xtype: 'panel',
region: 'south',
html: 'south'
}
]
}
]
});

var tabPanel7 = Ext.create('Ext.tab.Panel', {
id: 'tabPanel7',
deferredRender: false,
activeTab: 0, // first tab initially active
items: [
{
title: 'Close Me',
closable: true,
html: 'Panel 7',
autoScroll: true,
items:[
{
xtype: 'panel',
region: 'north',
html: 'north'
},
{
xtype: 'panel',
title: 'test',
region: 'center',
html: 'center p 7'

},
{
xtype: 'panel',
region: 'south',
html: 'south'
}
]
},
{
title: 'Center Panel 1',
autoScroll: true,
items:[
{
xtype: 'panel',
region: 'north',
html: 'north'
},
{
xtype: 'panel',
title: 'test',
region: 'center',
html: 'center'

},
{
xtype: 'panel',
region: 'south',
html: 'south'
}
]
},
{
title: 'Center Panel 2',
autoScroll: true,
items:[
{
xtype: 'panel',
region: 'north',
html: 'north'
},
{
xtype: 'panel',
title: 'test',
region: 'center',
html: 'center'

},
{
xtype: 'panel',
region: 'south',
html: 'south'
}
]
},
{
title: 'Center Panel 3',
autoScroll: true,
items:[
{
xtype: 'panel',
region: 'north',
html: 'north'
},
{
xtype: 'panel',
title: 'test',
region: 'center',
html: 'center'

},
{
xtype: 'panel',
region: 'south',
html: 'south'
}
]
},
{
title: 'Center Panel 4',
autoScroll: true,
items:[
{
xtype: 'panel',
region: 'north',
html: 'north'
},
{
xtype: 'panel',
title: 'test',
region: 'center',
html: 'center'

},
{
xtype: 'panel',
region: 'south',
html: 'south'
}
]
},
{
title: 'Center Panel 5',
autoScroll: true,
items:[
{
xtype: 'panel',
region: 'north',
html: 'north'
},
{
xtype: 'panel',
title: 'test',
region: 'center',
html: 'center'

},
{
xtype: 'panel',
region: 'south',
html: 'south'
}
]
},
{
title: 'Center Panel 6',
autoScroll: true,
items:[
{
xtype: 'panel',
region: 'north',
html: 'north'
},
{
xtype: 'panel',
title: 'test',
region: 'center',
html: 'center'

},
{
xtype: 'panel',
region: 'south',
html: 'south'
}
]
},
{
title: 'Center Panel 7',
autoScroll: true,
items:[
{
xtype: 'panel',
region: 'north',
html: 'north'
},
{
xtype: 'panel',
title: 'test',
region: 'center',
html: 'center'

},
{
xtype: 'panel',
region: 'south',
html: 'south'
}
]
}
]
});

var cardPanel = Ext.create('Ext.Panel', {
region: 'center',
id: 'card-panel',
layout: 'card',
border: false,
margins: '0 0 0 2',
activeItem: 0,
layout: 'card',
name: 'test',
items:[
tabPanel1,
tabPanel2,
tabPanel3,
tabPanel4,
tabPanel5,
tabPanel6,
tabPanel7

]

})


var viewport = Ext.create('Ext.Viewport', {
id: 'border-example',
layout: 'border',
items: [
{
region: 'north',
height: 38,
items:[
northTb
]
}, {
// lazily created panel (xtype:'panel' is default)
region: 'south',
split: true,
height: 100,
minSize: 100,
maxSize: 200,
collapsible: true,
collapsed: true,
title: 'South',
margins: '0 0 0 0'
}, {
xtype: 'tabpanel',
region: 'east',
title: 'East Side',
dockedItems: [{
dock: 'top',
xtype: 'toolbar',
items: [ '->', {
xtype: 'button',
text: 'test',
tooltip: 'Test Button'
}]
}],
animCollapse: true,
collapsible: true,
split: true,
width: 225, // give east and west regions a width
minSize: 175,
maxSize: 400,
margins: '0 5 0 0',
activeTab: 2,
tabPosition: 'bottom',
items: [{
html: '<p>A TabPanel component can be a region.</p>',
title: 'A Tab',
autoScroll: true
},{
html: '<p>A TabPanel component can be a region.</p>',
title: 'A Tab',
autoScroll: true
}, Ext.create('Ext.grid.PropertyGrid', {
title: 'Property Grid',
closable: true,
source: {
"(name)": "Properties Grid",
"grouping": false,
"autoFitColumns": true,
"productionQuality": false,
"created": Ext.Date.parse('10/15/2006', 'm/d/Y'),
"tested": false,
"version": 0.01,
"borderWidth": 1
}
})]
}, {
region: 'west',
stateId: 'navigation-panel',
id: 'west-panel', // see Ext.getCmp() below
title: 'West',
split: true,
width: 200,
minWidth: 175,
maxWidth: 400,
collapsible: true,
animCollapse: true,
margins: '0 0 0 5',
layout: 'accordion',
items: [{
title: 'Navigation',
iconCls: 'nav',
items:[
tree1
]
}, {
title: 'Settings',
iconCls: 'settings',
items:[
tree2
]
}, {
title: 'Advanced',
iconCls: 'settings',
items:[
tree3
]
}, {
title: 'Misc',
iconCls: 'settings',
items:[
tree4
]
}, {
title: 'Admin',
iconCls: 'settings',
items:[
tree5
]
}

]
},
cardPanel
]
});

var end = new Date();
var endhours = now.getHours();
var endminutes = end.getMinutes();
var endseconds = end.getSeconds();
var endmilli = end.getMilliseconds();
var date2 = new Date(2011,06,05,endhours,endminutes,endseconds,endmilli)
var diffDays = Math.abs((date1.getTime() - date2.getTime())/1000);
alert("Total Load and layout Time"+' ' +diffDays);


});
</script>
</head>
<body>
<div id="center7" class="x-hide-display">
<a id="hideit" href="#">Toggle the west region</a>
<p>My closable attribute is set to false so you can't close me. The other center panels can be closed.</p>
<p>The center panel automatically grows to fit the remaining space in the container that isn't taken up by the border regions.</p>
<hr>
<p>Lorem ipsum dolor sit amet, consectetuer adipiscing elit. Sed metus nibh, sodales a, porta at, vulputate eget, dui. Pellentesque ut nisl. Maecenas tortor turpis, interdum non, sodales non, iaculis ac, lacus. Vestibulum auctor, tortor quis iaculis malesuada, libero lectus bibendum purus, sit amet tincidunt quam turpis vel lacus. In pellentesque nisl non sem. Suspendisse nunc sem, pretium eget, cursus a, fringilla vel, urna. Aliquam commodo ullamcorper erat. Nullam vel justo in neque porttitor laoreet. Aenean lacus dui, consequat eu, adipiscing eget, nonummy non, nisi. Morbi nunc est, dignissim non, ornare sed, luctus eu, massa. Vivamus eget quam. Vivamus tincidunt diam nec urna. Curabitur velit. Quisque dolor magna, ornare sed, elementum porta, luctus in, leo.</p>
<p>Donec quis dui. Sed imperdiet. Nunc consequat, est eu sollicitudin gravida, mauris ligula lacinia mauris, eu porta dui nisl in velit. Nam congue, odio id auctor nonummy, augue lectus euismod nunc, in tristique turpis dolor sed urna. Donec sit amet quam eget diam fermentum pharetra. Integer tincidunt arcu ut purus. Cum sociis natoque penatibus et magnis dis parturient montes, nascetur ridiculus mus. Nulla blandit malesuada odio. Nam augue. Aenean molestie sapien in mi. Suspendisse tincidunt. Pellentesque tempus dui vitae sapien. Donec aliquam ipsum sit amet pede. Sed scelerisque mi a erat. Curabitur rutrum ullamcorper risus. Maecenas et lorem ut felis dictum viverra. Fusce sem. Donec pharetra nibh sit amet sapien.</p>
<p>Aenean ut orci sed ligula consectetuer pretium. Aliquam odio. Nam pellentesque enim. Nam tincidunt condimentum nisi. Maecenas convallis luctus ligula. Donec accumsan ornare risus. Vestibulum id magna a nunc posuere laoreet. Integer iaculis leo vitae nibh. Nam vulputate, mauris vitae luctus pharetra, pede neque bibendum tellus, facilisis commodo diam nisi eget lacus. Duis consectetuer pulvinar nisi. Cras interdum ultricies sem. Nullam tristique. Suspendisse elementum purus eu nisl. Nulla facilisi. Phasellus ultricies ullamcorper lorem. Sed euismod ante vitae lacus. Nam nunc leo, congue vehicula, luctus ac, tempus non, ante. Morbi suscipit purus a nulla. Sed eu diam.</p>
<p>Vestibulum ante ipsum primis in faucibus orci luctus et ultrices posuere cubilia Curae; Cras imperdiet felis id velit. Ut non quam at sem dictum ullamcorper. Vestibulum pharetra purus sed pede. Aliquam ultrices, nunc in varius mattis, felis justo pretium magna, eget laoreet justo eros id eros. Aliquam elementum diam fringilla nulla. Praesent laoreet sapien vel metus. Cras tempus, sapien condimentum dictum dapibus, lorem augue fringilla orci, ut tincidunt eros nisi eget turpis. Nullam nunc nunc, eleifend et, dictum et, pharetra a, neque. Ut feugiat. Aliquam erat volutpat. Donec pretium odio nec felis. Phasellus sagittis lacus eget sapien. Donec est. Vestibulum ante ipsum primis in faucibus orci luctus et ultrices posuere cubilia Curae;</p>
<p>Vestibulum semper. Nullam non odio. Aliquam quam. Mauris eu lectus non nunc auctor ullamcorper. Sed tincidunt molestie enim. Phasellus lobortis justo sit amet quam. Duis nulla erat, varius a, cursus in, tempor sollicitudin, mauris. Aliquam mi velit, consectetuer mattis, consequat tristique, pulvinar ac, nisl. Aliquam mattis vehicula elit. Proin quis leo sed tellus scelerisque molestie. Quisque luctus. Integer mattis. Donec id augue sed leo aliquam egestas. Quisque in sem. Donec dictum enim in dolor. Praesent non erat. Nulla ultrices vestibulum quam.</p>
<p>Duis hendrerit, est vel lobortis sagittis, tortor erat scelerisque tortor, sed pellentesque sem enim id metus. Maecenas at pede. Nulla velit libero, dictum at, mattis quis, sagittis vel, ante. Phasellus faucibus rutrum dui. Cras mauris elit, bibendum at, feugiat non, porta id, neque. Nulla et felis nec odio mollis vehicula. Donec elementum tincidunt mauris. Duis vel dui. Fusce iaculis enim ac nulla. In risus.</p>
<p>Donec gravida. Donec et enim. Morbi sollicitudin, lacus a facilisis pulvinar, odio turpis dapibus elit, in tincidunt turpis felis nec libero. Nam vestibulum tempus ipsum. In hac habitasse platea dictumst. Nulla facilisi. Donec semper ligula. Donec commodo tortor in quam. Etiam massa. Ut tempus ligula eget tellus. Curabitur id velit ut velit varius commodo. Vestibulum ante ipsum primis in faucibus orci luctus et ultrices posuere cubilia Curae; Nulla facilisi. Fusce ornare pellentesque libero. Nunc rhoncus. Suspendisse potenti. Ut consequat, leo eu accumsan vehicula, justo sem lobortis elit, ac sollicitudin ipsum neque nec ante.</p>
<p>Aliquam elementum mauris id sem. Vivamus varius, est ut nonummy consectetuer, nulla quam bibendum velit, ac gravida nisi felis sit amet urna. Aliquam nec risus. Maecenas lacinia purus ut velit. Vestibulum ante ipsum primis in faucibus orci luctus et ultrices posuere cubilia Curae; Suspendisse sit amet dui vitae lacus fermentum sodales. Donec varius dapibus nisl. Praesent at velit id risus convallis bibendum. Aliquam felis nibh, rutrum nec, blandit non, mattis sit amet, magna. Lorem ipsum dolor sit amet, consectetuer adipiscing elit. Pellentesque habitant morbi tristique senectus et netus et malesuada fames ac turpis egestas. Etiam varius dignissim nibh. Quisque id orci ac ante hendrerit molestie. Aliquam malesuada enim non neque.</p>
</div>

</body>
</html>

dongryphon
7 Nov 2011, 11:13 AM
@MrSparks,

Thanks again for all your help! I will definitely look at that to see where the bottlenecks are and get back to you. Hopefully today or tomorrow.

MrSparks
7 Nov 2011, 11:15 AM
@Don,

Great to hear. If you want any profiles from this end, let me know.

skirtle
7 Nov 2011, 6:48 PM
I gave MrSparks's examples a try. My observations are below. In short, I agree that 3.4.0 appears to be much faster than 4.1-pr1.


Running 4.1-pr1 in IE 6, the load time increased by 2s each time I hit F5. That's some scary leakage going on.
Initial load time of 4.1-pr1 is much better than 4.0.7. About 30% faster in IE 6 and IE 8.
Initial load time of 3.4.0 appears much better than 4.1-pr1, though it is difficult to be sure that we're comparing like for like. Seemed to be about a factor of 3 for IE.
The UI was noticeably snappier in 3.4.0. Clicking on tabs or collapsing regions was fast in all browsers. In 4.1-pr1 it's reasonable in Chrome but really sluggish in IE. For me this is much more important than the initial load time.
The example uses a lot of tabs and a card layout with deferred rendering disabled. While this is entirely understandable for a test case, I think it would be wrong to conclude that a real UI would take 20s to render. When I turned on deferred rendering it loaded much faster (but, of course, so did 3.4.0).

nicholasnet
8 Nov 2011, 6:53 AM
I think development team also needs to look at class structure. May be it is little too late for this but class structure of 4.x seems to be much more complicated than 3.x. Just look at the class hierarchy of Grid Panel in 3.x and 4.x. You will see that in 4.x version it is quite complex. Too much of abstraction and OO wizardry. Just my 2 cents.

stahlman
8 Nov 2011, 11:04 AM
I think development team also needs to look at class structure. May be it is little too late for this but class structure of 4.x seems to be much more complicated than 3.x. Just look at the class hierarchy of Grid Panel in 3.x and 4.x. You will see that in 4.x version it is quite complex. Too much of abstraction and OO wizardry. Just my 2 cents.

I agree. Unfortunately, I also agree that it may be a little too late, in the sense that I really don't see a good solution at this point. The time to reject the extreme OO paradigm - as aesthetically pleasing but totally impractical - was during the early whiteboard/prototyping stages. Short of a complete rewrite of the 4.1 rewrite, I doubt the v4.x code base will ever be able to get even close to v3 performance. Moreover, I fear that the complexity of the layouts is such that it could take as long for 4.1 to reach a stable state as it did for 4.0. (If I recall correctly, significant 4.0 layout bugs were still being discovered around the time 4.1 pr was rolling out.) Going back to the theme of my earlier post, I'm thinking that the Ext designers would do well to consider the benefits of the "Convention over Configuration" philosophy popularized by Ruby on Rails...

skirtle
8 Nov 2011, 1:31 PM
I have been wondering the same thing but I wouldn't dismiss the new class system quite yet, not until there's a concrete explanation for why it would cause performance problems. It may be to blame for some of the performance hit during initial load time but it's less clear how it could be to blame for UI snapiness during, for example, resize operations.

I did a bit of analysis comparing 3 & 4 in Chrome using MrSparks's example. It seems that the DOM contains fewer elements in 4, which can surely only be a good thing. However, the heap dump showed that 4 had huge numbers of arrays, strings and objects, far more than 3. Whether these actually affect performance is another matter but I do notice that a significant chunk of the initial load time is taken up by garbage collection. It doesn't account for the time difference in loading but it is suspicious.

stahlman
8 Nov 2011, 3:53 PM
@dongryphon - If you're looking for a complex app to profile, you might try the Ext JS API docs. When I run IE8, the following page takes around 44 seconds to load:
http://docs.sencha.com/ext-js/4-0/#!/api (http://docs.sencha.com/ext-js/4-0/#%21/api)

The same page in Chrome takes only a couple of seconds...

rich02818
8 Nov 2011, 6:06 PM
I have been wondering the same thing but I wouldn't dismiss the new class system quite yet, not until there's a concrete explanation for why it would cause performance problems. It may be to blame for some of the performance hit during initial load time but it's less clear how it could be to blame for UI snapiness during, for example, resize operations.

I did a bit of analysis comparing 3 & 4 in Chrome using MrSparks's example. It seems that the DOM contains fewer elements in 4, which can surely only be a good thing. However, the heap dump showed that 4 had huge numbers of arrays, strings and objects, far more than 3. Whether these actually affect performance is another matter but I do notice that a significant chunk of the initial load time is taken up by garbage collection. It doesn't account for the time difference in loading but it is suspicious.

That is very interesting. Moving bytes around in string handling has historically been an area of performance concern. Substantially increasing this from v3 may go a long way toward explaining the sluggishness of v4. In the *old days* writing string handling routines in assembler and using static string/array allocation (avoiding dynamic strings/arrays) were easy ways to increase overall application performance

Gummy
8 Nov 2011, 7:57 PM
@dongryphon - If you're looking for a complex app to profile, you might try the Ext JS API docs. When I run IE8, the following page takes around 44 seconds to load:
http://docs.sencha.com/ext-js/4-0/#!/api (http://docs.sencha.com/ext-js/4-0/#%21/api)

The same page in Chrome takes only a couple of seconds...
I tried with IE8, it loads in 2 seconds. Maybe you mean IE6 ? Loading it with IE6 takes forever, and then browsing the API is too frustrating to be usable.

I think we have to accept that ExtJS 4 doesn't support IE6, and that it doesn't matter.
A few months ago there was 5% of IE6, now it's 2%, and soon it will be as common as Mosaic.
Performance and reliability improvement should focus on newer browser version.

LesJ
9 Nov 2011, 2:25 AM
See what the Dojo team did to improve IE performance:

http://shaneosullivan.wordpress.com/2010/08/28/dojo-gets-a-speed-boost-on-ie6-and-ie7/

T (http://shaneosullivan.wordpress.com/2010/08/28/dojo-gets-a-speed-boost-on-ie6-and-ie7/)he comments about DynaTrace and className touching might be useful.

skirtle
9 Nov 2011, 3:19 AM
Interesting article. From comparing the removeCls methods in 4.0.7 to 4.1-pr1 it looks like className touching is one of the improvements being targeted.

stahlman
9 Nov 2011, 4:53 AM
@Gummy - No. I meant IE8: Version: 8.0.7601.17514
No idea what the difference could be between our setups. I haven't had a chance to investigate fully. I did run a few times with Developer Tools open, and noticed the following error appeared several times:
"Store defined with no model. You may have mistyped the model name."

Interestingly, it takes roughly the same length of time (>40 seconds) to load the Sencha home page...
http://www.sencha.com
...though several other websites I tried (cnn, jquery, drudgereport) load very quickly in IE8 (on the order of a second or two). Unfortunately, Dev Tools doesn't seem to provide a Net tab, so it's not immediately obvious what's taking all the time. Will post again if I learn something...

skirtle
9 Nov 2011, 5:01 AM
You can ignore that error message in the docs app, it's an over-zealous warning.


Unfortunately, Dev Tools doesn't seem to provide a Net tab, so it's not immediately obvious what's taking all the time.

If you want to dig further...


Try the docs app using a local copy of the docs.
Use Fiddler to get a better sense of where time is being lost.
Use DynaTrace if you're feeling really keen.


I would guess this is a networking issue judging by what you've observed so far.

stahlman
9 Nov 2011, 5:09 AM
Try the docs app using a local copy of the docs.

I first noticed the issue running this way. The time to load is over 40 seconds even when I serve from localhost.


I would guess this is a networking issue judging by what you've observed so far.

How could it be a network issue when the abnormally long load times are observed only in IE and only on the Sencha site?

skirtle
9 Nov 2011, 5:43 AM
How could it be a network issue when the abnormally long load times are observed only in IE and only on the Sencha site?

Actually, even running the docs on localhost isn't necessarily conclusive as it makes some requests to other domains.

My theory goes a bit like this. Different browsers often have different networking settings, e.g. proxies. If a proxy has problems contacting a particular domain (all sorts of reasons that could happen) then it'll only affect the browser that's using the proxy.

40s is long enough that it suggests you're hitting a timeout somewhere. It's possible other browsers are running up against the same timeout but they're handling it more gracefully. Try opening the docs in FF and see whether the Net tab shows anything time out after 40s.

stahlman
9 Nov 2011, 6:16 AM
...
I did a bit of analysis comparing 3 & 4 in Chrome using MrSparks's example. It seems that the DOM contains fewer elements in 4, which can surely only be a good thing. However, the heap dump showed that 4 had huge numbers of arrays, strings and objects, far more than 3. Whether these actually affect performance is another matter but I do notice that a significant chunk of the initial load time is taken up by garbage collection. It doesn't account for the time difference in loading but it is suspicious.

A week or so ago, I did a bit of digging into the way 4.1 was generating its markup. It appears that the generateMarkup method is called (in a highly recursive fashion) to generate an array representing a "tree" of html markup to be inserted in the dom. This array tends to be very large, because the html it contains is tokenized: e.g., it's not uncommon to see a sequence of elements such as...
"<", "div", " ", "id", "=", ...

In my particular application, a number of the trees so built contained over 1000 elements, with the largest I observed weighing in at between 6 and 7000 elements. After the array is fully built (through the use of templates and dynamically-compiled anonymous render functions), it is joined to produce the html markup string to be inserted in the dom. I'm guessing that all of this string/array manipulation comes at a cost, most likely a browser-dependent one...

Don't know how much (if at all) it's used in 4.1 pr, but I did notice while using 4.x that IE was spending a lot of time in spliceSim, the non-native method used as a workaround for a known IE8 bug involving the native Array.splice. I doubt that has anything to do with the IE issues I'm seeing on the documentation site, however, as I didn't see that routine in the profile.

stahlman
9 Nov 2011, 6:58 AM
@skirtle - I'm starting to suspect the following "Embedded Open Type" file, which seems to spend a long time in the status bar during page load:
use.typekit.com/k/uxj6dew-c-8007056-7081.eot?3bb2a6e53...<very long id string of some sort>

As I understand it, Embedded Open Type fonts are a Microsoft creation, which perhaps explains why the Net traces in FF and Chrome don't show this file at all. Not sure what would prevent its loading properly/efficiently in my browser. There appear to be 2 additional files (js and css) pulled from that same domain, and IE is able to access both of them.

stahlman
9 Nov 2011, 12:06 PM
I've confirmed that an EOT (Embedded Open Type) font file served from use.typekit.com is what's causing the excessive load times for API docs in IE8. At skirtle's suggestion, I used Fiddler to inspect the traffic and saw that the request for uxj6dww-c-8007056-7081.eot was failing with a status of 504 (Gateway Timeout). According to the article referenced below, if the document contains a <script> tag prior to the @font-face referencing the eot file, page rendering is blocked until the eot file is completely loaded (or in this case, until it times out with error after 40+ seconds).

http://www.stevesouders.com/blog/2009/10/13/font-face-and-performance/

(http://www.stevesouders.com/blog/2009/10/13/font-face-and-performance/)This certainly would explain the behavior I'm seeing. In light of the potential for issues, I'm wondering whether it might be best to remove the Sencha site's dependency on eot files altogether. Surely I'm not the only corporate user whose browser settings preclude his downloading this file. I'm thinking that the font data is stored in a data url in FF and Chrome. Perhaps a similar approach would work for IE? Or perhaps the eof file could be referenced before the first <script> tag to ensure that rendering isn't deferred...

skirtle
9 Nov 2011, 5:01 PM
I suggest reporting the fonts issue here:

http://www.sencha.com/forum/showthread.php?135036

dongryphon
10 Nov 2011, 11:17 PM
I have been wondering the same thing but I wouldn't dismiss the new class system quite yet, not until there's a concrete explanation for why it would cause performance problems. It may be to blame for some of the performance hit during initial load time but it's less clear how it could be to blame for UI snapiness during, for example, resize operations.

Agreed. There may be cost at load time and we are looking into that. A deep(er) prototype chain might have run-time cost on old browsers, but it doesn't seem to be the critically hot performance areas.


I did a bit of analysis comparing 3 & 4 in Chrome using MrSparks's example. It seems that the DOM contains fewer elements in 4, which can surely only be a good thing. However, the heap dump showed that 4 had huge numbers of arrays, strings and objects, far more than 3. Whether these actually affect performance is another matter but I do notice that a significant chunk of the initial load time is taken up by garbage collection. It doesn't account for the time difference in loading but it is suspicious.

The extra memory there is probably due to bulk rendering - we push string fragments into an array and join('') it to produce the render tree which we then write via innerHTML. When this was benchmarked against the non-bulk-rendering approach, it showed itself to be much faster even given the extra memory use.

Of course we could be paying that back for the next bit while GC cleans up.

dongryphon
10 Nov 2011, 11:21 PM
See what the Dojo team did to improve IE performance:

http://shaneosullivan.wordpress.com/2010/08/28/dojo-gets-a-speed-boost-on-ie6-and-ie7/

The comments about DynaTrace and className touching might be useful.

Interesting article. Our add/removeCls methods do check for non-change and generate one write to className. We have already considered a combo method that can add and remove in a single step, but it would only be rarely useful internally.

skirtle
11 Nov 2011, 3:11 AM
The extra memory there is probably due to bulk rendering - we push string fragments into an array and join('') it to produce the render tree which we then write via innerHTML. When this was benchmarked against the non-bulk-rendering approach, it showed itself to be much faster even given the extra memory use.

Of course we could be paying that back for the next bit while GC cleans up.

While my profiling did show a lot of GC, I don't know when that occurs. It could easily have been once rendering is finished and there's nothing else going on. That's my understanding of how GC is supposed to work...

I don't think the bulk rendering accounts for all the extra stuff in the heap dump. I added the following code to MrSparks's example:


var Tracker = function() {
Tracker.count++;
};

Tracker.count = 0;

(function() {
var join = Array.prototype.join;

Array.prototype.join = function() {
if (!this.tracker) {
this.tracker = new Tracker();
}

return join.apply(this, arguments);
};
})();

I also added similar code into XTemplate.applyOut.

What this does is tag each array used for a join operation with a Tracker class. I can then see those trackers in the heap dump and trace their GC roots.

Thousands of arrays were augmented (it keeps count) but only about 12 trackers made it through to the heap dump. I think all were caught in closures rather than deliberately kept and whilst this does indicate a memory leak it was only 12 relatively small arrays. The biggest culprit was the cache in Ext.DomQuery.select, which captures the array fn in the line:


eval(fn.join(""));

I then turned my attention to the strings. Some of the largest strings were HTML fragments, so I thought I might be on to something there. Turned out they were html properties on XTemplates. I made a small tweak to XTemplate so that it wiped the html property after it was compiled. While this did make those strings disappear from my heap dump it really made very little difference in the grand scheme of things.

One other observation I made is that grids keep recreating the same XTemplate over and over again. The compile times add up. It probably isn't significant compared to some of the other optimizations you're making but I managed to save myself about 5% on grid resize times by adding in a crude cache.

MrSparks
11 Nov 2011, 5:40 AM
@Don,

Do you feel that you are making any headway on understanding the IE issues on the 4.x framework? Can you see fundamental problem anywhere?

Best
MrSparks

silcreval
11 Nov 2011, 11:33 PM
When ExtJS 4 launched, I had that creeping feeling that ExtJS 4.x was suffering a
bit from the 'second system effect' (google Fred Brooks mythical man month).

Many frameworks get revised, and the API can get changed at some point,
and its understandable, we all want to work on modern 'clean' code, with the
latest features, etc. With the move from 3 to 4 its clear there is a push towards
an enterprise application development tool - and again its understandable.

However, and I can only speak for myself on this, performance is THE critical factor
for javascript frameworks.

Users might forgive the odd bug, I can work around 'issues' like I did with ExtJS 2
and 3. But if the performance of the framework is bad - there is very little I can do.

Performance is the 'killer app' as far as I'm concerned on javascript frameworks.

I'm glad to see this is getting some serious attention with ExtJS 4.1, but we need to
see a significant improvement.

Personally, I would remove features which are causing serious performance issues at
this stage. I would also be tempted to remove support for some of the older browsers
if this is causing serious problems, or taking a lot of developer time. Just my personal
opinion though - I understand some developers need that support.

On the theme - again I would simplify it if necessary.

Browser performance has increased dramatically in the past few years, but we cant
rely on this going forward...

skirtle
12 Nov 2011, 2:19 AM
Users might forgive the odd bug, I can work around 'issues' like I did with ExtJS 2 and 3. But if the performance of the framework is bad - there is very little I can do.

I've heard a lot of people say this but personally I've never found this to be true. While I understand that there's only so much you can do to overcome a fundamental architectural performance problem, I tend to find that I can squeeze a load more performance out of my apps just by targeting my own use case.

As you noted, out-of-the-box components need to support older browsers and all sorts of wildly varying configurations. In practice, your app may well only need to support a subset of browsers and the configuration of each component is known exactly. This gives you a major advantage in applying optimizations that might be much more difficult to attempt in the more general case.

Just like any other application, once in a while you have to break out a profiler and do some work to speed things up. This includes monkey-patching Ext the same way you would for any other bug.


Personally, I would remove features which are causing serious performance issues at this stage. I would also be tempted to remove support for some of the older browsers if this is causing serious problems, or taking a lot of developer time. Just my personal opinion though - I understand some developers need that support.

Many developers aren't suffering performance problems and you can no doubt imagine their response to losing the features they were using.

While the performance of ExtJS 4 is currently slower than ExtJS 3 in all browsers, I think most of the headaches surround older browsers. While it may not be universally the case, I suspect most developers would be able to tolerate the current performance were they not trying to support older versions of IE. Trying to improve performance by ignoring older browsers doesn't really address the majority need.

rich02818
12 Nov 2011, 6:22 AM
I've heard a lot of people say this but personally I've never found this to be true. While I understand that there's only so much you can do to overcome a fundamental architectural performance problem, I tend to find that I can squeeze a load more performance out of my apps just by targeting my own use case.

Which you can't do if your business customer is actually defining the use case and the basic UI. Try having several tabbed pages which are individually complex and run it in v4 on IE8...


...snip...
Many developers aren't suffering performance problems and you can no doubt imagine their response to losing the features they were using.

Then their apps have very simple UI with few components and perhaps no tabbed pages. As well documented in these forums it does not take a very complex UI to see the severe slowdown in v4 compared to v3 ... and don't forget that it has been acknowledged that v3 was itself *too slow*. V4 was supposed to resolve the poor v3 performance.


While the performance of ExtJS 4 is currently slower than ExtJS 3 in all browsers, I think most of the headaches surround older browsers. While it may not be universally the case, I suspect most developers would be able to tolerate the current performance were they not trying to support older versions of IE. Trying to improve performance by ignoring older browsers doesn't really address the majority need.

Business apps will absolutely *have* to run acceptably on IE8 running on XP machines for years to come. Certainly IE9 is much faster, but XP machines can't run it and will not disappear any time soon. True business apps are complex and must have good performance. ExtJS developers are helpless to resolve fundamental performance issues that reside within the framework.

saprot
12 Nov 2011, 6:46 AM
quote from http://www.sencha.com/blog/ext-js-4-preview-faster-easier-more-stable/


Everyone cares about performance - whether it’s how fast our applications load, how long they take to render and layout, or how fast they feel when interacted with. One of the most time-consuming parts of application execution is layout. Ext JS 4 features a brand new layout engine, using all of the experience we have gained crafting this framework over the last 4 years. Those who were able to join us at the conference saw just how fast the new layout engine is, and that it uses the exact same API as Ext JS 3. Although the layout engine is by no means the only performance improvement we have made, it has such a stunning impact that it deserves its own special treatment in a blog post nearer the release date. Ext JS 4 is far faster than anything we've ever created.


image from http://www.slideshare.net/edspencer/intro-to-ext-4

29245

(http://www.slideshare.net/edspencer/intro-to-ext-4)What has happened during the developement process?

skirtle
13 Nov 2011, 12:02 AM
@rich02818. Largely agree with you but you lost me in the bit about business customers. It doesn't matter who is coming up with the specifications, once you've written the UI it is possible to optimize it.

Whether you can optimize it enough to make performance acceptable is another matter. That doesn't mean you shouldn't try. Simple optimizations are just config tweaks, like the ones mentioned here:

http://www.sencha.com/forum/showthread.php?153565

More advanced optimizations need you to break out the profiler (Chrome has one built in, for IE I'd use DynaTrace). You may find you can get a load more performance just by patching sections of the library to reflect the configurations you're using.

Don't let the volume of forum activity surrounding performance put you off trying to optimize your app. I've seen a number of examples where people have complained of horrendous Ext 4 performance where the problems were being hugely magnified by their own app code.

Don't get me wrong, many apps won't be fast enough even after optimizing. When I'm asked for my opinion about upgrading apps from 3 to 4 I currently advise staying on 3 and performance is the reason I give. I just think that too many developers are assuming that all their performance problems lie in the framework when they haven't made a genuine attempt to optimize their apps.

rich02818
13 Nov 2011, 5:26 AM
Concerning optimizing our own apps for performance. I'll be much more willing to attack this when I have any objective reason to believe that the result will be acceptable for deployment (and that means on IE8 as my customers are business, not just websites - many large enterprises are not going to abandon XP and IE8 any time soon). How about Sencha optimize their own examples used to demonstrate ExtJSv4 so that they are faster than v3? That evidence would allow me to believe that my own efforts would be successful. Of course, if v4 could just render the basic elements as shown in the examples with the performance promised, then I would not need to do anything else at the moment...

tvanzoelen
14 Nov 2011, 2:36 AM
These Buffered thing Animal is talking about http://www.sencha.com/forum/showthread.php?153565-ExtJS-Performance-Best-Practices/page2. Should be a standard part of the Store. So that it is done in ExtJs without extra implementations done by the developper. Whit prefetch et cetera.

Animal is talking about 100K records, well 8K is a crash in my app. But in ExtJs it was 1.5K so there is improvement.

dongryphon
14 Nov 2011, 11:24 AM
To handle large numbers of records, you'll probably need a custom reader to avoid any and all "no-op" conversions or transformations, but this almost sounds like these are being rendered. I know I have seen very large amount of pure data (no DOM) work w/o a problem. Maybe not 100k, but certainly 10k's.

stahlman
14 Nov 2011, 11:38 AM
@rich02818.

Don't let the volume of forum activity surrounding performance put you off trying to optimize your app. I've seen a number of examples where people have complained of horrendous Ext 4 performance where the problems were being hugely magnified by their own app code.

Don't get me wrong, many apps won't be fast enough even after optimizing. When I'm asked for my opinion about upgrading apps from 3 to 4 I currently advise staying on 3 and performance is the reason I give. I just think that too many developers are assuming that all their performance problems lie in the framework when they haven't made a genuine attempt to optimize their apps.

I have spent *way* too much development time (in a project with a highly compressed schedule) attempting to optimize my application to the point that it's usable in IE8 (and it still isn't, according to my definition of "usable"). The time spent on this fool's errand was time we didn't have to put into the meat of the application: i.e., robustness of the backend, business logic, etc... The fact is, a UI is not something that's supposed to require optimization on the part of the application developer. A framework that requires the application developer to spend a lot of time optimizing the UI is failing to deliver, in my opinion, on one of the primary objectives of a UI framework.

When developers attempt to sell a JS framework to management or a customer, the justification typically involves savings in development time over something like jQuery or even JS and DHTML alone. Given the weeks wasted in "optimization" with Ext, I don't think we could honestly make that claim for Ext JS 4...

lager
14 Nov 2011, 11:57 AM
@skirtle, I have to say that I feel a bit surprised on how you respond to customer's concerns on bad performance in ExtJS 4. Is the general opinion from Sencha that we should go out and monkey-patch the framework to make it usable? Isn't it obvious that the performance problems goes way beyond what is reasonable?


@rich02818, @stahlman, I agree with everything you said.

LesJ
14 Nov 2011, 11:59 AM
stahlman, there's a super easy way to speed up you application in IE :>

http://code.google.com/chrome/chromeframe/

dongryphon
14 Nov 2011, 12:55 PM
@Don,

As promised, here an example app that performs as follows.

FYI: I managed to get the layouts working under 4.1 PR1, so its safe to profile against that framework

IE 8 - EXT JS 3.4.0 - 4.078 Seconds
Chrome 15 - EXT JS 3.4.0 - 1.227 Seconds

IE 8 - EXT JS 4.1 PR1 - 22.406 Seconds
Chrome 15 - EXT JS 4.1 PR 1 - 2.731 Seconds



http://www.sencha.com/forum/showthread.php?153008&p=669796&viewfull=1#post669796

My testing of this has the following timings:

IE8
3.4.0 - 1273 ms / 1395 ms
4.0.7 - 6954 ms / 7351 ms
4.1.0 - 4040 ms / not measured (my current build)

The only change I made to your code was to also measure inside of onReady for the sake of this comparison (to avoid measuring the dynamic loader in my 4.1 test harness). I did not enable deferRender.

What kind of machine are you using for a benchmark box? We have some mediocre machines we use for this (this one is Core i3 2.1 GHz laptop running Windows 7 64-bit), but maybe they are speed demons by comparison... :)

In all seriousness though, this is a key factor (and a rather obvious one) so I am curious to know if we may also need to consider the hardware platform on which we base performance acceptance criteria. Some time back, we decided to use only real hardware (no VM's) for these tests since we were getting rather jittery results probably from the host OS load level.

We have some ground to make up still when we consider just relative performance. We are currently in stabilize mode and have been for quite some time, but I hope we can get in a couple other promising changes before we call 4.1 done. TBD on that at the moment since we really focused right now on getting 4.1 beta and final released.

Again, thanks for taking the time to dig in and provide such a useful example!

rich02818
14 Nov 2011, 1:54 PM
My testing of this has the following timings:

IE8
3.4.0 - 1273 ms / 1395 ms
4.0.7 - 6954 ms / 7351 ms
4.1.0 - 4040 ms / not measured (my current build)

Why did you not measure with your current build? Doesn't work, or you don't expect it to be faster?


The only change I made to your code was to also measure inside of onReady for the sake of this comparison (to avoid measuring the dynamic loader in my 4.1 test harness). I did not enable deferRender.

What kind of machine are you using for a benchmark box? We have some mediocre machines we use for this (this one is Core i3 2.1 GHz laptop running Windows 7 64-bit), but maybe they are speed demons by comparison... :)

In all seriousness though, this is a key factor (and a rather obvious one) so I am curious to know if we may also need to consider the hardware platform on which we base performance acceptance criteria. Some time back, we decided to use only real hardware (no VM's) for these tests since we were getting rather jittery results probably from the host OS load level.

Mr. Sparks showed v4.1pr1 to be 5.49x slower than v3.4.0; you changed the test case slightly and showed 4.1pr1 to be 3.17x slower than v3.4.0. I'd say that confirms that this test case shows 4.1pr1 to have a serious performance problem.



We have some ground to make up still when we consider just relative performance. We are currently in stabilize mode and have been for quite some time, but I hope we can get in a couple other promising changes before we call 4.1 done. TBD on that at the moment since we really focused right now on getting 4.1 beta and final released.

Again, thanks for taking the time to dig in and provide such a useful example!

I'm afraid that this means we shouldn't expect 4.1 to even approach 3.4.0 in performance...please tell me I'm wrong.

MrSparks
14 Nov 2011, 2:40 PM
@Don,

Platform wise I’ve tested on a few decent spec systems but I have to say all of my benchmarks are consistent in relative terms.

For arguments sake my Dev (physical) box spec is:
Intel Pentium 4 - 3.2GHz
4GB Dual DDR - CL2.5
300GB 10K SATA - Raid 1
NVidia GeForce 7800 GS

I have benchmarked on a business class system and of course that’s a higher spec that my dev box and EXTJS ran faster. However it a mute point because this is a benchmark comparisons between 3.4.0 and 4.x (framework benchmarks). We’re not performing benchmarks comparisons between hardware.

Taking your benchmarks, on a system that would be classed as a very high spec for a business class user. 3.4.0 is over 3 times faster than 4.1.0 when using IE 8. That’s really highlights the fact than even with super fast machine 4.1.0 can’t touch 3.4.0. In fact really proves the point that no matter what the hardware 4.1.0 always comes out slower. Again if you run the same test on Chrome on that laptop, 3.4.0 out performs 4.1.0

dongryphon
14 Nov 2011, 3:06 PM
Why did you not measure with your current build? Doesn't work, or you don't expect it to be faster?

I don't expect the load vs onReady delta to be a lot different than it was in 4.0.7, though a bit faster. The real reasons are just that it would take more steps to make a real build (we use dynamic loading primarily during development) and I was really much more interested in the time spent in onReady itself.


Mr. Sparks showed v4.1pr1 to be 5.49x slower than v3.4.0; you changed the test case slightly and showed 4.1pr1 to be 3.17x slower than v3.4.0. I'd say that confirms that this test case shows 4.1pr1 to have a serious performance problem.

...snip...

I'm afraid that this means we shouldn't expect 4.1 to even approach 3.4.0 in performance...please tell me I'm wrong.

It is currently deemed a blocker to regress the performance baseline as we have measured it using our own internal benchmarks (Themes example and a few others). Whether or not there will be time allocated to pursue some of the other improvements to which I alluded is TBD.

The key there, I think, is to incorporate examples that are more like real world apps (as did MrSparks) so we can make the performance baseline a proper acceptance criteria.

dongryphon
14 Nov 2011, 3:29 PM
@Don,

Platform wise I’ve tested on a few decent spec systems but I have to say all of my benchmarks are consistent in relative terms.

For arguments sake my Dev (physical) box spec is:
Intel Pentium 4 - 3.2GHz
4GB Dual DDR - CL2.5
300GB 10K SATA - Raid 1
NVidia GeForce 7800 GS


Thanks. I recognize that information - I probably need to make this a sticky post or something ;)


I have benchmarked on a business class system and of course that’s a higher spec that my dev box and EXTJS ran faster. However it a mute point because this is a benchmark comparisons between 3.4.0 and 4.x (framework benchmarks). We’re not performing benchmarks comparisons between hardware.

Agreed when we are talking about relative terms. But people (internally and externally) will often look at individual tests in absolute terms. Consciously our not, folks see 2 seconds and might conclude that is OK, but they see 10 and know that it is not - regardless of the relative comparison.

Since your 3.4 timings were 3x slower than mine, I would have expected 10-12 seconds for 4.1, not 22. Just makes me wonder how we could be measuring the same things. :) Is the installation of Windows very old maybe or perhaps had lots of apps installed/removed? I've seen Windows get crazy in its old age... where "old age" is somewhere between 6-12 months.


Taking your benchmarks, on a system that would be classed as a very high spec for a business class user. 3.4.0 is over 3 times faster than 4.1.0 when using IE 8. That’s really highlights the fact than even with super fast machine 4.1.0 can’t touch 3.4.0. In fact really proves the point that no matter what the hardware 4.1.0 always comes out slower. Again if you run the same test on Chrome on that laptop, 3.4.0 out performs 4.1.0

I could see that spec as "high end" in some environments, but it was the lowest-end laptop you could get 6 months ago basically. We probably need to mine eBay for some even older machines.

Agreed - the relative performance of 3.4 vs 4 vs 4.1 is rather stable regardless of actual speed. Except with your mystery machine as noted above ;)

Again, thanks for all your help and input!

rich02818
14 Nov 2011, 4:37 PM
It is currently deemed a blocker to regress the performance baseline as we have measured it using our own internal benchmarks (Themes example and a few others). Whether or not there will be time allocated to pursue some of the other improvements to which I alluded is TBD.

After scratching my head a bit, I think this means that you won't release a build that is worse than its predecessor. Is this correct? Does this mean that v4.1 when released will likely be 3x slower than 3.4.0 on examples such as that provided by Mr. Sparks?

skirtle
14 Nov 2011, 4:49 PM
@skirtle, I have to say that I feel a bit surprised on how you respond to customer's concerns on bad performance in ExtJS 4. Is the general opinion from Sencha that we should go out and monkey-patch the framework to make it usable? Isn't it obvious that the performance problems goes way beyond what is reasonable?

@rich02818, @stahlman, I agree with everything you said.

Just in case there was any confusion, I do not work for Sencha and the views I have expressed are purely my own. They do not necessarily reflect the views of Sencha or its developers.

I agree that the performance of ExtJS 4 is not yet acceptable. If I gave you the impression that I think otherwise then I apologize. Sencha have also made it clear on a number of occasions that they see performance as the top priority for the next few releases.

Monkey-patching to solve performance issues is not the ideal solution but it's currently all we have. If you can afford to wait for Sencha to solve these issues then obviously there's no point trying to do it yourself. However, not everyone has the luxury of being able to wait and for those developers who desperately need to improve performance right now so that they can make a release it may be worth a shot at optimizing. There's no guarantees it will work, it's just something to consider. In many cases, like that of stahlman, it will prove fruitless and frustrating.

dongryphon
14 Nov 2011, 5:00 PM
After scratching my head a bit, I think this means that you won't release a build that is worse than its predecessor. Is this correct? Does this mean that v4.1 when released will likely be 3x slower than 3.4.0 on examples such as that provided by Mr. Sparks?

Sorry for the confusion there... I couldn't quite tell what I meant by that after re-reading it :)

The "performance baseline" we have right now is 4.1 PR1. So it is a blocker to regress from there. This is currently based on measuring the Themes example and a few others.

Whether or not we will be able to include further improvements in 4.1 is TBD. I wish I could say which way that decision will go, but it is not mine to make.

Our current focus is stabilization, but we do have other promising things we want to do. These are much more isolated than the bulk of the work in 4.1 for rendering and layout, so we are not talking about large-scale efforts here. I will certainly post information regarding them if we do decide to scope them in to 4.1.

lager
14 Nov 2011, 11:33 PM
@skirtle - I confused you with an Sencha employee, my bad!

I've tried to find an official date for the 4.1 release, but haven't found one? Where can I find such information?

stahlman
15 Nov 2011, 5:58 AM
After scratching my head a bit, I think this means that you won't release a build that is worse than its predecessor. Is this correct? Does this mean that v4.1 when released will likely be 3x slower than 3.4.0 on examples such as that provided by Mr. Sparks?

@rich - To accept this would be to accept a "factor of 3" baseline shift from 3.4.0 to 4.0. Given that 4.0 was supposed to shift performance in the opposite direction, it seems unreasonable to consider 4.0 to be the "predecessor" to 4.1 in the context of the aforementioned acceptance test. With acceptance criteria applied selectively in this manner, it becomes far too easy to move the goalposts substantially in the wrong direction...

stevil
15 Nov 2011, 6:50 AM
@rich, @don,

I'm confident that Sencha will address the performance issues. The question is, will it happen soon enough to retain developer interest?

Don, I know you're all busting your tails to get this done, and get it done right. And getting it done right should be the priority. That said, if 3.4.0 is the baseline for performance improvements, I think that we're missing the mark.

2.3 was the gold standard for performance - things took a hit in 3.0, improved along the way to 3.4, but nothing has been as fast as the 2.x line.

stevil

MrSparks
15 Nov 2011, 6:54 AM
@Don,



Since your 3.4 timings were 3x slower than mine, I would have expected 10-12 seconds for 4.1, not 22. Just makes me wonder how we could be measuring the same things. Is the installation of Windows very old maybe or perhaps had lots of apps installed/removed? I've seen Windows get crazy in its old age... where "old age" is somewhere between 6-12 months.

My Windows installation is around 3 years old. Enterprise infrastructure, hardware and software have been my bread and butter for over a decade, so despite the 3 year life span of my OS, its fresh as a daisy. That’s not to say I haven’t spent considerable amounts of time isolating the issue. When 4.0 first dropped I spent a 2 week period going through my OS with a fine tooth comb, just to ensure that when I raised my concerns on the forum, they were correct.

Onto the 22 seconds mystery, that’s a good question but not a mystery. If you watch the CPU when EXTJS is doing its load, it’s driving the CPU hard. A CPU load of 70% or above is classed as being driven hard and at this point CPU performance profile starts curve off. Also the longer an app consumes CPU time for,the more context switching takes place, more and more OS processes backup behind what’s consuming the CPU time and the benchmark curves becomes ”far” less linier. You might argue from this that as long as an 4.x EXTJS app doesn’t take anymore than x seconds to load, then no one is likely to see this behaviour, however that’s out of the developers control and when the app gains size you will start to see the extended less linier load times. The only real solution for 4.x is to get it faster the 3.x and give devs a real usable performance window to play with.



I could see that spec as "high end" in some environments, but it was the lowest-end laptop you could get 6 months ago basically. We probably need to mine eBay for some even older machines.

That really depends on what industry you are in. The vast majority of company's are still sweating assets from pre 2008/2009 which when the world went financially pair-shaped. Until companies can afford to invest in new kit (which is probably few years away), business customers need to be treated with the above in mind.



Agreed - the relative performance of 3.4 vs 4 vs 4.1 is rather stable regardless of actual speed. Except with your mystery machine as noted above

As above, that’s just the way it is with PCs

With regards to hardware/os/sencha framework and what’s at fault. It can only be the 4.x framework which is causing the issue. Using the same browser on the same hardware, 3.4.0 vs 4.1 you see there is serious issue in 4.1


Again, thanks for all your help and input!


You are welcome, if you need any more input just shout. Again we really need to know if this is the right Framework for us. So if you can come back as soon as possible with an answer, we can take appropriate action.

Best
MrSparks

stahlman
15 Nov 2011, 7:01 AM
I'm confident that Sencha will address the performance issues.

@stevil,
Given what we've been hearing, I would say you are an incorrigible optimist... ;-) I think it's safe to say that 2.3 performance levels are a pipe dream at this point... Also, you seem to have misunderstood Don's position on performance baseline. (Either that or I have...) If I understood his post correctly, he considers 4.1 - not 3.4.0 - to be the performance baseline; hence, my concerns about "moving goalposts"...

dongryphon
15 Nov 2011, 10:37 AM
you seem to have misunderstood Don's position on performance baseline. (Either that or I have...) If I understood his post correctly, he considers 4.1 - not 3.4.0 - to be the performance baseline; hence, my concerns about "moving goalposts"...

Please don't confuse "baseline" with "goal".

The baseline simply serves as the point where a performance regression blocks the build process. Like a unit test failure. In a stabilization phase, the baseline is there to ensure we don't lose what we have gained in the previous optimization phases.

The "baseline" is also not necessarily the final word on "acceptance criteria" for 4.1. As I mentioned, that is TBD at this point.

stahlman
15 Nov 2011, 11:21 AM
Please don't confuse "baseline" with "goal".

The baseline simply serves as the point where a performance regression blocks the build process. Like a unit test failure. In a stabilization phase, the baseline is there to ensure we don't lose what we have gained in the previous optimization phases.

The "baseline" is also not necessarily the final word on "acceptance criteria" for 4.1. As I mentioned, that is TBD at this point.

Understood. Thanks. However, I think there may be a bit of confusion here on the difference between a goal (realistic and attainable) and a mere wish. Does anyone at Sencha still believe that they can get back to 3.4.0 or better performance levels by continuing to make incremental improvements to 4.1 (and its successor versions)? Personally, I find this highly improbable. It seems to me that this would require more of a paradigm shift (e.g., something of a rollback). The sense I get is that Sencha agrees with my assessment, but is assiduously avoiding making such statements publicly. While I can appreciate the reluctance to make such statements, I also think it would be better for Sencha in the long-run to be honest about what it believes is realistically attainable. Simply saying something to the effect of "We're going to keep performance a priority going forward" doesn't really give developers the information they need to make informed decisions about which framework is right for them on future projects.

tjstuart
15 Nov 2011, 2:39 PM
@rich, @don,
2.3 was the gold standard for performance - things took a hit in 3.0, improved along the way to 3.4, but nothing has been as fast as the 2.x line.

stevil

The reason I won't move beyond 2.3 (yet). 2.3 was a great release. None of the goodies in later versions have warranted a move IMO.

I do hope things improve beyond v4.

rich02818
16 Nov 2011, 6:10 AM
The reason I won't move beyond 2.3 (yet). 2.3 was a great release. None of the goodies in later versions have warranted a move IMO.

I do hope things improve beyond v4.

Will v2.3 run in IE9?

stevil
16 Nov 2011, 10:35 AM
@stevil,
Given what we've been hearing, I would say you are an incorrigible optimist... ;-) I think it's safe to say that 2.3 performance levels are a pipe dream at this point... Also, you seem to have misunderstood Don's position on performance baseline. (Either that or I have...) If I understood his post correctly, he considers 4.1 - not 3.4.0 - to be the performance baseline; hence, my concerns about "moving goalposts"...

I am an incorrigible optimist, thanks for noticing!

I don't know how Don's baseline can be 4.1, as it hasn't released yet - 3.4.0 is the most recent non-4 release against which to compare performance?

stahlman
16 Nov 2011, 10:50 AM
I am an incorrigible optimist, thanks for noticing!

I don't know how Don's baseline can be 4.1, as it hasn't released yet - 3.4.0 is the most recent non-4 release against which to compare performance?

@stevil,
While I don't claim to agree with the logic behind it, here's the statement from Don upon which I based my conclusions:

The "performance baseline" we have right now is 4.1 PR1. So it is a blocker to regress from there. This is currently based on measuring the Themes example and a few others.

tryanDLS
16 Nov 2011, 12:36 PM
Will v2.3 run in IE9?
I'm guessing it will 'run'. That's not to say you won't run into rendering issues. You'd probably want to look at what changed from 3.3 to 3.4 for IE9 support to see if you'd need to make similar changes for 2.3.

MrSparks
16 Nov 2011, 1:40 PM
Would be interested to know if 2.3 runs under IE 9 also.

Had a quick look at the online 2.3 examples under IE8 and it seems nice and fast. Will have to benchmark and see if 2.3 if the best route for my app.

beavx420
16 Nov 2011, 1:47 PM
Would be interested to know if 2.3 runs under IE 9 also.

Had a quick look at the online 2.3 examples under IE8 and it seems nice and fast. Will have to benchmark and see if 2.3 if the best route for my app.

This is what we do for our 2.3 code...

<meta http-equiv="X-UA-Compatible" content="IE=EmulateIE7,chrome=1" />

MrSparks
16 Nov 2011, 1:51 PM
@beavx420,

Many thanks for that :)

tjstuart
16 Nov 2011, 2:46 PM
Apologies as I seem to have taken this thread OT. However, i'll answer the questions raised ...

2.3 works perfectly in all IEs if you send the right doctype or meta tag.

IE <= 8 send <meta http-equiv="X-UA-Compatible" content="IE=7" />
IE > 8 send <!DOCTYPE html>

In fact, IE9 rendering was comprable to Firefox in terms of speed.

For example, a screen in one of our apps (200 widgets approx incl. grids, tabpanels, form elements etc) ...

IE7 683ms
IE8 589ms
IE9 216ms
FF5 192ms
Chrome13 84ms

There's also a few tweaks you can apply to Ext.lib.Event (which may not be in the official release; listener cache as an object vs array, _getCacheIndex, add/removeListener etc) which speed things up enormously, prevent memory blowout in long running enterprise apps and reduce the likelihood of the "Stop running this script" warning one typically receives on big destroys.

saprot
16 Nov 2011, 11:36 PM
There's also a few tweaks you can apply to Ext.lib.Event (which may not be in the official release; listener cache as an object vs array, _getCacheIndex, add/removeListener etc) which speed things up enormously, prevent memory blowout in long running enterprise apps and reduce the likelihood of the "Stop running this script" warning one typically receives on big destroys.

Sorry for offtop, but where to find these tweaks?

nomack84
17 Nov 2011, 8:21 AM
It will be a big problem for Sencha if the developers decide to switch to the very all 2.3 version.
This just show how wrong was the decision of releasing Ext 4.0 just to be on schedule, with the framework completely unstable.

I hope you Sencha guys learn from this mistake.

mmullany
17 Nov 2011, 1:25 PM
Hi all. Rich sent me a PM asking for an additional summary vs. what I posted near the top of this thread, so this is what I sent him, and thought I should repost the essentials:

<Quote>

I hope I did a good job outlining the complete situation in the original blog post: http://www.sencha.com/blog/ext-js-4-1-update/ and my follow-up forum posts and comments. But to summarize again, if 4.x performance is not meeting your needs then for the short term you should stay on the 3.4x line. We're looking at extending 3.x support for at least 6 months beyond the 5.x ship based on this recommendation, since more people will be staying on 3.x for longer.


Our goal is to get the 4.x line to be faster than 3.4 at the very least for the common app cases. From looking at what people are posting on this thread and our internal testing, it looks like the consensus is that the current 4.1 preview is roughly 2x faster than 4.0 but also still about 2x slower than 3.4. We are working as aggressively as possible and will continue to release performance improvements in 4.1.x and 4.2 releases until we achieve our performance goals. Hence our recommendation. As an aside, we've integrated continuous performance benchmarking in our testing process as a result of our 4.0 performance experience.


Our initial comments that 4.x would be faster than 3.x was based on early benchmarks of our refactored layout and rendering pipeline - which we showed at SenchaCON 2010. Subsequent to SenchaCON 201, we integrated the new class system, added fairly involved theming code and also did a grid rewrite to support the new 4.x features. The combination of these, particularly for more complex layouts, reduced performance substantially from our early benchmarks, as all of our, and your, test benchmarks have shown.

I hope this summary helps those of you who are trying to make decisions about which version of Ext JS to use.

MrSparks
18 Nov 2011, 3:43 AM
@mmullany



I hope I did a good job outlining the complete situation in the original blog post: http://www.sencha.com/blog/ext-js-4-1-update/ and my follow-up forum posts and comments. But to summarize again, if 4.x performance is not meeting your needs then for the short term you should stay on the 3.4x line. We're looking at extending 3.x support for at least 6 months beyond the 5.x ship based on this recommendation, since more people will be staying on 3.x for longer.

To be fare a lot of us signed up to 4.x because 3.4 wasn’t quick enough. So really the statement should be "if performance is not meeting our needs”, "2.3 would be the best line to either stay on or adopt".




Our initial comments that 4.x would be faster than 3.x was based on early benchmarks of our refactored layout and rendering pipeline - which we showed at SenchaCON 2010. Subsequent to SenchaCON 201, we integrated the new class system, added fairly involved theming code and also did a grid rewrite to support the new 4.x features. The combination of these, particularly for more complex layouts, reduced performance substantially from our early benchmarks, as all of our, and your, test benchmarks have shown.

With regards to theming and it being a performance blocker. If it cannot be improved, simply remove it from 4.x and utilise the existing theming model. There was nothing fundamentally wrong with the existing one. There’s no point in bulking out the framework with “concepts” that sacrifice performance just for the sake of having them.


I’ll reserve my final judgment/decision until PR2 is released. However can I ask Sencha to start to consider reinstating support for the 2.x line. From comments made on this thread it sounds like there is a lot of room in the 2.x line to improve its performance even further still. Sencha should consider a 2.4 release which has these optimisation out of the box. I know this would be a hard pill for Sencha to swallow but as a gesture of good faith and with a view to stopping developers seeking out solutions with your competitors. (not to mention the plethora of refund requests you would get!) I think its something that should be seriously considered.


Best
MrSparks

tvanzoelen
18 Nov 2011, 4:43 AM
I don't understand why people are kicking on performance while ExtJs 4 is still unstable.

All the bug fixes on layout, recalculation sizes and still collapsing panels et cetera are making my application slow. But unfortunately these doLayouts and all these layout patches are necessary. I hoped after 3.4 that the layout problems would be over.

Second point. ExtJs 2, 3 have brought it so far that is was possible to build big web applications. You can not say that ExtJs 4 is faster in certain conditions if you not meet the level of stability of Ext 2 or 3. That would be a comparison between an apple and a pear.

nomack84
18 Nov 2011, 5:17 AM
What I don't understand is what Sencha is waiting to release a PR2. Why wait so much time?
If improvements are made, then release a PR2, to calm down all developers, showing all the advances.

terrycursh
18 Nov 2011, 5:23 AM
What I don't understand is what Sencha is waiting to release a PR2. Why wait so much time?
If improvements are made, then release a PR2, to calm down all developers, showing all the advances.
Agreeed with my heart!

danattfield
18 Nov 2011, 8:44 AM
I hope this summary helps those of you who are trying to make decisions about which version of Ext JS to use.

This summary would have been really useful 6 months ago. Had we known this before upgrading, I don't think we would have done.

What I find particularly disappointing is that Sencha have been running training courses (one of which I attended in May 2011) specifically targeting 'Upgrading to Ext JS 4', which although highlighted some bugs, mentioned nothing of this performance hit, or the colossal effort which the upgrade would require for a very large application such as ours. Don't get me wrong - we knew we'd have a lot of work to do when we chose to upgrade. But call me naive; when a company is running and taking payment for training courses for a product, is it wrong to expect that product to be almost, if not fully stable?

This is not to say that the course itself was not enlightening on the whole, and for the most part led us to decide that we wanted the additional functionality the Ext JS 4 would offer, and that we wanted it sooner rather than later. There are some great features and on the whole we really like it. It's just a shame we didn't know how many months we'd need to commit to upgrading, fixing the horrific lack of backwards compatibility (even with the 'compatibility' scripts), or that when we'd finished our application would be even slower than with 3.4.

Was Ext JS 4 ready for adoption back in June when we started upgrading? Definitely not. Did we make the decision to adopt it too early? Probably. Would we now like to see greater transparency, increased communication and some indication from Sencha that our concerns are being prioritised and addressed accordingly? Absolutely.

</rant>

tjstuart
18 Nov 2011, 12:55 PM
Sorry for offtop, but where to find these tweaks?

I'll post them when back at work next week. In the meantime, search the forum for _getCacheIndex as I believe there was some discussion regarding this some time ago.

amlody
29 Nov 2011, 4:08 AM
How about adding changes which improve performance to 3.4 version which is most commonly used until we get stable and fast 4.x?

Do you know any tweaks for 3.x?

petercdobbs
1 Dec 2011, 7:57 PM
This is not where I had hoped Sencha was going when I first considered it.

What's sad is, v4 runs pretty good on newer browsers (damn government users!). Thank goodness we don't have to support Netscape.

I really don't want to consider going back to Telerik. The promise of a usable extjs solution is too appetizing. :-|

Hoopoe
2 Dec 2011, 4:28 AM
This is not where I had hoped Sencha was going when I first considered it.

What's sad is, v4 runs pretty good on newer browsers (damn government users!). Thank goodness we don't have to support Netscape.

I really don't want to consider going back to Telerik. The promise of a usable extjs solution is too appetizing. :-|

May I ask you, what’s wrong with Telerik? We were considering Telerik + JQuery (just because we found ExtJS 4 unusable in its current state). Might mean a lot of work for us, but looks like it may be better then depend on ExtJS.

_matias_
2 Dec 2011, 6:54 AM
The following is not meant to argue with anyone as there are many use cases and what is true for one doesn't have to be for one's neighbour.

I am the first to about Ext's release strategy and lack of clarity regarding release dates. This being said, I love the way Ext is going and how it allows to write eminently re-usable and maintainable code, something that, in my use case, far outweighs having to wait. That is, provided a functional release ever sees the light in the next few months.

nomack84
2 Dec 2011, 7:53 AM
It's true @_matias_.
I'm unhappy with Ext ATM because they release a version with many problems: performance, bugs, etc. tut at the same time, I'm not using Ext 3.4 for my projects.
It's true that ATM I'm not supporting IE, is possible to me to restrict my users, temporally, to FF and Chrome, but, Ext 4 has so many nice features, that I can't switch back to a previous version...

What is sad is they late to many time from release to release. I don't understand why they release Ext4.1-PR1 full of bugs, but is not possible to release a PR2, which certainly will have less bugs. I know they like to jump straight to Beta, but...is a long wait, and people get mad during the process.

stever
11 Dec 2011, 12:54 PM
I don't understand why they release Ext4.1-PR1 full of bugs, but is not possible to release a PR2, which certainly will have less bugs.

I don't know about that. Different bugs, sure. But certainly not "certainly will have less bugs". Big software projects rarely work that way.

brianpolk
13 Dec 2011, 4:59 AM
Still checking just about every day to see if a pr2 or beta is available, or if maybe just a new message has been tossed over the wall. I am a veteran software developer and an enthusiastic user of the extjs framework. Like many others, my organization has staked a lot on extjs4. We've done a lot of development, and porting of existing projects, but they have now been on hold for way too long. When asked for progress estimates, the stakeholders expect something more than crickets. Please help me to defend the decision to take this road. A pr2 would take a lot of pressure off at this point. We know you are all working very hard on this, and are dedicated to a quality deliverable. Please keep us better informed of what to expect over the coming week(s), month(s) or if it might be longer than that, we just need to know.

nomack84
13 Dec 2011, 9:07 AM
There won't be a pr2, they'll switch to beta1 directly, and it should be ready before the end of this year, so be patient....

nbourdeau
10 Apr 2012, 9:47 AM
Any update on performance issues with Ext4 ??
Espescially with IE ?

Grolubao
10 Apr 2012, 11:28 AM
The unfortunate truth is that Sencha is aiming their efforts in Sencha Touch and not ExtJS. All the tweetings, etc, is towards Sencha Touch.

It's incomprehensible that it takes so many months to iron out the bugs. It's also not possible that these performance problems couldn't be measured before releasing ExtJS 4.

There is something very wrong going on, and I'm really afraid that the latest stable version from Ext would be 3.4

mmullany
11 Apr 2012, 3:03 PM
We have had a full team working on Ext JS since we shipped Ext JS 4. We *just launched* Sencha Touch 2, so our marketing efforts have been concentrated on getting it into market. We've blogged along our way about Ext JS 4.1 and had a number of newsletter articles on what's going on. Ext JS 4.1 has a full rewrite of the layout system for improved performance - which is a core component that the entire framework has massive and subtle dependencies on. We're almost there.

nbourdeau
10 May 2012, 5:38 AM
While my profiling did show a lot of GC, I don't know when that occurs. It could easily have been once rendering is finished and there's nothing else going on. That's my understanding of how GC is supposed to work...

I don't think the bulk rendering accounts for all the extra stuff in the heap dump. I added the following code to MrSparks's example:


var Tracker = function() {
Tracker.count++;
};

Tracker.count = 0;

(function() {
var join = Array.prototype.join;

Array.prototype.join = function() {
if (!this.tracker) {
this.tracker = new Tracker();
}

return join.apply(this, arguments);
};
})();

I also added similar code into XTemplate.applyOut.

What this does is tag each array used for a join operation with a Tracker class. I can then see those trackers in the heap dump and trace their GC roots.

Thousands of arrays were augmented (it keeps count) but only about 12 trackers made it through to the heap dump. I think all were caught in closures rather than deliberately kept and whilst this does indicate a memory leak it was only 12 relatively small arrays. The biggest culprit was the cache in Ext.DomQuery.select, which captures the array fn in the line:


eval(fn.join(""));

I then turned my attention to the strings. Some of the largest strings were HTML fragments, so I thought I might be on to something there. Turned out they were html properties on XTemplates. I made a small tweak to XTemplate so that it wiped the html property after it was compiled. While this did make those strings disappear from my heap dump it really made very little difference in the grand scheme of things.

One other observation I made is that grids keep recreating the same XTemplate over and over again. The compile times add up. It probably isn't significant compared to some of the other optimizations you're making but I managed to save myself about 5% on grid resize times by adding in a crude cache.

Hi skirtle!

Could you post these tweaks for us to test it ? Or is it already in 4.1 GA ?

Regards

nbourdeau
10 May 2012, 10:47 AM
I've heard a lot of people say this but personally I've never found this to be true. While I understand that there's only so much you can do to overcome a fundamental architectural performance problem, I tend to find that I can squeeze a load more performance out of my apps just by targeting my own use case.

As you noted, out-of-the-box components need to support older browsers and all sorts of wildly varying configurations. In practice, your app may well only need to support a subset of browsers and the configuration of each component is known exactly. This gives you a major advantage in applying optimizations that might be much more difficult to attempt in the more general case.

Just like any other application, once in a while you have to break out a profiler and do some work to speed things up. This includes monkey-patching Ext the same way you would for any other bug.



Many developers aren't suffering performance problems and you can no doubt imagine their response to losing the features they were using.

While the performance of ExtJS 4 is currently slower than ExtJS 3 in all browsers, I think most of the headaches surround older browsers. While it may not be universally the case, I suspect most developers would be able to tolerate the current performance were they not trying to support older versions of IE. Trying to improve performance by ignoring older browsers doesn't really address the majority need.

Skirtle, I blog post or new forum thread about how to tweak ExtJs the way you talk for fitting our needs would be great. I do not really know where to start and/or possible spots where I could strip things to optimize a bit !
For example, If I don't want ot support IE6, is there some compatibility I can remove somewhere that will speed up things ?

MrSparks
11 May 2012, 1:14 PM
@Skirtle & @nbourdeau

I would also be very interested in the performance tweaks your mentioned and if it possible to strip out parts of the framework that would not be required on my target platforms. i.e. remove I.E. 6 (that's a dead browser these days to be honest, MS don't release security patches any more so most corporates have moved on) also how to remove SASS, MVC and a few other items that would't be needed in a performance (targeted) framework environment.

Really don't want to have to go the EXT 2.x route, just to get performance :(

Best
MrSparks

skirtle
12 May 2012, 3:19 PM
To start with have a read of the following:

http://www.sencha.com/forum/showthread.php?153565
http://www.sencha.com/forum/showthread.php?201608
http://www.sencha.com/blog/optimizing-ext-js-4-1-based-applications/

Generally I just start by using a profiler or adding some timing logging and narrowing down the cause of the problems from there. Since 4.1 came out I haven't needed to do any library tweaking, just writing application code to follow best practices has proved sufficient to get fast performance. 4.1 is still a bit slower than 3.4 but we're talking such small differences that users can't really feel it. Absolute performance is what matters, not comparisons to 3.4. Those kinds of comparisons just help to set expectations on what the ExtJS dev team should be aiming for.

@MrSparks. I'd be curious to know what sort of performance problems you're still seeing against 4.1. The example you provided comparing 3.4 and 4.0 many months ago was very useful for performance analysis but it didn't really give any hints about what sort of problems you're having in practice. Creating and rendering so many components up front the way that example did is great for finding library performance bottlenecks but in a real app you'd just do everything lazily and the load time would plummet.

If you want to strip down the JS section of the library then follow the guide to creating a custom build. You just need to create a jsb3 and then build it. You won't be able to remove dynamic loading but things like charting, MVC and Ext Direct should drop out, unless you're using them. Stripping back the CSS can also help a little. The default HTML styling at the end of the CSS is totally unnecessary unless you're using styleHtmlContent and the rules it uses are really slow. It'll only make a couple of percentage points of difference at best but if you're looking to squeeze out every morsel it's certainly something I'd do.

I've helped quite a few people upgrade from 4.0.7 to 4.1.0. In all cases we finished the upgrade in a few hours (backwards-compatibility is pretty good in my experience) and the remaining performance problems were all tracked down to inefficient application code. There are still some problem areas in the library, such as grids with many columns, but unless you're unfortunate enough to fall into one of those nightmare scenarios you should find performance is pretty reasonable.

rich02818
14 May 2012, 5:08 AM
@skirtle: The performance requirement is to be at least as fast as 3.4 in real application use. Your statement that "the remaining performance problems were all tracked down to inefficient application code" is effectively a new, subjective performance requirement that is based only upon comparisons to 4.0.x performance.


Is Sencha still committed to correcting the performance deficiencies of ExtJS 4.x and making it at least as fast as 3.4? When can we expect to see this achieved?

rich02818
14 May 2012, 6:44 AM
EXTJSIV-3283 was opened about 11 months ago, documenting 4.x performance problems with multiple tab panels. What is the current status of this bug?


http://www.sencha.com/forum/showthread.php?136886-Very-slow-Tab-Panel-performance-vs-3.4

skirtle
14 May 2012, 6:54 AM
@skirtle: The performance requirement is to be at least as fast as 3.4 in real application use. Your statement that "the remaining performance problems were all tracked down to inefficient application code" is effectively a new, subjective performance requirement that is based only upon comparisons to 4.0.x performance.

I think you've misunderstood me. My statement isn't a performance requirement, it's an observation. I'm not comparing to 4.0.x, I'm asking the users whether they think the apps are fast enough. Sure, it's subjective, but it's also the only metric that really matters to me.

Sencha's requirement: make ExtJS 4 as fast as ExtJS 3.4.

My requirement: make my customers' apps fast enough for their needs.

I would hope for the sake of your users that your own requirement is similar to mine.


Is Sencha still committed to correcting the performance deficiencies of ExtJS 4.x and making it at least as fast as 3.4? When can we expect to see this achieved?

From what folks at Sencha have said on forum posts and blog entries it would seem that performance is still the top priority for 4.2.