I am building an angular 2 app in plain JS. My problem is that when I change from a page to another it flicker a white page until the new view is rendered. This happens for all components only first time I access them. If I go to same route second time the page is loaded without white page. I capture the screen to explain better my problem: https://drive.google.com/file/d/0B5pOsXT-4rdTbmtuVnlUdXRMdE0/view?usp=sharing
Here is my main view:
<router-outlet></router-outlet>
<nav id="menu">
<a [routerLink]="['Page1']">Page 1</a>
<a [routerLink]="['Page2']">Page 2</a>
<a [routerLink]="['Page3']">Page 3</a>
<a [routerLink]="['Page4']">Page 4</a>
<a [routerLink]="['Page5']">Page 5</a>
</nav>
RouteConfig is defined like this:
AppComponent = ng.router
.RouteConfig([
{path: '/page1', name:"Page1", component: Page1Component, useAsDefault: true },
{path: '/page2', name:"Page2", component: Page2Component},
...
])
(AppComponent);
And all my components have a .html file and a .css file like this:
Page1Component = ng.core
.Component({
selector: 'rl-page1',
templateUrl: 'app/components/page1/view.html',
styleUrls: ['app/components/page1/style.css'],
directives: [ng.router.ROUTER_DIRECTIVES]
})
.Class({
constructor: [ng.router.Router, function(router) {
this.router = router;
}]
});
From what it looks like angular cache pages after I access them and at second access will display instantly (without white flickering). I search how I can preloade this but I can't find any answer or method on this.
Please let me know if you need more code.
(I don't use Page1, Page2 in real app, only for this question I changed to be more clear for example)
Thanks.
EDIT: 2016-03-18
I try to use DynamicComponentLoader to load all the components in a hidden div. The code looks like this in AppComponent:
ngOnInit: function(){
this.dcl.loadIntoLocation(Page1Component, this.elementRef, 'preloadpages');
this.dcl.loadIntoLocation(Page2Component, this.elementRef, 'preloadpages');
},
and the html where is loaded is: <div style="display: none;"><div #preloadpages></div></div>
But I faced 2 problems:
If one of my component has in the constructor RouteParams like this:
constructor: [ng.router.RouteParams, function(routeParam) {
...
}],
I am getting this error: EXCEPTION: No provider for RouteParams! (class19 -> RouteParams)
All components are loaded just like you open it. If I have a ajax call in a constructor that ajax call is created and all the components html will be appended in my hidden div. Here can be a performance problem if at start I try to load like 5 components and some make ajax calls. I am looking if there is a solution to load only html + css or to send a flag to component constructor to know that I am loading hidden just for preaching.
Thanks.
Paraphrasing https://stackoverflow.com/a/37298914/441662
The problem is that the files are loaded separately, which you can prevent using something like webpack that compiles the sources into bundles which can include both your app and the templates used in the routes. (altough I still can't explain the jump to the top of the page).
Here's how you can modify the webpack config of the angular/angular2-seed project:
package.json
"devDependencies": {
...,
"html-loader": "^0.4.3",
},
webpack.config.js
module: {
loaders: [
...,
{ test: /\.html$/, loader: 'html' }
]
}
Example usage in your-component.ts
@Component({
template: require('app/components/your-component/your-component.html')
})
Now the routes are loaded instantly and there is no flickering or jumping going on.
Add a wrapper around the <router-outlet>
<div [hidden]="!isInitialized">
<router-outlet></router-outlet>
</div>
In the page component set isInitialized
to false
. Then call
this.router.navigate(['Page1'])
.then(_ => this.router.navigate(['page2']))
.then(_ => this.router.navigate(['page3']))
...
.then(_ => {
this.isInitialized = true;
this.router.navigate(['Page1']);
});
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With