5 ExtJS6 Internal Caches

I’ve recently been involved in some memory leak troubleshooting and wanted to note the following caches, which often end up being the culprits retainers of some objects that were not cleaned up (e.g. destroy()) correctly, for one reason or another:

Ext.ComponentManager.all   // Ext.Component cache as map
Ext.cache                  // Ext.Element cache as map
Ext.StoreManager.items     // Ext.data.Store cache as array
Ext.fx.Manager.targets.map // Ext.fx.target.Element cache as map
Ext.dd.DragDropManager.ids // DD Object cache as map - also "leaks" by design;
                           // it retains empty objects mapped out to IDs that
                           // used to be legit components, so minimal memory
                           // impact, but those IDs are never wiped

I also would like to share the following functions that I use to compare snapshots of these caches:

// e.g.
// * var s1 = getCacheSnapshot()
// * ... interact with the app
// * var s2 = getCacheSnapshot()
// * compareCacheSnapshots(s1, s2);
function getCacheSnapshot() {
    return {
        cmp: Ext.Object.getKeys(Ext.ComponentManager.all),
        el: Ext.Object.getKeys(Ext.cache),
        st: Ext.Array.pluck(Ext.StoreManager.items, 'storeId'),
        fx: Ext.Object.getKeys(Ext.fx.Manager.targets.map),
        dd: Ext.Object.getKeys(Ext.dd.DragDropManager.ids)
    };
}
 
// logs any deltas
function compareCacheSnapshots(s1, s2) {
    function diffArrays(name, a1, a2) {
        var added = Ext.Array.difference(a2, a1);
        var removed = Ext.Array.difference(a1, a2);
        if (added.length || removed.length) {
            console.log(' ---- ', name, 'Added:', added, 'Removed:', removed);
        }
    }
    for (var key in s1) {
        var a1 = s1[key];
        var a2 = s2[key];
        console.log(key, a1.length === a2.length ? a1.length : a1.length + '->' + a2.length);
        diffArrays(key, a1, a2);
    }
}
VN:F [1.9.22_1171]
Rating: 5.1/10 (18 votes cast)

Implicit ViewModel 2-Way Data Bindings

I’ve come across a rather interesting… let’s call it “feature” of ExtJS ViewModel and data binding system. Turns out it is possible to establish “implicit” two-way data binds between parent & child view model data (within same component hierarchy) by setting the data of “lower” view model to “undefined”, so long as the view models both define that data property with the same name. Picture the following simple hierarchy:

  • Parent Panel

    • Child Panel

Now imagine that both of the panels define their own ViewModels (implicit or not doesn’t matter) that both define the same two properties, like so:

  • Parent Panel

    • undefinedText: “default Parent text”
    • definedText: “default Parent text”
  • Child Panel

    • undefinedText: undefined
    • definedText: “default Child text”

This is what the default rendering of these panels would look like:
Screen

Read on for a walk through of various scenarios and a Sencha Fiddle…
Continue reading Implicit ViewModel 2-Way Data Bindings

VN:F [1.9.22_1171]
Rating: 6.0/10 (21 votes cast)

Declarative Listeners vs. Control

Back in ExtJS 5 Sencha rolled out a rather cool concept of declarative listeners, where you could write something like this:

{
    xtype: 'button',
    handler: 'onButtonClick'
}

…note that onButtonClick is a string, rather than a function reference. The idea here is that the actual function would be resolved at runtime and will be located somewhere in the ViewController world. It was described well by Don Griffin in his blog post: https://www.sencha.com/blog/using-viewcontrollers-in-ext-js-5/.

However, what was omitted in this blog post and the guides, is the potentially powerful and risky “up the component tree” resolution of the ViewController. Read on to learn more with a Sencha Fiddle example…

Continue reading Declarative Listeners vs. Control

VN:F [1.9.22_1171]
Rating: 5.4/10 (24 votes cast)

Hybrid Apps: Staged Rollouts

I love native apps, but for large enterprise projects they’ve been making less and less sense as mobile devices have become more powerful and the modern browser capabilities have exploded in the recent years.

One particularly important aspect of mission- critical mobile app is the risk involved with rolling out each new version. Imagine waiting out the 10 day approval period from Apple only to discover that you had a royal screw up and now the production version is unusable. Now you need a day or two to fix the issue, then another 10 days for approval, all while your app is unusable? A single occurrence can be enough to destroy your business.

Consider the advantages that a hybrid app can offer you in this case, illustrated in the following fictitious scenario, based on real life implementations I’ve been involved with:

  • The hybrid app stack is based on PhoneGap and Sencha ExtJS6
  • Has not needed an app store redeploy in years because the native code has no need to change
  • The app downloads its JavaScript code dynamically
  • Depending on the organizational unit that the user belongs to, or whatever organization they are choosing to operate in during their session, a different version of the JavaScript code is downloaded
  • A seamless transition between different versions of code occurs as the user navigates between different organizational units

This approach allows you to perform staged rollouts of new production code, or to perform AB testing on potential code candidates, within isolated organizational units, without risking mass disaster, with no regards for the app store or the 10 day waiting period. Try doing that with a native app.

Now some of you might be thinking “but it’s against some policies to remote download code” and I say “welcome to the big league, boys”. When we are talking about multi billion dollar enterprises, it costs peanuts to “persuade” Apple to “overlook” these policies and countless businesses operate based on this model.

VN:F [1.9.22_1171]
Rating: 9.4/10 (5 votes cast)

ExtJS 6: Responsive HBox vs. VBox

A basic ExtJS6 Classic Toolkit responsive technique for going from vertical to horizontal based on tall/wide screen, is by using responsiveConfig on a Viewport running Border layout, and change desired child’s regions from i.e. South to West. However, what if you want to do the same, but using an HBox vs. VBox layout, to get that additional flex functionality? Turns out it’s not as straightforward, however still pretty simple. You just need to use Box layout (ancestor of HBox and VBox) with “vertical” boolean config changing inside the responsiveConfig of the viewport. Here is the sample source code from Sencha Fiddle; click the link below to experiment with it in different window sizes:

https://fiddle.sencha.com/fiddle/sls/preview



VN:F [1.9.22_1171]
Rating: 6.9/10 (7 votes cast)