ionic-framework: Unable to bootstrap an Ionic2 app in a web worker
Short description of the problem:
The current bootstrap process for Ionic2, whether via the @App
decorator or through direct use of the ionicProviders
function in https://github.com/driftyco/ionic/blob/2.0/ionic/config/bootstrap.ts makes it really difficult to run it in a web worker. They make direct use of the window
and document
objects which are not available in a web worker.
What behavior are you expecting?
Suggest the creation of an ionicProviders
equivalent that uses abstracted ng2 primitives (e.g DomAdapter, MessageBus, etc) to obtain the needed information when running in a worker app.
Might need a message bus bridge internally to retrieve the necessary information from the render thread. FYI: https://github.com/angular/angular/blob/master/modules/angular2/docs/web_workers/web_workers.md
Steps to reproduce:
- Try to boot an Ionic2 app in a web worker
export function ionicProviders(args: any={}) {
let platform = new Platform();
let navRegistry = new NavRegistry(args.pages);
var config = args.config;
if (!(config instanceof Config)) {
config = new Config(config);
}
platform.setUrl(window.location.href);
platform.setUserAgent(window.navigator.userAgent);
platform.setNavigatorPlatform(window.navigator.platform);
platform.load();
config.setPlatform(platform);
let clickBlock = new ClickBlock();
let events = new Events();
let featureDetect = new FeatureDetect();
setupDom(window, document, config, platform, clickBlock, featureDetect);
bindEvents(window, document, platform, events);
// prepare the ready promise to fire....when ready
platform.prepareReady(config);
return [
IonicApp,
provide(ClickBlock, {useValue: clickBlock}),
provide(Config, {useValue: config}),
provide(Platform, {useValue: platform}),
provide(FeatureDetect, {useValue: featureDetect}),
provide(Events, {useValue: events}),
provide(NavRegistry, {useValue: navRegistry}),
TapClick,
Form,
Keyboard,
MenuController,
Translate,
ROUTER_PROVIDERS,
provide(LocationStrategy, {useClass: HashLocationStrategy}),
HTTP_PROVIDERS,
];
}
function setupDom(window, document, config, platform, clickBlock, featureDetect) {
let bodyEle = document.body;
let mode = config.get('mode');
// if dynamic mode links have been added the fire up the correct one
let modeLinkAttr = mode + '-href';
let linkEle = document.head.querySelector('link[' + modeLinkAttr + ']');
if (linkEle) {
let href = linkEle.getAttribute(modeLinkAttr);
linkEle.removeAttribute(modeLinkAttr);
linkEle.href = href;
}
// set the mode class name
// ios/md/wp
bodyEle.classList.add(mode);
// language and direction
platform.setDir(document.documentElement.dir, false);
platform.setLang(document.documentElement.lang, false);
let versions = platform.versions();
platform.platforms().forEach(platformName => {
// platform-ios
let platformClass = 'platform-' + platformName;
bodyEle.classList.add(platformClass);
let platformVersion = versions[platformName];
if (platformVersion) {
// platform-ios9
platformClass += platformVersion.major;
bodyEle.classList.add(platformClass);
// platform-ios9_3
bodyEle.classList.add(platformClass + '_' + platformVersion.minor);
}
});
// touch devices should not use :hover CSS pseudo
// enable :hover CSS when the "hoverCSS" setting is not false
if (config.get('hoverCSS') !== false) {
bodyEle.classList.add('enable-hover');
}
if (config.get('clickBlock')) {
clickBlock.enable();
}
// run feature detection tests
featureDetect.run(window, document);
}
/**
* Bind some global events and publish on the 'app' channel
*/
function bindEvents(window, document, platform, events) {
window.addEventListener('online', (ev) => {
events.publish('app:online', ev);
}, false);
window.addEventListener('offline', (ev) => {
events.publish('app:offline', ev);
}, false);
window.addEventListener('orientationchange', (ev) => {
events.publish('app:rotated', ev);
});
// When that status taps, we respond
window.addEventListener('statusTap', (ev) => {
// TODO: Make this more better
var el = document.elementFromPoint(platform.width() / 2, platform.height() / 2);
if (!el) { return; }
var content = closest(el, 'scroll-content');
if (content) {
var scrollTo = new ScrollTo(content);
scrollTo.start(0, 0, 300, 0);
}
});
// start listening for resizes XXms after the app starts
setTimeout(function() {
window.addEventListener('resize', function() {
platform.windowResize();
});
}, 2000);
}
Ionic Version: 2.x
Browser & Operating System: Android / Chrome
Run ionic info
from terminal/cmd prompt:
Your system information:
Cordova CLI: 6.0.0
Gulp version: CLI version 3.9.1
Gulp local: Local version 3.9.1
Ionic Version: 2.0.0-beta.2
Ionic CLI Version: 2.0.0-beta.19
Ionic App Lib Version: 2.0.0-beta.9
OS:
Node Version: v5.6.0
About this issue
- Original URL
- State: closed
- Created 8 years ago
- Reactions: 4
- Comments: 16 (4 by maintainers)
I would also like to run ionic in a web worker as it brings fairly big performance improvements. Is this planned for the final release of v2?
@adamdbradley ?
+1 I find webworkers to be a pivotal implementation for ionic and absolutely would like to hear more about it.
Hello! Is there any chance to get any updates on this feature request? Is it accepted and planned to be released as part of a known milestone? Thanks.
Now that there is the new
ionicBootstrap
function would it be possible to also provide two functionsionicBootstrapRender
andionicBootstrapWorker
? The setup part for the platform and DOM could be executed in the former and the results could be send via thepostMessage
mechanism to the application. The application would then be bootstrapped as a result of this setup message.+1
Is there any update on this?
+1 to let ionic run in a web worker