-
Notifications
You must be signed in to change notification settings - Fork 0
Cookbook: bundle
In order to use io.bundle make sure that it is enabled:
// optional:
// set custom properties (can be done at any time)
io.bundle.waitTime = 30; // ms
io.bundle.url = '/custom/bundle'; // URL for a bundler
// defaults are sane, so you are unlikely to break anything
// activate the package
io.bundle.attach();See How to include for more details. See bundle for the full documentation.
const oldBundleOptIn = io.bundle.optIn.bind(io.bundle);
io.bundle.optIn = options => {
if (!oldBundleOptIn(options)) return false;
const match = /^https?:\/\/(.*)$/.exec(options.url);
if (!match) return false;
const domain = match[1].toLowerCase();
if (domain === 'localhost' || /^localhost[:\/]/.test(domain)) return false;
return true;
}
io.bundle.attach();By default bundles are formed within 20ms window. That's probably enough to capture all I/O requests issued on a current execution thread,
and even requests that delayed by DOM layout events. Just enable io.bundle, and it should start working.
io.bundle.attach();
// ...
// now we can collect requests
// ...
io.get(url1).then(/* ... */).then(/* ... */);
// ...
io.get(url2).then(/* ... */);
// ...
io.get(url3).then(/* ... */);
// all three requests will be sent as one bundleIf we know when we issue requests, we can opt in for an explicit collecting of bundles:
io.bundle.waitTime = 0; // turn off a time-based bundle collection
io.bundle.attach();
// ...
// now we can collect requests
io.bundle.start(); // start collecting a bundle
initStuff(); // this procedure can issue I/O requests
io.bundle.commit(); // stop collecting and send out a bundleIf we actually know what requests we want to issue, we can make it even easier:
io.bundle.waitTime = 0; // turn off a time-based bundle collection
io.bundle.attach();
// ...
io.bundle.submit([url1, url2, url3]);Time-based bundling introduces a necessary delay, when a bundle is collected. If we want to reduce it as much as possible, and we are fine with collecting requests only from a current execution thread, we may use heya-defer for that:
io.bundle.waitTime = 0; // turn off a time-based bundle collection
// let's attach our alternative bundling mechanism to inspect()
var oldOptIn = io.bundle.optIn;
io.bundle.optIn = function (options) {
if (oldOptIn(options)) {
if (!io.bundle.isStarted()) {
io.bundle.start();
defer.asap(function () {
io.bundle.commit();
});
}
return true;
}
return false;
};
io.bundle.attach();
// ...
// now we can collect requests
// ...
io.get(url1).then(/* ... */).then(/* ... */);
io.get(url2).then(/* ... */);
io.get(url3).then(/* ... */);
// all three requests will be sent as one bundleWe can issue a bundle request before actually loading any JavaScript library. This way we shifted a data acquisition way forward, so our code will wait less, or, potentially, data will be ready by the time we can consume it.
<!doctype html>
<html>
<head>
<!-- meta information goes here -->
<script>
'use strict';
// data ahead section
(function () {
// put forward a bundle
var xhr = new XMLHttpRequest();
xhr.onload = function () {
var data = JSON.parse(xhr.responseText);
if (window.heya && heya.io && heya.io.bundle) {
// if io.bundle is ready, use it to unbundle
heya.io.bundle.unbundle(data);
} else {
// otherwise store it for future unbundling
window.__io_initial_bundle = data;
}
// no need to fly() the requests => they are already in the cache
delete window.__io_initial_options;
};
// send out a bundle saving original options (URLs) to fly() later
xhr.open('PUT', '/bundle', true);
window.__io_initial_options = ['/me', '/menu', '/clients'];
xhr.send(JSON.stringify(window.__io_initial_options));
}());
</script>
<script src="our.js"></script>
<!-- other import, like CSS styles goes here -->
</head>
<body>
<!-- HTML goes here -->
</body>
</html>The first script session is short. It issues a request for a bundle, which will be collected in our.js file.
We assume that it includes all code we need for our web application. We may import more JavaScript files before our.js.
Somewhere in our.js but after bundle.js is loaded we may deal with our pre-fetch:
// somewhere in our.js after bundle.js,
// but preferably before our actual app code
(function () {
'use strict';
heya.io.bundle.attach();
// processing an initial bundle
if (window.__io_initial_options) {
// register I/O requests in progress
heya.io.bundle.fly(window.__io_initial_options);
delete window.__io_initial_options;
// if we don't fly() them, they can be reinitiated
// by our code that requests those resources
}
if (window.__io_initial_bundle) {
// if data have arrived => unbundle it
heya.io.bundle.unbundle(window.__io_initial_bundle);
delete window.__io_initial_bundle;
}
}());We may create a custom endpoint, which will return a custom bundle with mosts responses required in the future. Frequently, such endpoint takes no direct arguments figuring out details from a session object.
The code will be similar to the previous pre-fetch case.
<!doctype html>
<html>
<head>
<!-- meta information goes here -->
<script>
'use strict';
// data ahead section
(function () {
// put forward a bundle
var xhr = new XMLHttpRequest();
xhr.onload = function () {
var data = JSON.parse(xhr.responseText);
if (window.heya && heya.io && heya.io.bundle) {
// if io.bundle is ready, use it to unbundle
heya.io.bundle.unbundle(data);
} else {
// otherwise store it for future unbundling
window.__io_initial_bundle = data;
}
// no need to fly() the requests => they are already in the cache
delete window.__io_initial_options;
};
// send out a bundle saving original options (URLs) to fly() later
xhr.open('GET', '/custom/endpoint', true);
window.__io_initial_options = ['/me', '/menu', '/clients'];
xhr.send(null);
}());
</script>
<script src="our.js"></script>
<!-- other import, like CSS styles goes here -->
</head>
<body>
<!-- HTML goes here -->
</body>
</html>As you can see the code is quite similar, but we use GET without any payload. We still need to register options (URLs) our code may issue immediately.
The code snippet in our.js will be the same.