17 Optimize Performance of Oracle JET Apps
About Performance and Oracle JET Apps
In general, you can optimize an Oracle JET app the same way that you would optimize performance for any client-side HTML5 app.
There are many online resources that provide tips for performance optimization. For example, the Google Developers website describes their tools for improving the performance of the app.
Most of the recommendations made by the Google tools are up to you to implement, but Oracle JET includes features that can reduce the payload size and the number of trips to retrieve the Oracle JET app's CSS. In general, strive to follow these guidelines.
- Always minify and bundle app resources to reduce the number of requests from the server.
- Configure the app to load resources from Oracle CDN to minimize network usage.
- Configure the app to use the Oracle JET library on CDN so that the
bundles-config.js
script will load minified bundles and modules by default. - Compress the app with gzip to reduce the size (and enable compression on the web server.)
- Enable HTTP caching on web server so that some requests can be served from the cache instead of from the server. Use ETags on files that should always be served from the server.
- Take advantage of HTTP/2 to serve page resources faster than is possible with HTTP/1.1.
- Use a single page app, so that the browser isn’t forced to tear down and rebuild the whole app.
- Avoid putting too many data-centric components into a single page.
- Optimize graphic images: prefer vector format; choose the appropriate image format based on the best overall compression available.
For more information about these optimization tips and others, see Add Performance Optimization to an Oracle JET App.
Add Performance Optimization to an Oracle JET App
Most tips for optimizing performance of web apps also apply to Oracle JET apps. However, there are some steps you can take that apply specifically to Oracle JET apps to optimize JavaScript, CSS, Oracle JET components, REST calls, and images.
JavaScript Performance Tips
Performance Tip | Details |
---|---|
Maintain the expected JavaScript folder structure |
Use folder organization generated by the Oracle JET tooling and maintain all
JavaScript files inside the |
Send only the JavaScript code that your app needs. |
Oracle JET includes modules that you can load with RequireJS. For additional
information, see Use RequireJS for Modular Development. One approach is
to preload the JavaScript modules that your app will use. The following sample
shows how to modify the require function in the app
main.js .
|
Send minified/obfuscated JavaScript. |
Oracle JET provides minified versions of the Oracle JET library as well as
third-party libraries when available. By default, the path mappings for the
minified versions of these libraries in "jquery": { "cdn": "3rdparty", "cwd": "node_modules/jquery/dist", "debug": { "src": "jquery.js", "path": "libs/jquery/jquery-#{version}.js", "cdnPath": "jquery/jquery-3.x.x" }, "release": { "src": "jquery.min.js", "path": "libs/jquery/jquery-#{version}.min.js", "cdnPath": "jquery/jquery-3.x.x.min" } }, For additional information about using the RequireJS bootstrap file in your Oracle JET app, see About RequireJS in an Oracle JET App. |
Minimize the number of trips to retrieve the JavaScript. |
Oracle JET doesn't provide support for minimizing the number of trips, but RequireJS has an optimization tool that you can use to combine modules. For additional detail, see the documentation for the RequireJS optimizer. Alternatively, use a JavaScript code minifier, such as Terser to bundle and minify the JavaScript source. |
Use lazy loading for JavaScript not needed on first render. |
You can lazy load content that is not needed on first render. For example, you can configure the |
Compress or zip the payload. |
Oracle JET has no control over the server, and this recommendation is up to you to implement. For some additional information and tips, see https://developers.google.com/speed/docs/best-practices/payload#GzipCompression. |
Set cache headers. |
JET has no control over the server, and this recommendation is up to you to implement. For additional information about cache optimization, see https://developers.google.com/speed/docs/best-practices/caching. |
CSS Performance Tips
Performance Tip | Details |
---|---|
Maintain the expected CSS folder structure |
Use folder organization generated by the Oracle JET tooling and maintain all CSS
files inside the |
Render pages for all the needed CSS once |
Link to style sheets inside the HEAD section of the HTML page and do not use CSS links in the page body to avoid rerendering an already loaded page. |
Send only the CSS that your app needs. |
You can control the CSS content that goes into your app. If you're using the Oracle JET grid system, you can also control which responsive classes get included in the CSS. For details, see Control the Size and Generation of the CSS. |
Send minified/obfuscated CSS. |
By default, Oracle JET includes minified CSS. However, if you want to modify the CSS
to send only what your app needs, you can use Sass to minimize your output. For
additional information, see the |
Oracle JET App and Component Performance Tips
Performance Tip | Details |
---|---|
Configure your app to load bundled JET modules and libraries using Oracle CDN and the bundle configuration support it provides for JET. | Leveraging the Oracle Content Delivery Network (CDN) and bundle configuration support optimizes the app startup performance of enterprise apps and also ensures that your app builds with the module and library versions required for a particular Oracle JET release. Referring directly to the bundles within the app is not recommended and that includes adding or modifying links that make direct reference to the configuration of the bundles. For additional information, see About Configuring the App for Oracle CDN Optimization. |
Consider using plain HTML components were possible. | For stamping components (like Table or ListView) or declarative components (like a composite component), if you embed a simple Oracle JET component like a read-only input component or button, consider using a plain HTML component instead. The plain HTML component can be lighter weight (less DOM), and if the component is stamped that can add up. However, note that with plain HTML, you also won't have access to any built-in accessibility support, such as converters and validators, which the Oracle JET component provides. |
Follow Oracle JET component best practices. |
Consult the API documentation for the Oracle JET component. The API Reference for Oracle® JavaScript Extension Toolkit (Oracle JET) includes a performance section for a component when applicable. For example, see the ojDataGrid—Performance section. |
Limit number of Oracle JET components per page. |
The number of components on the page will impact the page load time. If you want to reduce the load time, place fewer data-centric components in the page. |
Use the |
When a component contains hidden content to display, the |
Limit the fetch size for collection components |
Set the collection component |
REST Request Performance Tips
Performance Tip | Details |
---|---|
Reduce the number of roundtrips between client and server. |
There are a number of techniques that you can use to reduce the number of roundtrips, and here are some examples:
|
Image Optimization
Performance Tip | Details |
---|---|
Maintain the expected images folder structure |
Use folder organization generated by the Oracle JET tooling and maintain all image
files inside the |
Reduce image size. |
Reducing the size of the images will result in faster downloads and reduce the time it takes to render the content on the screen. For example, Scalable Vector Graphics (SVG) images are usually smaller than Portable Network Graphics (PNG) images and scale on high resolution devices. There are also a number of third-party tools that you can use to reduce the size of your images. The tool that you select will depend on the image type, for example: |
Reduce the number of roundtrips between client and server. |
There are a number of techniques that you can use to reduce the number of roundtrips, and here are some examples:
|
For additional performance tips, see the Google Developers documentation for improving the quality of web pages, including how to audit for performance.
About Configuring the App for Oracle CDN Optimization
You can configure the Oracle JET app to minimize the network load at app startup through the use of Oracle Content Delivery Network (CDN) and the Oracle JET distributions that the CDN supports.
The local loading of the required Oracle JET libraries and modules, as configured by default when you create the app, is not recommended for a production app since it does not use Oracle CDN and requires each app running in the browser to load libraries and modules in a standalone manner. This default configuration can be used when you build and serve the app locally until you need to stage the app in a test environment to simulate network access.
To enable Oracle CDN optimization, you configure the
path_mapping.json
file in your app. The choices you make in the path
mapping file determine the libraries and modules settings for the entire app. With this file,
you will not need to edit the path URL of the required libraries and modules in any other app
file. When you configure path mapping for CDN optimization, you will determine how the tooling
updates the require block of the main.js
file and how the app will load
modules and libraries as follows:
-
If you configure path mappings to use CDN without accessing the bundles configuration, so that modules and libraries will be loaded individually from CDN, the tooling injects the URLs from the path mapping file into the
requirejs
block ofmain.js
. -
If you configure the path mappings to use CDN bundle loading, the tooling updates the
index.html
file to execute the bundles configuration script file (bundles-config.js
) from the following script reference:<body> <script type="text/javascript" src="https://static.oracle.com/cdn/jet/14.1.0/default/js/bundles-config.js"></script> .. </body>
Note: Starting in JET release 9.0.0, the convention of using the leading character "
v
" to identify the release number has changed. As the above sample shows, the release identifier is now a semver value specified as14.1.0
with no leading character.
The bundles configuration file specifies its own require block that the app executes
to load as a set of bundled modules and libraries from CDN. When you configure the app this
way, the main.js
is updated by the tooling to display only a URL list
composed of third-party libraries. In the bundles configuration scenario, the injected require
block in main.js
becomes a placeholder for any app-specific libraries that
you want to add to the list. Where URL duplications may occur between the require block of the
bundles configuration file and the app main.js
, the bundles configuration
takes precedence to ensure bundle loading from CDN has the priority.
Tip:
Configuring your app to reference the bundles configuration script file on Oracle CDN is recommended because Oracle maintains the configuration for each release. By pointing your app to the current bundles configuration, you will ensure that your app runs with the latest supported library and module versions.
Configure Bundled Loading of Libraries and Modules
For Oracle CDN optimization, you may use the bundles configuration script that loads a set of bundled libraries and modules from the CDN.
To configure bundle loading of the libraries and modules using the bundles configuration script, perform the following steps.
Configure Individual Loading of Libraries and Modules
You can configure path mappings to use CDN without accessing the bundles configuration script, so that modules and libraries are loaded individually from the CDN.
main.js
(without the use of the bundles
configuration script), perform the following steps.
main.js
; edit instead the path_mapping.json
file
and, in the case of bundle loading, also edit the bundles-config.js
URL
in your app’s index.html
file. You will need to rebuild the app to
apply the changes. For details about the path_mapping.json
file and the
configuration updates performed by the tooling, see Understand the Path Mapping Script File and Configuration Options.
Understand the Path Mapping Script File and Configuration Options
When you build the application, the tooling invokes the path_mapping.json
configuration file and determines the URL path for the Oracle JET modules and libraries based on the settings you configured for the use
element.
The path mapping use
element, set to local
by default, specifies location of these require libraries:
-
Core Oracle JET libraries (appear as
ojs
,ojL10n
,ojtranslations
) -
Third-party dependency libraries (for example, knockout, jquery, hammerjs, and other)
When you build your app, by default, Oracle JET will load the libraries from the
local app as specified in the require block of the app's main.js
. Each
library URL is assembled from the baseUrl
element and the
path
attribute of the lib
element as specified by the path
mapping file.
For example, the path mapping definition for the knockout library shows the following details.
"baseUrl": "js"
"use": "local"
"libs": {
...
"path": "libs/knockout/knockout-3.x.x.debug"
}
And, after build or serve, the main.js
require block contains the following URI:
/js/libs/knockout/knockout-3.x.x.debug
When configured for Oracle Content Delivery Network (CDN), the
main.js
require block is determined either entirely by the path mapping
file local to the app or, in the case of the bundle loading optimization, partially from the
path mapping file and partially from the require block of the
bundles-config.js
file maintained by Oracle on Oracle CDN. Path injector
markers in main.js
indicate where the release specific URLs appear.
CDN Scenario 1: To load libraries and modules as bundles from CDN, by default only the path mappings for third-party libraries will appear in the URL library list in the require block of main.js
.
For example, the path mapping definition for the knockout library shows the following details. Note that the config
attribute specifies the name of the bundles configuration script file as bundles-config.js
.
"baseUrl": "js" <==ignored
"use": "cdn"
"cdns": {
"jet": {
"prefix": "https://static.oracle.com/cdn/jet/14.1.0/default/js",
"css": "https://static.oracle.com/cdn/jet/14.1.0/default/css",
"config": "bundles-config.js"
},
"3rdparty": "https://static.oracle.com/cdn/jet/14.1.0/3rdparty"
},
"libs": {
...
"cdnPath": "knockout/knockout-3.x.x"
}
And, after build or serve, the main.js
require block contains a list of third-party library URLs as a placeholder, and, as the following code snippet shows, the index.html
file references the script to load libraries and modules as bundles from CDN.
<body>
<script type="text/javascript" src="https://static.oracle.com/cdn/jet/14.1.0/default/js/bundles-config.js"></script>
..
</body>
Note that loading libraries and module as specified in the require block of the
bundles-config.js
file takes precedence over any duplicate libraries that
may appear in the main.js
require block. However, if you prefer, you can
configure the third-party library path mapping so their URLs do not appear in the
main.js
require block. To accomplish this, set "cdn":
"3rdparty"
in the path_mapping.json
file to show "cdn":
"jet"
for each third-party library path definition.
CDN Scenario 2: To load the libraries individually from CDN using the path mapping URLs to specify the location, the list of library URLs will appear entirely in the require block of main.js
.
For example, the path mapping definition for the knockout library shows the following details after you edit the cdns
element to remove the bundles configuration script reference.
"baseUrl": "js" <==ignored
"use": "cdn"
"cdns": {
"jet": "https://static.oracle.com/cdn/jet/14.1.0/default/js",
"css": "https://static.oracle.com/cdn/jet/14.1.0/default/css",
"3rdparty": "https://static.oracle.com/cdn/jet/14.1.0/3rdparty"
}
"libs": {
...
"cdnPath": "knockout/knockout-3.x.x"
}
And, after build or serve, the main.js
require block contains the following URL (along with the URLs for all other base libraries and modules):
"knockout":"https://static.oracle.com/cdn/jet/14.1.0/3rdparty/knockout/knockout-3.x.x"
CDN Scenario 3: If your app needs to access libraries that reside on a
non-Oracle CDN, you can update the path-mapping.js
file to specify your own
CDN endpoint and library definition.
Depending on whether you use the bundles configuration script, add your CDN name and endpoint URI to the cdns
definition as follows.
When using the bundles configuration script to load libraries and modules:
"cdns": {
"jet": {
"prefix": "https://static.oracle.com/cdn/jet/14.1.0/default/js",
"css": "https://static.oracle.com/cdn/jet/14.1.0/default/css",
"config": "bundles-config.js"
},
"3rdparty": "https://static.oracle.com/cdn/jet/14.1.0/3rdparty"
"yourCDN": "endPoint to your own CDN"
},
...
Or, when loading libraries and modules individually (not using the bundles configuration script):
"cdns": {
"jet": "https://static.oracle.com/cdn/jet/14.1.0/default/js",
"css": "https://static.oracle.com/cdn/jet/14.1.0/default/css",
"3rdparty": "https://static.oracle.com/cdn/jet/14.1.0/3rdparty",
"yourCDN": "endPoint to your own CDN"
},
...
Then, in the list of libraries, define your library entry similar to the following sample.
"yourLib": {
"cdn": "yourCDN",
"cwd": "node_modules/yourLib",
"debug": {
"src": "yourLib.js",
"path": "libs/yourLib/yourLib.js",
"cdnPath": "yourLib/yourLib.js"
},
"release": {
"src": "yourLib.min.js",
"path": "libs/yourLib/yourLib.min.js",
"cdnPath": "yourLib/yourLib.min.js"
}
},