2016-04-14 13 views
19

Sto indagando sul motivo per cui il tempo di compilazione per il mio progetto TypeScript Angular 2.0 è passato da circa 4 secondi a circa 15 secondi in un tempo relativamente breve.Investigare tempi di compilazione TypeScript lunghi

Mi sono imbattuto nello switch molto utile, ma apparentemente non documentato --diagnostics.

Per esempio, ecco cosa ottengo quando si esegue tsc --noEmit --diagnostics sul mio progetto ora:

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 

Ecco cosa ottengo quando faccio funzionare lo stesso comando su una versione precedente del progetto.

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 

Il numero di Types è andato verso l'alto, e così ha la Check time.

È possibile ottenere un output più dettagliato/dettagliato da --diagnostics?

NodeJS v4.4.3, TypeScript v1.8.10. Questo è il mio 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" 
    ] 
} 

risposta

0

Compiler è noto per essere lento, è possibile utilizzare il compilatore in modalità orologio tsc -w o passare a webpack e ts-loader che espongono transpileOnly opzione (non in termini di tempo controlli).

+0

Grazie. Usiamo 'gulp-typescript' (https://www.npmjs.com/package/gulp-typescript) per la ricerca di modifiche. Supporta la compilazione incrementale. Anche con la visione, ottengo costantemente da 12 a 18 secondi di build. Ma le build erano più veloci e non è stato aggiunto tanto codice e abbiamo appena iniziato. Qualcosa deve aver causato il problema, ma richiederebbe molto tempo per cercare commit-by-commit. –

+0

ho provato gulp-dattiloscritto e compilatore Intellij Idea integrato, ma era troppo lento, circa 8 secondi dopo ogni modifica, inaccettabile. Ora sto usando webpack e ts-loader con l'opzione transpileonly, il tempo di ricompilazione è di circa 0.5 secondi. – kemsky

13

Sembra che io abbia trovato il colpevole nel mio caso. L'ho fatto nel modo più duro; il mio processo:

  1. Trova il commit che ha rallentato la compilazione. Passare attraverso la cronologia commit-by-commit e controllare i tempi di compilazione.
  2. Commentare il codice modificato finché non vengono trovate le righe incriminate.

Prima del commit offensivo, ho ottenuto costantemente tempi di compilazione di circa 2-4 secondi, dopo il commit - 13-17 secondi.

Nel mio caso, ho una classe, con un campo accessTokenGetter, che è stato inizializzato nel costruttore:

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

La seconda parte dell'inizializzazione || (() => Observable.of(null)); stava causando la lentezza. Commentandolo o aggiungendo un'annotazione di tipo ha ottenuto il tempo di compilazione indietro. Poiché Observable è generico, sembra che il compilatore TypeScript abbia bisogno di un suggerimento per restringere alcuni controlli di tipo che deve eseguire. Il mio inizializzazione ora recita:

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

Observable.of(null as string)) sembra anche per fare il lavoro. Ci sono stati un paio di altri posti in cui aggiungere un'annotazione di tipo ha accelerato la compilazione.

Spero che questo aiuti qualcuno.

Ancora, se c'è una funzione nel compilatore per la risposta più veloce - sarei felice di sentirlo.

+0

Grazie, ho riscontrato lo stesso problema. Regola imparata per evitarlo: aggiungi annotazione del tipo quando possibile –

+0

Wow, questo è pazzesco. Sarebbe bello se ci fosse un modo automatico per rintracciare inferenze lente come queste. – bcherny

+1

È possibile trarre vantaggio da 'git bisect' con il tempo di compilazione come pivot/condizione. Ciò avrebbe richiesto solo pochi minuti per dividere i commit di 1000s. L'installazione è probabilmente inferiore a un'ora e potresti riutilizzarla per future ricerche – user3041539

0

Nel mio caso il tempo di compilazione era di circa 15-30 secondi. Dopo il comando tsc --noEmit --diagnostics ho notato che sto costruendo file 2k.Soluzione era quella di escludere tutti i file dalla cartella node_modules:

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

E 'una buona idea per escludere cartella typings troppo.

+0

Sì, d'accordo. Ma avevo già escluso entrambi quando ho iniziato ad avere il mio problema. Per quanto riguarda le tipizzazioni, non sono così sicuro - a seconda di come hai impostato il tuo progetto, cioè se non usi i riferimenti a tre barre ('///

3

Potrei accelerare il processo di compilazione da 15 sec. a 6-7 sec. modificando questa singola riga di codice:

// 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); 
     }); 
}); 

dal Manuale tipografico (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' 

"Si noti che non abbiamo avuto bisogno di passare in modo esplicito il tipo nell'angolo staffe (<>), il compilatore ha appena esaminato il valore "myString" e imposta T nel suo tipo. Mentre l'argomento di tipo inferenza può essere uno strumento utile per mantenere il codice più breve e più leggibile, potrebbe essere necessario esplicitamente passare gli argomenti di tipo come abbiamo fatto nell'esempio precedente quando il compilatore non riesce a dedurre il tipo, come può accadere in più complessi esempi. "

Nel mio caso non ha fallito; il tipo di inferenza ha impiegato molto tempo (tra l'altro, ha consumato anche molta memoria). Prima di iniziare a creare soluzioni alternative, tornare alla cronologia delle revisioni e provare a identificare la revisione errata. Per essere sicuri che il compilatore sia il colpevole, utilizzare l'opzione --diagnostics. Se le statistiche restituite restituiscono un valore "Check time" elevato, quindi controlla il tuo codice per i tipi mancanti.

1

Per me, i rallentamenti erano dovuti a importazioni come import "./file.ts";. La rimozione dell'estensione .ts rende le cose più veloci del 90%: import "./file";

Problemi correlati