Performance Improvement with Component-preload.js
Performance is always very important. By using a Component-preload.js file in your custom developed Fiori App (“Build your own Fiori App in the cloud”) startup and runtime performance can be improved.
Probably you saw already “negatively” the Component-preload.js file as failed http request in your custom developed Fiori App or if you used one of the Project Templates of the SAP Web IDE. Or perhaps you recognized it in the source of an installed standard SAP Fiori App, which you have downloaded from SAPUI5 ABAP Repository via the SAP Web IDE. The standard SAP Fiori Apps have this file included by default. To make it short this file basically contains all the JavaScript (controller, views, utilities) and XML view files of the application within one single files. So instead of multiple http request for each of the app resources, only one request is necessary. This could be a huge performance improvement if you have for example bad latency times.
See the number of request in the below screenshot the difference without (left) and with the usage of Component-preload.js (on the right):
Generate Component-preload with Gulp
Currently SAP Products lack off a ready-running build process to generate such a file. Also SAP Web IDE does not support the generation of this file (at least in the current version). I’m very curious how and when SAP will close this gap and include a build process within SAP Web IDE. Probably soon. So what can you do in the meanwhile to solve this issue?
The answer is easy. Use one of the available build tools. There is Grunt and there is Gulp among others. For both tools packages are available to generate the preload file. I choose Gulp here, because I saw the video of Eric Schoffstall presentation MountainWest JavaScript 2014 – Build Systems The Next Generation by Eric Schoffstall – YouTube. Great show, worth seeing and also entertaining!
gulp-ui5-preload package
With Gulp we can use the very handy gulpui5-preload package from Christian Theilemann (Thx geekflyer!). I will show it with the Fiori UI5 Boilerplate (UI5BP). Please use the latest version is case you have already download the source of the UI5BP. For UI5BP and if you have node.js installed it quite simple:
install necessary packages via npm (npm comes with node.js, this task is only initially necessary):
npm install
and generate to Component-preload.js with Gulp:
gulp ui5preload
on success you should see something like this:
and as result you have the generated Component-preload.js file:
Be aware that you always have to rebuild the Component-preload if you made changes to one of the included files! So it makes sense to generate it, if you deploy on QA or PRODUCTION and remove it if you developing locally.
The base for this easy build process are the file package.json which defines the relevant package. This information is used by npm to install the necessary packages locally. And the gulpfile.js, which defines what should be added to the Component-preload.js and what not:
var gulp = require('gulp');
var ui5preload = require('gulp-ui5-preload');
var uglify = require('gulp-uglify');
var prettydata = require('gulp-pretty-data');
var gulpif = require('gulp-if');
gulp.task(
'ui5preload',
function() {
return gulp.src(
[
'**/**.+(js|xml)',
'!Component-preload.js',
'!gulpfile.js',
'!WEB-INF/web.xml',
'!model/metadata.xml',
'!node_modules/**',
'!resources/**'
]
)
.pipe(gulpif('**/*.js', uglify())) //only pass .js files to uglify
.pipe(gulpif('**/*.xml', prettydata({type: 'minify'}))) // only pass .xml to prettydata
.pipe(ui5preload({
base: './',
namespace: 'ui5bp',
fileName: 'Component-preload.js'
}))
.pipe(gulp.dest('.'));
}
)
Workaround for SAP Web IDE and HCP
If you followed the previous post and deployed the UI5BP app via SAP Web IDE to SAP HANA Cloud Platform (HCP) and on the Cloud SAP Fiori Launchpad ( Deploy UI5 Boilerplate on Fiori Launchpad of HANA Cloud Platform ) you can generate the Component-preload.js with this workaround:
Step 1: As the SAPUI5/OpenUI5 App is deployed on the Git Repo on HCP checkout/clone the repo locally with Git. You find the Git Repository URL in HCP Cockpit under the following location:
Step 2: generate the Component-preload.js with Gulp:
npm install
gulp ui5preload
Step 3: Add, Commit and Push to HCP Git Repo
git add Component-preload.js
git commit -m "generate Component-prekiad.js"
git push
Step 4: Create and activate a new version of application in HCP Cockpit
This is a two step process. You create a new version go the just push source and in a second step activate this version. The result should look like this:
Now the Fiori App, here Fiori UI5BP is using the Component-preload.js.
Usage of Grunt
For Grunt there is also a task available. Have a look at SAP/grunt-openui5 · GitHub
and the post from Matthias Osswald http://scn.sap.com/community/developer-center/front-end/blog/2015/02/18/optimizing-openui5-apps
Thanks for posting this blog - its extremely helpful!
Ive noticed that some of the resources though included and minified int the Component-preload,js are still loaded again with dedicated requests. Could this be related to the specific reference to those files from other reources using the jQuery.sap.require(...) statements? Should these be removed once he Component-preload,js is there?
thanks again,
Ido
Thanks Ido,
which resources do you mean? Do you have an example?
If these resources are included in the Component-preload.js file they should not be requested after the Component-preload.js was loaded.
BR, HP
It seems like any javascript resources that start with jQuery initialization (or perhaps any "non standard" format):
(function($) {
"use strict";
$.sap.declare("googleMaps.places");
. ...
}(jQuery));
Are loaded specifically even though they are included in the Component-preload.js
Hi Seitz, i to facing the same problem as Ido Shemesh.Please give us the solution so that we can figure out the mistake.
Thanks in advance
Kiran B
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.
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
Hi
After creating the component-preload.js, even my application is loading other files also along with that.
Please help me what did you do to resolve this.
Thanks
Gunjan
Hi! I generated the Component-preload.js file. But what happens next??? How will it be accessed? Should I reference or import it somehow somewhere? How can I instantiate my views, controllers and other js files?
Although using Component-preload.js seems all cool, but for example I can't actually have a file with "-" inside the BSP Application (tried creating in SE80). Also how would i instantiate my components?
var oMenuView = sap.ui.view({
id: "idMenu",
viewName: "view.Navigatsioon.Menu",
type: sap.ui.core.mvc.ViewType.JS,
controller: sap.ui.controller("view.Navigatsioon.Menu")
});
this obviously causes errors since the file is not found. Do I need to reset my resourceroot tag?
Hi,
is your application running without Component-preload.js file, hence is it running with Component.js?
Is your Component.js loaded and executed?
If not, you should first solve this.
Normally views are part of the Component and access/instanciated via routing, if not you can not benefit from Component-preload either!
Normally you create UI5 Apps externally and uploaded with se38 or you could use SAP Web IDE.
BR, HP
Thanks for you quick feedback!
I will first implement Component.js part.
Once i get it to work, i'm still not sure how will the component referencing be affected? For example, at the moment I initialize my component as follows:
var oMenuView = sap.ui.view({
id: "idMenu",
viewName: "view.Navigatsioon.Menu",
type: sap.ui.core.mvc.ViewType.JS,
controller: sap.ui.controller("view.Navigatsioon.Menu")
});
How would I access my custom **.js files after Component-preload.js and Component.js are implemented?
Sorry Man,
what you doing here is creating a view. There is no Component!
This is very basic stuff!
Please have a look at the ui5 walkthrough tutorial and work on this first to get a better understanding on fundamental ui5 concepts!
OpenUI5 SDK - Demo Kit
BR, HP
The UI5 application structure and the Demo Kit has changed a lot since our customers app was developed. So what is basic now and what was basic a year ago are very different.
But to me it seems that in order to successfully use the generated Component-preload file you have to deploy the app to Fiori Launchpad. If your app is launched from Fiori Launchpad (FioriLaunchpad.html or what was the name of the file), then it will try to look for the Component-preload file. Otherwise, nothing will happen (for example when launching directly from index.html).
Please correct me if I am wrong!
Hello HP Seitz,
Is it only available for sap.m library or after a specific version of sap ui5 library. Because we have an application running on an older version of sap ui5 library 1.24.0. Also this is an desktop application using sap.ui.commons. We don't get this error.
regards,
PT
HP,
thank you for this blog - it is well documented and easy to follow. i was able to get my app to generate the component preload using gulp easier than when struggling with grunt.
not sure if you would know but any idea why the library-preload and library.css files are requested twice? same thing on my end.. i am looking into how to reduce those multiple requests.. also, did your sap-icons request took the longest to execute? not sure why that would take so long..
thank you again for your blog
Is there any option to generate Component-preload.js using the SAP Webide, other than the workaround mentioned in the post?
I would be also really interested if there is something like that.