In 1.4.0 StealTools added a new optimize API which aims to replace stealTools.build
as the default way of creating a build of a module and all of its dependencies; builds created by stealTools.optimize are smaller and load faster.
Unlike regular builds, optimized builds don't need to load or bundle StealJS at all; a thin wrapper is added instead to the main bundle so the browser can load and execute the modules correctly.
The optimize API is a work in progress, some StealJS features are not supported yet.
In this guide, we'll go through the steps required to create and use an optimized build. We'll be using the
myhub application created in the Progressive Loading guide.
Now, start an http server by running npm start and open http://127.0.0.1:8080/
in a web browser. You should see myhub's home page.
One limitation of the optimized loader is that unlike StealJS' loader it does not normalize module identifiers on runtime. For static imports that's not a problem, but it's an issue for dynamic imports (through steal.import), the module identifier needs to match the name set in bundle.
Performance comparison
For most application builds where StealJS is not included in each of the main bundles, optimized builds will
have one fewer http request on the initial load which is already a win.
In this example, we are comparing how fast the load event is fired (this event is fired when a resource and its dependent resources have finished loading) when creating the build using stealTools.build (with bundleSteal set to true) and stealTools.optimize.
In the screenshot above, the build created by stealTools.build takes 157ms to
fire the load event, in contrast the optimized build takes 119ms (24% faster) to fire the load event, see the screenshot below.
It's also worth noting that the optimized bundles are smaller; the gzip size of the optimized main bundle is 31.8 kB compared to the 59.5 kB bundle of the regular build (46% smaller!).
Progressive loading and async script tags
So far we have only loaded the main module of the myhub application; one of the features of this application is that it progressively loads the modules needed to render the weather page and the puppies page only when the user navigates to any of these pages.
Once again, the optimized bundle is smaller than the regular one (although the difference is less that 1 kB); but unlike regular bundles loaded with StealJS, the optimized loader can handle bundles loaded using script tags; which means we can take advantage of the browser capability to download the bundle and parse its code without blocking the main thread and without waiting for the user to click any of the navigation links.
Edit index.html to asynchronously load the bundles of the other two pages like this:
If you reload your browser, you'd notice that there are two extra requests and the load event takes more or less the same time to fire as before. The browser downloaded and parsed the bundles without blocking the main thread, instead of waiting for the user to navigate away from the home page, which results in smoother transitions.
Navigate to the puppies page and see it for yourself!
iOS builds using Apache Cordova
In this part of the guide we will turn the myhub application into an iOS application that can be tested in the iOS simulator using Apache Cordova.
This guide is targeted to macOS users, please download and install Xcode from the AppStore before moving forward.
To set up the Cordova build, we have to install a couple of packages, run:
Once steal-cordova is installed and saved in your package.json file, update optimize.js with the following code:
var path = require("path");
var stealTools = require("steal-tools");
var stealCordova = require("steal-cordova")({
buildDir: "./build/cordova",
id: "com.myhub",
name: "MyHub",
platforms: ["ios"],
index: path.join(__dirname, "index.html")
});
stealTools
.optimize()
.then(stealCordova.build)
.then(function() {
// launch the iOS simulator automatically
stealCordova.ios.emulate();
});
Read steal-cordova documentation to get familiar with all the available options.
Run the build script with:
> node optimize.js
Congrats! you just created an iOS application!
If you receive the error "Error: Cannot read property 'replace' of undefined", you can work around it by running cd build/cordova/platforms/ios/cordova/ && npm install ios-sim@6 then cd back into the myhub root folder and run the optimize build script again.
Optimized build targets and Cordova builds
The optimize API can be passed a target option to generate code specific to certain platforms, you can read more about it in the steal-tools documentation.
The Cordova build requires the web target output to be passed in, first, make sure your target array includes the "web" option.
Assuming you're creating a build to load on Web Workers as a second target, optimize.js should look like this:
// The code up to this point remains the same
stealTools
.optimize({}, { target: ["web", "worker"] })
.then(function(buildResult) {
return stealCordova.build(buildResult.web);
})
.then(function() {
stealCordova.ios.emulate();
});
and that's it!
Desktop builds using Electron
In the last part of this guide we will make a desktop build of our myhub application using Electron.
To set up the desktop build, we have to install steal-electron by running:
npm install --save-dev steal-electron
Electron main module
We will need a different entry point for our Electron application, this module will take care of creating windows and handling system events.
In 1.4.0 StealTools added a new optimize API which aims to replace stealTools.build as the default way of creating a build of a module and all of its dependencies; builds created by
stealTools.optimize
are smaller and load faster.Unlike regular builds, optimized builds don't need to load or bundle StealJS at all; a thin wrapper is added instead to the main bundle so the browser can load and execute the modules correctly.
In this guide, we'll go through the steps required to create and use an optimized build. We'll be using the
myhub
application created in the Progressive Loading guide.Install Prerequisites
Window Setup
Linux / Mac Setup
Setting up myhub
Clone the Github repo
Run the following command:
Install dependencies
As mentioned before, the optimize API is still in its early days, for that reason we need to use some pre-release packages.
Edit your
package.json
like:Run
npm install
to install all the application dependencies.Make an optimize build script
Create optimize.js:
Run the build script with:
Now, start an http server by running
npm start
and openhttp://127.0.0.1:8080/
in a web browser. You should see myhub's home page.Performance comparison
For most application builds where StealJS is not included in each of the main bundles, optimized builds will have one fewer http request on the initial load which is already a win.
In this example, we are comparing how fast the load event is fired (this event is fired when a resource and its dependent resources have finished loading) when creating the build using
stealTools.build
(withbundleSteal
set totrue
) andstealTools.optimize
.In the screenshot above, the build created by stealTools.build takes 157ms to fire the load event, in contrast the optimized build takes 119ms (24% faster) to fire the load event, see the screenshot below.
It's also worth noting that the optimized bundles are smaller; the gzip size of the optimized main bundle is 31.8 kB compared to the 59.5 kB bundle of the regular build (46% smaller!).
Progressive loading and async script tags
So far we have only loaded the main module of the
myhub
application; one of the features of this application is that it progressively loads the modules needed to render theweather
page and thepuppies
page only when the user navigates to any of these pages.Once again, the optimized bundle is smaller than the regular one (although the difference is less that 1 kB); but unlike regular bundles loaded with StealJS, the optimized loader can handle bundles loaded using script tags; which means we can take advantage of the browser capability to download the bundle and parse its code without blocking the main thread and without waiting for the user to click any of the navigation links.
Edit
index.html
to asynchronously load the bundles of the other two pages like this:If you reload your browser, you'd notice that there are two extra requests and the load event takes more or less the same time to fire as before. The browser downloaded and parsed the bundles without blocking the main thread, instead of waiting for the user to navigate away from the home page, which results in smoother transitions.
Navigate to the puppies page and see it for yourself!
iOS builds using Apache Cordova
In this part of the guide we will turn the
myhub
application into an iOS application that can be tested in the iOS simulator using Apache Cordova.To set up the Cordova build, we have to install a couple of packages, run:
Update the optimize build script
Once
steal-cordova
is installed and saved in yourpackage.json
file, update optimize.js with the following code:Run the build script with:
Congrats! you just created an iOS application!
Optimized build targets and Cordova builds
The
optimize
API can be passed a target option to generate code specific to certain platforms, you can read more about it in the steal-tools documentation.The Cordova build requires the web target output to be passed in, first, make sure your
target
array includes the "web" option.Assuming you're creating a build to load on Web Workers as a second target, optimize.js should look like this:
and that's it!
Desktop builds using Electron
In the last part of this guide we will make a desktop build of our
myhub
application using Electron.To set up the desktop build, we have to install
steal-electron
by running:Electron main module
We will need a different entry point for our Electron application, this module will take care of creating windows and handling system events.
Create electron-main.js with the following code:
Update the optimize build script
Once
steal-electron
is installed and saved in yourpackage.json
file, update optimize.js with the following code:Run the build script with:
Then open the generated application file by running the following command:
Congrats, you just created a desktop application!