Welcome!

Welcome to the official BlackBerry Support Community Forums.

This is your resource to discuss support topics with your peers, and learn from each other.

inside custom component

Native Development Knowledge Base

Improving startup performance of Cascades apps

by Retired on ‎05-13-2013 02:56 PM (7,009 Views)

Many Cascades™ apps use a Web Service of some sort to query data from (e.g. Facebook®, Twitter®, LinkedIn® etc.). If that Web Service is needed to display data when the app starts up, it is strongly recommended to make that request as early as possible. A typical mistake is to first setup the UI, which will take a considerable amount of time (typically around half a second), and then do the network request afterwards or in between. A typical scenario might look like this:

 

cascades-app-typical.png

 

In the diagram above, all the network related tasks are part of getting the latest updates from the network (e.g. retrieving updates from Facebook or Twitter). Since making a network request does not affect loading local QML files from disk, those tasks can run in parallel with minimal interference:

 

cascades-app-ideal.png

 

So in other words, the typical suboptimal way of initializing an app is (assuming that the network request will take more time than loading the QML files):

  1. load QML files
  2. make the network request(s)
  3. start the event loop

The optimal way however is:

  1. start the event loop
  2. make the network request(s)
  3. load QML files

To express this in code, here is stub code for the suboptimal way:

 

// header file:
class MyClass : public QObject {
    public:
    MyClass();
    ...
}
 
// in cpp files:
int main(int argc, char **argv)
{
    Application app(argc, argv);
    MyClass c;
    return Application::exec();
}
 
MyClass::MyClass() : QObject()
{
    QmlDocument *qml = QmlDocument::create(...); // time-consuming loading of local QML files
    QNetworkReply *reply = networkAccessManager.get(...); // load data from the network afterwards
    // note that the event loop will not be running before this method exits
}

 

To transform this into the optimal way, the question is: How can an app start the event loop first and then do all the work? Answer: create an invokable init() method that is called through the event loop.

 

So the optimal way to start up an application looks like this:

 

// header file: add invokable init() method:
class MyClass : public QObject {
    public:
    MyClass();
    ...
    private:
    Q_INVOKABLE void init();
}
 
// in cpp files:
 
int main(int argc, char **argv)
{
    Application app(argc, argv);
    MyClass c;
    return Application::exec();
}
 
MyClass::MyClass() : QObject()
{
    QMetaObject::invokeMethod(this, "init", Qt::QueuedConnection);
    // do nothing else than invoking init(), which will do all the heavy work once the event loop has started
}
 
MyClass::init()
{    // note that the event loop is already running at this point
    QNetworkReply *reply = networkAccessManager.get(...); // load data from the network beforehand (method returns immediately and will not block QML file loading)
    QmlDocument *qml = QmlDocument::create(...); // time-consuming loading of local QML files
}

 This small refactoring can save hundreds of millseconds at app startup time.

Contributors
Users Online
Currently online: 32 members 1,899 guests
Please welcome our newest community members: