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. |
To control the CSS content that goes into your app, create a custom theme and limit what it includes to the CSS that your app needs. See Optimize the CSS in a Custom Theme. Also, 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 an Oracle JET app to minimize the network load at app startup through the use of the 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, which is configured by default when you create the app, is not recommended for a production app because it does not use the 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, configure the path_mapping.json
file in your app. The options configured in the path mapping file determine the library and module settings for the entire app. With the path_mapping.json
file, you do 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 the path mappings to use the CDN without accessing the bundles configuration, such that modules and libraries will be loaded individually from the CDN, the tooling injects the URLs from the path mapping file into the
require
block of themain.js
file. -
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/17.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 as 17.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 the CDN. When you configure the app this way, the main.js
file is updated by the tooling to display only a URL list comprising third-party libraries. In the bundles configuration scenario, the injected require
block in the main.js
file 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's main.js
file, the bundles configuration takes precedence to ensure bundle loading from the CDN has priority.
Tip:
Configuring your app to reference the bundles configuration script file on the 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 the CDN without accessing the bundles configuration script, so that modules and libraries are loaded individually from the CDN.
require
block of the main.js
file (without the use of the bundles configuration script), perform the following steps.
main.js
file; instead, edit 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
You may need to integrate additional functionality into your apps using libraries and modules that are not provided by Oracle JET. Apps built using Oracle JET's command-line interface (CLI) have a mechanism that helps with this process: the path_mapping.json
file.
When you build or serve your app, Oracle JET tooling invokes the appRootDir/src/js/path_mapping.json
configuration file and determines the URI path for the Oracle JET modules and libraries based
on the settings you configured for the path mapping use
attribute.
The use
attribute, set to local
by default, specifies the location of required libraries including core Oracle JET libraries (such as ojs
, ojL10n
, and ojtranslations
) and third-party dependency libraries (such as knockout
, jquery
, and hammerjs
).
When you build your app, Oracle JET defines load paths for each library specified in the path_mapping.json
file using the requirejs.config()
function of the app's main.js
file. Each library path URI is determined based on the path
or cdnPath
attribute of the library listed in the libs
map.
For example, the path mapping entry for the Knockout library shows the following details.
"libs": {
"knockout": {
"cdn": "3rdparty",
"cwd": "node_modules/knockout/build/output",
"debug": {
"src": "knockout-latest.debug.js",
"path": "libs/knockout/knockout-#{version}.debug.js",
"cdnPath": "knockout/knockout-3.x.x.debug"
},
"release": {
"src": "knockout-latest.js",
"path": "libs/knockout/knockout-#{version}.js",
"cdnPath": "knockout/knockout-3.x.x"
}
},
After building or serving the app, the main.js
file's requirejs.config()
paths map contains the following path mapping:
"knockout":"libs/knockout/knockout-x.x.x.debug"
For more information on the path_mapping.json
configuration file and
how to use it, see Add Third-Party Tools or Libraries to Your Oracle JET App.
Work with Libraries and Modules on Content Delivery Networks
The following list includes common scenarios encountered in working with libraries and modules hosted on CDNs and your Oracle JET apps.
When configured for the Oracle CDN, the main.js
file's
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 the Oracle CDN. Path
injector markers in the main.js
file indicate where the release-specific URLs
appear.
-
CDN Scenario 1: To load libraries and modules as bundles from the Oracle CDN, by default only the path mappings for third-party libraries will appear in the URL library list in the
require
block of themain.js
file.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 asbundles-config.js
."baseUrl": "js" <==ignored "use": "cdn" "cdns": { "jet": { "prefix": "https://static.oracle.com/cdn/jet/17.1.0/default/js", "css": "https://static.oracle.com/cdn/jet/17.1.0/default/css", "config": "bundles-config.js" }, "3rdparty": "https://static.oracle.com/cdn/jet/17.1.0/3rdparty" }, "libs": { ... "cdnPath": "knockout/knockout-3.x.x" }
After building or serving your app, the
main.js
file'srequire
block contains a list of third-party library URLs as a placeholder.Note that loading libraries and module as specified in the
bundles-config.js
file'srequire
block takes precedence over any duplicate libraries that may appear in themain.js
file'srequire
block. However, if you prefer, you can configure the third-party library path mapping so that their URLs do not appear in themain.js
file'srequire
block. To accomplish this, edit"cdn": "3rdparty"
in thepath_mapping.json
file to"cdn": "jet"
for each third-party library path definition. -
CDN Scenario 2: To load libraries individually from the Oracle CDN using the path mapping URLs to specify the location, the list of library URLs will appear entirely in the
main.js
file'srequire
block.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/17.1.0/default/js", "css": "https://static.oracle.com/cdn/jet/17.1.0/default/css", "3rdparty": "https://static.oracle.com/cdn/jet/17.1.0/3rdparty" } "libs": { ... "cdnPath": "knockout/knockout-3.x.x" }
After a build or serve, the
main.js
file'srequire
block contains the following URL (along with the URLs for all other base libraries and modules):"knockout": "https://static.oracle.com/cdn/jet/17.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.json
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/17.1.0/default/js", "css": "https://static.oracle.com/cdn/jet/17.1.0/default/css", "config": "bundles-config.js" }, "3rdparty": "https://static.oracle.com/cdn/jet/17.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/17.1.0/default/js", "css": "https://static.oracle.com/cdn/jet/17.1.0/default/css", "3rdparty": "https://static.oracle.com/cdn/jet/17.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" } },