2016-04-14 12 views
19

Sprawdzam, dlaczego czas kompilacji dla mojego projektu Angular 2.0 TypeScript minął od około 4 sekund do około 15 sekund w stosunkowo krótkim czasie.Badanie długich czasów kompilacji TypeScript

Natknąłem się na bardzo przydatny, ale z pozoru nieudokumentowany przełącznik --diagnostics.

Na przykład, oto co mi się podczas pracy na moim projekcie tsc --noEmit --diagnostics teraz:

Files:    231 
Lines:   50872 
Nodes:   170067 
Identifiers:  65994 
Symbols:  7712123 
Types:   407677 
Memory used: 600554K 
I/O read:  0.43s 
I/O write:  0.00s 
Parse time:  1.13s 
Bind time:  0.34s 
Check time:  10.17s 
Emit time:  0.00s 
Total time:  11.64s 

Oto co mam kiedy uruchomić tego samego polecenia na wcześniejszej wersji projektu.

Files:    197 
Lines:   30882 
Nodes:   124208 
Identifiers:  46201 
Symbols:  5856945 
Types:   10989 
Memory used: 80412K 
I/O read:  0.03s 
I/O write:  0.00s 
Parse time:  0.60s 
Bind time:  0.27s 
Check time:  0.93s 
Emit time:  0.00s 
Total time:  1.79s 

Liczba Types upadł droga w górę, a więc ma Check time.

Czy można uzyskać bardziej szczegółowe/szczegółowe dane wyjściowe od --diagnostics?

NodeJS v4.4.3, TypeScript v1.8.10. To jest mój tsconfig.json

{ 
    "compilerOptions": { 
    "target": "es5", 
    "module": "system", 
    "moduleResolution": "node", 

    "noImplicitAny": false, 
    "noEmitOnError": false, 

    "experimentalDecorators": true, 

    "emitDecoratorMetadata": true, 
    "removeComments": false 
    }, 
    "exclude": [ 
    "node_modules", 
    "wwwroot", 
    "typings/main.d.ts", 
    "typings/main" 
    ] 
} 

Odpowiedz

0

Compiler znany jest powolny, można użyć kompilatora w trybie zegarka tsc -w lub przełączyć się webpack i ts-loader które narażają transpileOnly opcję (bez czasochłonnej kontroli).

+0

Dzięki. Używamy "gulp-maszynopis" (https://www.npmjs.com/package/gulp-typescript) do oglądania zmian. Obsługuje przyrostową kompilację. Nawet przy oglądaniu konsekwentnie uzyskuję od 12 do 18 sekund kompilacji. Ale kompilacja była szybsza i nie dodawano tak dużo kodu, a my dopiero zaczynaliśmy. Coś, co się zmieniło, musiało być przyczyną problemu, ale przeszukiwanie commit-by-commit byłoby bardzo czasochłonne. –

+0

Próbowałem gulp-maszynopis i wbudowanego kompilatora Intellij Idea, ale było zbyt wolno, około 8 sekund po każdej zmianie, nie do przyjęcia. Teraz używam webpack i ts-loader z opcją transpileonly, czas rekompilacji wynosi około 0.5s. – kemsky

13

Wydaje się, że znalazłem winnego w moim przypadku. Zrobiłem to na własnej skórze; mój proces:

  1. Znajdź zatwierdzenie, które spowodowało spowolnienie kompilacji. Przejdź przez historię commit-by-commit i sprawdź czasy kompilacji.
  2. Skomentuj zmieniony kod, dopóki nie zostaną znalezione nieprawidłowe linie.

Przed popełnieniem przestępstwa konsekwentnie kompilowałem czasy około 2-4 sekund po zatwierdzeniu - 13-17 sekund.

W moim przypadku mam klasy, z accessTokenGetter pola, który został zainicjowany w konstruktorze:

export class JwtConfig { 
    //... 
    accessTokenGetter:() => Observable<string>; 
    //... 
     constructor(private config?: IJwtConfig) { 
      // ... 
      this.accessTokenGetter = this.config.accessTokenGetter || (() => Observable.of(null)); 
     } 
} 

Druga część inicjalizacji || (() => Observable.of(null)); było przyczyną powolność. Skomentowanie lub dodanie adnotacji typu przywróciło czas kompilacji. Ponieważ Observable ma charakter ogólny, wydaje się, że kompilator TypeScript potrzebuje podpowiedzi, aby zawęzić niektóre sprawdzenia typów, które musi wykonać. Moja inicjalizacja brzmi teraz:

//... 
this.accessTokenGetter = this.config.accessTokenGetter || (() => Observable.of(<string>null)); 
//... 

Observable.of(null as string)) również wydaje się wykonywać tę pracę. Było kilka innych miejsc, w których dodawano adnotację typu adnotacja.

Mam nadzieję, że to komuś pomaga.

Nadal, jeśli w kompilatorze jest odpowiedź na odpowiedź szybciej - chętnie bym to usłyszał.

+0

Dzięki, napotkałem ten sam problem. Zapoznaj się z tą zasadą, aby tego uniknąć: dodaj adnotację typu, kiedy to możliwe –

+0

Wow, to jest szalone. Byłoby wspaniale, gdyby istniał zautomatyzowany sposób śledzenia powolnych wniosków, takich jak te. – bcherny

+1

Możesz skorzystać z 'git bisect' z czasem kompilacji jako pivot/condition. To by zajęło tylko kilka minut, by podzielić półtora tysiąca razy. Konfiguracja prawdopodobnie trwa krócej niż godzinę i można ją wykorzystać do przyszłych dochodzeń. – user3041539

0

W moim przypadku czas kompilacji wynosił około 15-30 sekund. Po komendzie tsc --noEmit --diagnostics zauważyłem, że buduję pliki 2k.Rozwiązaniem było wykluczyć wszystkie pliki z folderu node_modules:

{ 
    "compilerOptions": {...}, 
    "exclude": [ 
    "node_modules" 
    ] 
} 

To jest dobry pomysł, aby wykluczyć typings folderu zbyt.

+0

Tak, zgodzono się. Ale już wykluczyłem oba, gdy zacząłem mieć problem. Jeśli chodzi o typowania, nie jestem tego pewien - w zależności od tego, jak skonfigurowałeś swój projekt, tj. Jeśli nie używasz potrójnych slashów ('///

3

Mogłabym przyspieszyć proces kompilacji z 15 sekund. do 6-7 sek. poprzez zmianę tej jednej linijki kodu:

// slow: 
// ... 
.flatMap((receivedObj: MyType) => { 
    let nextObservable: Observable<MySecondType> = this.dependingPut(receivedObj); 
    return nextObservable || new Observable((observer) => { 
      observer.next(undefined); 
     }); 
}); 


// fast: 
.flatMap((receivedObj: MyType) => { 
    let nextObservable: Observable<MySecondType> = this.dependingPut(receivedObj); 
    return nextObservable || new Observable<MySecondType>((observer) => { // <--- use the generics! 
      observer.next(undefined); 
     }); 
}); 

Z podręcznika maszynopis (https://www.typescriptlang.org/docs/handbook/generics.html):

function identity<T>(arg: T): T { 
    return arg; 
} 

// ... 

let output = identity("myString"); // type of output will be 'string' 

„Zauważ, że nie trzeba jawnie przekazać typ kąta wsporniki (<>), kompilator po prostu przyjrzał się wartości "myString", a ustawił T na jej typ. Podczas gdy argumentacja argumentów typu może być pomocnym narzędziem , aby kod był krótszy i bardziej czytelny, konieczne może być jawne Przekaż argumenty typu tak jak w poprzednim przykładzie, gdy kompilator nie może wywnioskować typu, co może się zdarzyć w bardziej złożonych przykładach . "

W moim przypadku nie zawiódł; wnioskowanie o typ zajęło bardzo dużo czasu (przy okazji, zużyło też mnóstwo pamięci). Przed rozpoczęciem tworzenia obejść należy wrócić do historii wersji i spróbować zidentyfikować złą wersję. Aby mieć pewność, że przyczyną problemu jest kompilator, użyj opcji --diagnostics. Jeśli zwrócone statystyki zwracają wysoką wartość "Sprawdź czas", sprawdź kod pod kątem brakujących typów.

1

Dla mnie spowolnienie spowodowane było przywozem, takim jak import "./file.ts";. Usunięcie rozszerzenia .ts powoduje, że rzeczy są o 90% szybsze: import "./file";