microsoft / microsoft/TypeScript

Investigate making the binding phase lazy

Offen
#35,120 3 Kommentare 11 Reaktionen 0 zugewiesene Personen Auf GitHub ansehen

Dieses Issue hat noch niemand übernommen.

Domain: Performance
Vorherrschende Sprache
Go
Sterne
111k
Forks
14.3k
Ø Merge
2 T. 4 Std.
Gemergte PRs (30 T.)
132

Beschreibung

Today, any semantic or language service operations must be preceded by a phase of our compiler called binding. This phase does two things:

  • creates symbol tables as well as symbols per scope
  • sets parent pointers (because it's already walking the tree anyhow)

However, this can end up being a of unnecessary up-front work. For type-checking a given file, the only files that need to be bound are

  • files that affect global namespaces (e.g. global files or files containing module augmentations, global augmentations, and UMD namespaces)
  • any file that needs to be checked to check the current file

Recently, I spent a bit of time on a plane ride wondering if we could do less work based on this. Instead of forcing all files to be bound, we could bind only global-affecting files up-front, and then force a bind prior to checking or resolving a given file. This has the advantage that something like quick info only needs to bind the minimal set of dependencies before coming back with an answer, making checking significantly lazier. It also means that skipLibCheck could end up working faster in command-line scenarios by binding fewer .d.ts files that are automatically included (e.g. why bind .d.ts files for Jest if you're compiling app code instead of test code?).

The flip side of this is that making this lazy can complicate a lot of other operations. Many language service operations don't actually care about binding, but they do care about parent pointers being set. They'll be preceded by a call to getTypeChecker() just to ensure files are bound before performing specific steps.

Yeah, I know, weird design!

The other issue is that certain type-checker APIs likely need to be guarded against to ensure a requested file is bound. I haven't dived deep here, so this is more of a speculative concern.

Finally, while laziness means that we can partially amortize each operation into incremental chunks of work, there's no telling when pulling on a thread of work will trigger TypeScript to do ALL of the work. Currently TypeScript does ALL the work up front, but that might be good for avoiding frustrating delays later on. For example, if not all files are bound yet, TypeScript can't immediately respond to go to symbol, find all references, or even some cases of get completions (thanks to auto-imports!) before ensuring every file is bound.

On the other hand, once that work gets done, it's done! Only re-parsed files need to be re-bound. So TypeScript might start out slow on some operations, warming up, and eventually staying hot going forward. There are also other possibilities of making this easier. For example, the services layer could also potentially bind unbound files in the background on idle time if it turned out we really needed to.

Beitragsleitfaden

Beitragsleitfaden öffnen

Erste Schritte

  1. Lies das ganze Issue und danach den Beitragsleitfaden des Projekts.
  2. Schreib ins Issue, dass du es übernimmst — das erspart doppelte Arbeit.
  3. Forke das Repository und arbeite in einem Branch.
  4. Öffne einen Pull Request, der die Issue-Nummer nennt.

Rechercherichtung

Beginne damit, die Binding-Phase des Compilers und die Aufrufstellen von getTypeChecker() nachzuverfolgen, und untersuche anschließend, wie language-service-Operationen Parent Pointer und Symbole anfordern. Als abgeschlossen gilt die Feststellung, ob Lazy Binding praktikabel ist, einschließlich der Frage, welche Operationen das Binding erzwingen müssen und wie sich inkrementelle oder Hintergrundarbeit verhalten würde; das Issue nennt keine bestimmten Tests oder Dateien.

Vom Indexierungsmodell aus dem Issue-Text verfasst.

Bewertung

Tech-Stack
typescript
Bereich
compilers
Issue-Typ
Refactoring
Schwierigkeit
5/5
Geschätzter Aufwand
Über eine Woche
Aktivitätsstatus
Veraltet
Klarheit
Muss geklärt werden
Anfängerfreundlichkeit
25/100

Neue Issues direkt in Ihr Postfach

Eine kurze Übersicht über anfängerfreundliche GitHub-Issues.