Importing rxjs operators: Best practices when lazy loading


#1

When modules were eagerly loaded (framework 2), I only had to load rxjs operators like take or do one time, and could do it more or less anywhere, and it would be available to all modules. Now it looks as though each time I want to use take, I need to import it into the module where I want to use it.

Does anyone have ideas about best practices here? While debugging, I’ll probably import do into app.component.ts, because I see myself using that a lot. But do I have duplicate take code for each page where I import take? If so, this looks like potentially a more expensive duplication than the code duplication for components. (At least my components tend to be smaller than rxjs operators.)


Ionic 3 update problem with Http
Modular architecture of Ionic 2 application
Considering deleting all page module files
#2

EDIT: I was wrong, see below.

No. Angular internals like RxJS get magically promoted into the CommonsChunk, so they stay in the root main.js.


#3

I need to import operators into each page where I use them. Doing it with from right now. Is that expected behavior? You’re saying I need to mention it every time, but each mention relates to the same code section in CommonsChunk?


#4

Well, I was saying that, but turns out I was wrong. They do in fact get duped:

import { Component } from '@angular/core';
import {IonicPage, NavController} from 'ionic-angular';
import {Observable} from "rxjs/Observable";
import "rxjs/add/observable/interval";
import "rxjs/add/operator/skip";

@IonicPage()
@Component({
  selector: 'page-contact',
  templateUrl: 'contact.html'
})
export class ContactPage {
  constructor(public navCtrl: NavController) {
    Observable.interval(1000).skip(3).subscribe(v => console.log('contact ' + v));
  }
}
import { Component } from '@angular/core';
import {IonicPage, NavController} from 'ionic-angular';
import {Observable} from "rxjs/Observable";
import "rxjs/add/observable/interval";
import "rxjs/add/operator/skip";

@IonicPage()
@Component({
  selector: 'page-about',
  templateUrl: 'about.html'
})
export class AboutPage {
  constructor(public navCtrl: NavController) {
    Observable.interval(1000).skip(3).subscribe(v => console.log('about ' + v));
  }
}

Observable itself is in main.js, but I see copies of skip and interval in both page files.

Now for the good news It gets worse. I had a hope that importing Observable straight from rxjs might help, and just pick the operators out of the commons chunk. Nope, makes things astronomically worse, as now each page gets 600K of the rxjs kitchen sink.


#5

Well ok. I only use BehaviorSubject on one page, but I use Observable on most pages. So my current plan is that I will try to load Observable and most operators once, globally; and load what I rarely use with the pages that need them.


#6

I’m a bit mystified that that even compiles, but it seems to work. Importing skip and interval in app.component.ts brings them into the commons chunk and both lazily loaded pages still seem to be able to access them. JavaScript is just straight-up weird.


#7

Currently, it looks as though I can import operators globally in app.component.ts, but I need to import Observable and Subscription in each page.


#8

I don’t think that will cost you, though. In my scratchpad project, both Observable and Subscription are in main.js.


#9

Ya. Exactly my problem. I am lazy loading 5 pages which wont be used frequently by the user. But each page has to import a module which imports raxjs. Now my bundle size is going up because of rxjs duplication. btw can you please post your bundle (main.js) with webpack visualizer ? I would like to see how it looks in ionic serve and in ionic run android --prod ?


#10

I don’t have that scratch project in that state any more, sorry.


#11

Hi @AaronSterling

I’m just in the process of trying to optimise my app startup time and performance and just came across this thread.

I currently import the rxjs operators in every component/service that uses them. From what you said it’s better to import these in one place globally (app.component.ts). Is that the case? Many thanks.


#12

I don’t know. The only data point I’m aware of is here. If you experiment, I’d like to know what you find out.