Skip to Content

Large web applications usually consist of multiple files. Every single resource has to be fetched from the server which comes with overhead and latency.

During development this is usually not a problem. It also allows only reloading files that have been changed instead of bundling all files after only one line was changed.

However when running an app in production the performance is important for a great user experience. A bundling process does also not create too much overhead as it won’t be done every minute.

There are some simple techniques to boost the loading performance of OpenUI5 applications which do not even require you to touch app code.

All this does of course also apply for SAPUI5 and can be used by SAP customers and partners to optimize apps locally and e.g. upload them to a SAP NetWeaver system.

What can be done?

Reducing HTTP requests

Reducing the number of requests to the server is often the most effective way to boost performance.

OpenUI5 has already a built-in concept called preload. Usually when a module gets required and wasn’t loaded before, a XHR will be sent to load that specific file. The preload allows loading multiple modules bundled into a single file. This can currently be done on library or component level.

If a module gets required after the bundled preload file was loaded, it can be executed directly, because the module content is already available. This can speed up the initial loading process especially if there is a high latency (mobile network / long distance to server).

Reducing payload

The payload size can be reduced by removing white-space and line-breaks or even rename variables or remove/rewrite code. This can reduce the file size a lot which not only speeds up loading those files but also reduces the amount of traffic for you and your users (bandwidth can be very limited in mobile scenarios).

Example

Let’s assume our app’s component has the following files/folders:

  • controller
    • BaseController.js
    • Detail.controller.js
    • LineItem.controller.js
    • ListSelector.js
    • Master.controller.js
  • model
    • AppModel.js
    • Device.js
    • formatter.js
    • grouper.js
  • view
    • App.view.xml
    • Detail.view.xml
    • LineItem.view.xml
    • Master.view.xml
    • NotFound.view.xml
    • ViewSettingsDialog.fragment.xml
  • Component.js

In total

  • 10 Javascript files
  • 6 XML files

If we would just load the component, all files are loaded and this would end up into 16 requests, just for our component.

(As you can see, a “Component-preload.js” file will be loaded first, but currently it’s not there and OpenUI5 will fall back to the “Component.js” file)

/wp-content/uploads/2015/02/before_646932.png

What if we could load all the files in 1 request and also reduce the overall file size?

Note: This does only include JavaScript files and views. Locale specific files (i18n) or custom CSS would create additional requests.

You can use the grunt-openui5 plugin for this. Grunt is a task-runner based on node.js. See here for more information and help about grunt in general.

openui5_preload task

This task can be configured to bundle and minimize all relevant files of your component.

For our example app, it could look like this:


grunt.initConfig({
    openui5_preload: {
        component: {
            options: {
                resources: {
                    cwd: 'webapp', // path to app root folder
                    src: [ // include/exclude patterns for files
                        '**/*.js', // in this example, we do only have js/xml files
                        '**/*.xml' // but this can be used to e.g. exclude language-specific files
                    ],
                    prefix: 'my/app' // namespace prefix (in case the namespace is not already in folder structure like sap/ui/core/**)
                },
                dest: 'dist' // destination for the Component-preload.js file
            },
            components: 'my/app' // specify which component(s) should be processed
        }
    }
});

When we now load the component, you can see that only the Component-preload.js will be loaded which contains all the modules of our app.

(All other files in the screenshot are part of OpenUI5 itself, not the app)

/wp-content/uploads/2015/02/after_646933.png

Further information

A detailed documentation of the grunt task can be found on GitHub:

SAP/grunt-openui5 · GitHub

There is also a very small sample app project that demonstrates the usage of bower & grunt with OpenUI5:

SAP/openui5-sample-app · GitHub



Best regards,

Matthias


Twitter: @matthiaso

GitHub: matz3

To report this post you need to login first.

20 Comments

You must be Logged on to comment or reply to a post.

  1. Matt Harding

    Hi Matthias,

    Thanks for writing about a crucial grunt task for UI5 development that has only recently become available outside of SAP. While I don’t use grunt for development per se, grunt has been fantastic at a couple of sites for deployment and I thought I would highlight a couple of extra features to leverage alongside this one that make life easier for a UI5 developer targeting SAP deployments (more for your readers as I’m sure you are aware of most of this).

    First, wouldn’t it be great if you didn’t have to ask users to refresh their cache after every deployment…

    e.g. Inserting data-sap-ui-appCacheBuster=”./” into the sap-ui-core.js section does wonders for stand-alone apps deployed to SAP servers (though haven’t tested whether Fiori integrated apps are smart enough to use app-cache-buster but assume they are).  e.g. SAP automatically creates a file during ui5 upload that is used to reference the latest version ensuring cache is not persisted.

    Secondly, if you’re a team working with Git, wouldn’t it be great if you could just run one command and get the latest copy…And this is where grunt-git and gitclone comes into action by downloading the latest master branch automatically for you.

    Of course, you need to do a bit of cleaning up and the like to make a final distribution, but that’s just other grunt tasks.

    So all this said, hopefully this all gets bundled up into WebIDE so the less savvy get these features consistently in the future and benefit from a repeatable deployment with the ability to add new grunt tasks in the future (like image collation like the old Google Web Toolkit used to do).

    Cheers,

    Matt

    Edit: Ouch – Just tested it and it looks like the Fiori Launchpad doesn’t support sap app cache buster by default and you need to implement note 2075016 which isn’t the same thing and looks kind of dodgy!


    Edit #2: Looks like SP11 introduces the app-cache-buster (note 2043432) so recommend not integrating UI5 apps into the FLP for now if you want performance but no risk of people running old UI5 code.

    (0) 
    1. Matthias Osswald Post author

      Hi Matt,

      thanks for your comment!

      Yes, the appCacheBuster is doing well once the files are already cached.

      So both optimizations are even better to also perform well on mobile, where the initial loading is the biggest problem.

      In future, the WebIDE should become the main point for such things to allow users to do such optimizations with just one click. But until we get there, I think using grunt is also a good way to optimize and shouldn’t be too complicated to setup.

      Best regards,

      Matthias

      (0) 
  2. Beck Tan

    this only works for files that are residing in the application right? it does not works with making the sapui5 libraries does it?

    (0) 
    1. Matthias Osswald Post author

      The “openui5_preload” task offers also the possibility to create an “library-preload.json” for a library. But those files are already part of the SAPUI5 libraries.

      I guess you want to bundle the component and SAPUI5 libraries in one file, right?

      “Component-preload” files are usually meant to bundle all component related files but not SAPUI5 libraries.

      You could also bundle the libraries into the Component-preload if you extend the file pattern in the grund config to also include the library files. However, that’s usually not recommended as you have to re-build this bundle whenever the SAPUI5 libraries get updated. Another disadvantage is that when loading multiple apps which bundle their own SAPUI5 libraries, the browser needs to load and cache them multiple times.

      (0) 
      1. Beck Tan

        I was trying to figure out how to use grunt-openui5. I got the Gruntfile.js and package.json in the root of my maven project package. Do I need to include anything within the pom.xml so that when when I build the maven project it will run the grunt file?

        When I was viewing my network, I realised that it will loads all the application js (which are written by us), is the purpose of this Component.js to combine everything into just 1 single call?

        My project structure is as of below

        project package

        – src/main/resources

        — META-INF

        — resources

        —- js (application js in here)

        – Gruntfile.js

        – package.json

        – pom.xml

        Would be good you be able to advise, because I have got grunt installed and stuff, includes the grunt.npmLoadTask() but won’t works

        (0) 
        1. Matthias Osswald Post author

          There are a few ways to run node scripts (like grunt) from maven. Just search for “maven node plugin”.

          Yes, the purpose of the “Component-preload.js” is that it combines the app files to reduce HTTP requests.

          You have to install node.js (which includes npm), grunt-cli and run “npm install” to fetch the dependencies. After that you can e.g. run “grunt openui5_preload” to run the preload task.

          (0) 
          1. Vivekananda Panigrahy

            Hi Matthias

            The article is very useful. We also implemented this preload task for our project. Ours is a XS application hosted on HCP. We don’t follow maven build infrastructure. Currently, I copy  all my files to a source directory in my local system and run the job which creates a component-preload.js for my application, then i copy this content back to my application on HCP layer.

            Is there a better way where I can automate this job on HANA layer itself.

            Best Regards

            Vivek

            (0) 
  3. Beck Tan

    hi, i finally managed to generate the library-preload.json, how do I get my app to load using that instead of all the custom utilities that I have created?

    (0) 
    1. Matthias Osswald Post author

      Hi Wei,

      if you are loading your library and the library-preload.json is located next to your library.js file, then UI5 should automatically load and use the preload file instead of requesting all single files.

      Could you give some more information about your setup and what you are trying to do in detail?

      Thanks,

      Matthias

      (0) 
      1. Beck Tan

        Hi Matthias,

        The structure is as of such:

        src/main/resources

        — META-INF

        —- resources

        —— com

        ——– application

        ———- controls (all our custom SAPUI5 controls are in here)

        ———- util (all our custom utility files are in here)

        ———— library.js

        ———— library-preload.json

        —— index.html

        —— login.html

        what happens is when our index.html loads, it calls an appUtil.js in util folder which within the files we use sapUI5 requires that takes all the files within controls and util.

        now I have the library.js and library-preload.json generated using grunt-openUI5. But I am not too sure how or where should I load the library.js.

        another thing is that I realised my library.js is empty, is that correct? And there is no way to specify which files to exclude in the src that I have specify when I am running grunt-openUI5.

        (0) 
  4. Udo Eirich

    Is it possible to include also static *.json or properties (e.g. message bundles) files to *-preload.json?? Currently we have the problem that files not included in that preload file are not cached on client side. They are alway requested for validation and return with status code 304.

    (0) 
      1. Dheeram Kallem

        Hi Matthias,

        I include *.properties and *.json models into preload file, but still these files are getting called or loaded separately.

        Thanks,

        Dheeram

        (0) 
  5. Ravikant Kumar

    Hi Gents,

    Upon reading through the entire discussion on component-preload.js for improving the performance. i was wondering if i can also implement it for my recently developed Fiori Extension Projects.

    My Doubts are:

    1. Since Std Fiori does have Component-preload.js file in app directory, is it best practise to create Component-preload.js file for Extension Project also?

    2. If answer to first question is yes, importing the extension project in File system and setting up grunt to generate the Component-preload.js and copy it back to the original project directory would be the approach right?

    please address these points, I’m really looking forward to improve the performance 🙂

    Thanks in Advance!

    please let me know for any further clarifications.

    Thanks & Regards

    Ravikant

    (0) 
    1. Michael Appleby

      Unless you are asking for clarification/correction of some part of the Document, please create a new Discussion marked as a Question.  The Comments section of a Blog (or Document) is not the right vehicle for asking questions as the results are not easily searchable.  Once your issue is solved, a Discussion with the solution (and marked with Correct Answer) makes the results visible to others experiencing a similar problem.  If a blog or document is related, put in a link.  Read the Getting Started documents (link at the top right) including the Rules of Engagement. 

      NOTE: Getting the link is easy enough for both the author and Blog.  Simply MouseOver the item, Right Click, and select Copy Shortcut.  Paste it into your Discussion.  You can also click on the url after pasting.  Click on the A to expand the options and select T (on the right) to Auto-Title the url.

      Thanks, Mike (Moderator)

      SAP Technology RIG

      (0) 
  6. Enrique Rodriguez Lasterra

    Maybe too late to write here, but…

    I’m starting to develop ui5.. i have experience with othe JS/Web frameworks, and ui5 is impressive… but for me there are various things that are difficult to understand for me.

    One of this things is how to package and optimize applications. Component-preload is documented, but … what about ui5 libraries? openui5-runtime.zip is 22MB¡

    What i’m doing is genereting library-preload.json using gulp openui5_preload task for every ui5 bower component i use.

    With ui5 themes, is very similar, each theme has a lot of stuff, but finally i only need library.css file and images.

    Why there is not an official guide to package applications?

    (0) 
    1. Michael Appleby

      Unless you are asking for clarification/correction of some part of the Document, please create a new Discussion marked as a Question.  The Comments section of a Blog (or Document) is not the right vehicle for asking questions as the results are not easily searchable.  Once your issue is solved, a Discussion with the solution (and marked with Correct Answer) makes the results visible to others experiencing a similar problem.  If a blog or document is related, put in a link.  Read the Getting Started documents (link at the top right) including the Rules of Engagement.

      NOTE: Getting the link is easy enough for both the author and Blog.  Simply MouseOver the item, Right Click, and select Copy Shortcut.  Paste it into your Discussion.  You can also click on the url after pasting.  Click on the A to expand the options and select T (on the right) to Auto-Title the url.

      Thanks, Mike (Moderator)

      SAP Technology RIG

      (0) 

Leave a Reply