• Stars
    star
    4,027
  • Rank 10,811 (Top 0.3 %)
  • Language
  • License
    MIT License
  • Created about 8 years ago
  • Updated over 1 year ago

Reviews

There are no reviews yet. Be the first to send feedback to the community and the maintainers!

Repository Details

⚡ Cheatsheet for developing lightning fast progressive Angular applications

Angular Performance Checklist

Introduction

This document contains a list of practices that will help us boost the performance of our Angular applications. "Angular Performance Checklist" covers different topics - from server-side pre-rendering and bundling of our applications to runtime performance and optimization of the change detection performed by the framework.

The document is divided into two main sections:

  • Network performance - lists practices that are going to improve mostly the load time of our application. They include methods for latency and bandwidth reduction.
  • Runtime performance - practices that improve the runtime performance of our application. They include mostly change detection and rendering related optimizations.

Some practices impact both categories so there could be a slight intersection, however, the differences in the use cases and the implications will be explicitly mentioned.

Most subsections list tools, related to the specific practice, that can make us more efficient by automating our development flow.

Note that most practices are valid for both HTTP/1.1 and HTTP/2. Practices which make an exception will be mentioned by specifying to which version of the protocol they could be applied.

Table of Content

Network performance

Some of the tools in this section are still in development and are subject to change. The Angular core team is working on automating the build process for our applications as much as possible so a lot of things will happen transparently.

Bundling

Bundling is a standard practice aiming to reduce the number of requests that the browser needs to perform in order to deliver the application requested by the user. In essence, the bundler receives as an input a list of entry points and produces one or more bundles. This way, the browser can get the entire application by performing only a few requests, instead of requesting each individual resource separately.

As your application grows bundling everything into a single large bundle would again be counterproductive. Explore Code Splitting techniques using Webpack.

Additional http requests will not be a concern with HTTP/2 because of the server push feature.

Tooling

Tools which allows us to bundle our applications efficiently are:

Resources

Minification and dead code elimination

These practices allow us to minimize the bandwidth consumption by reducing the payload of our application.

Tooling

  • Uglify - performs minification such as mangling variables, removal of comments & whitespace, dead code elimination, etc. Written completely in JavaScript, has plugins for all popular task runners.
  • Google Closure Compiler - performs similar to uglify type of minification. In advanced mode, it transforms the AST of our program aggressively in order to be able to perform even more sophisticated optimizations. It has also a JavaScript version that can be found here. GCC also supports most of the ES2015 modules syntax so it can perform tree-shaking.

Resources

Remove template whitespace

Although we don't see the whitespace character (a character matching the \s regex) it is still represented by bytes which are transferred over the network. If we reduce the whitespace from our templates to the minimum we will be respectively able to drop the bundle size of the AoT code even further.

Thankfully, we don't have to do this manually. The ComponentMetadata interface provides the property preserveWhitespaces which by default has value false meaning that by default the Angular compiler will trim whitespaces to further reduce the size of our application. In case we set the property to true Angular will preserve the whitespace.

Tree-shaking

For the final version of our applications, we usually don't use the entire code which is provided by Angular and/or any third-party library, even the one that we've written. Thanks to the static nature of the ES2015 modules, we're able to get rid of the code which is not referenced in our apps.

Example

// foo.js
export foo = () => 'foo';
export bar = () => 'bar';

// app.js
import { foo } from './foo';
console.log(foo());

Once we tree-shake and bundle app.js we'll get:

let foo = () => 'foo';
console.log(foo());

This means that the unused export bar will not be included into the final bundle.

Tooling

  • Webpack - provides efficient bundling by performing tree-shaking. Once the application has been bundled, it does not export the unused code so it can be safely considered as dead code and removed by Uglify.
  • Rollup - provides bundling by performing an efficient tree-shaking, taking advantage of the static nature of the ES2015 modules.
  • Google Closure Compiler - performs plenty of optimizations and provides bundling support. Originally written in Java, since recently it has also a JavaScript version that can be found here.

Note: GCC does not support export * yet, which is essential for building Angular applications because of the heavy usage of the "barrel" pattern.

Resources

Tree-Shakeable Providers

Since the release of Angular version 6, The angular team provided a new feature to allow services to be tree-shakeable, meaning that your services will not be included in the final bundle unless they're being used by other services or components. This can help reduce the bundle size by removing unused code from the bundle.

You can make your services tree-shakeable by using the providedIn attribute to define where the service should be initialized when using the @Injectable() decorator. Then you should remove it from the providers attribute of your NgModule declaration as well as its import statement as follows.

Before:

// app.module.ts
import { NgModule } from '@angular/core'
import { AppRoutingModule } from './app-routing.module'
import { AppComponent } from './app.component'
import { environment } from '../environments/environment'
import { MyService } from './app.service'

@NgModule({
  declarations: [
    AppComponent
  ],
  imports: [
    ...
  ],
  providers: [MyService],
  bootstrap: [AppComponent]
})
export class AppModule { }
// my-service.service.ts
import { Injectable } from '@angular/core'

@Injectable()
export class MyService { }

After:

// app.module.ts
import { NgModule } from '@angular/core'
import { AppRoutingModule } from './app-routing.module'
import { AppComponent } from './app.component'
import { environment } from '../environments/environment'

@NgModule({
  declarations: [
    AppComponent
  ],
  imports: [
    ...
  ],
  providers: [],
  bootstrap: [AppComponent]
})
export class AppModule { }
// my-service.service.ts
import { Injectable } from '@angular/core'

@Injectable({
  providedIn: 'root'
})
export class MyService { }

If MyService is not injected in any component/service, then it will not be included in the bundle.

Resources

Ahead-of-Time (AoT) Compilation

A challenge for the available in the wild tools (such as GCC, Rollup, etc.) are the HTML-like templates of the Angular components, which cannot be analyzed with their capabilities. This makes their tree-shaking support less efficient because they're not sure which directives are referenced within the templates. The AoT compiler transpiles the Angular HTML-like templates to JavaScript or TypeScript with ES2015 module imports. This way we are able to efficiently tree-shake during bundling and remove all the unused directives defined by Angular, third-party libraries or by ourselves.

Resources

Compression

Compression of the responses' payload standard practice for bandwidth usage reduction. By specifying the value of the header Accept-Encoding, the browser hints the server which compression algorithms are available on the client's machine. On the other hand, the server sets the value for the Content-Encoding header of the response in order to tell the browser which algorithm has been chosen for compressing the response.

Tooling

The tooling here is not Angular-specific and entirely depends on the web/application server that we're using. Typical compression algorithms are:

  • deflate - a data compression algorithm and associated file format that uses a combination of the LZ77 algorithm and Huffman coding.
  • brotli - a generic-purpose lossless compression algorithm that compresses data using a combination of a modern variant of the LZ77 algorithm, Huffman coding, and 2nd order context modeling, with a compression ratio comparable to the best currently available general-purpose compression methods. It is similar in speed with deflate but offers more dense compression.

Resources

Pre-fetching Resources

Resource pre-fetching is a great way to improve user experience. We can either pre-fetch assets (images, styles, modules intended to be loaded lazily, etc.) or data. There are different pre-fetching strategies but most of them depend on specifics of the application.

Lazy-Loading of Resources

In case the target application has a huge code base with hundreds of dependencies, the practices listed above may not help us reduce the bundle to a reasonable size (reasonable might be 100K or 2M, it again, completely depends on the business goals).

In such cases, a good solution might be to load some of the application's modules lazily. For instance, let's suppose we're building an e-commerce system. In this case, we might want to load the admin panel independently from the user-facing UI. Once the administrator has to add a new product we'd want to provide the UI required for that. This could be either only the "Add product page" or the entire admin panel, depending on our use case/business requirements.

Tooling

  • Webpack - allows asynchronous module loading.
  • ngx-quicklink - router preloading strategy which automatically downloads the lazy-loaded modules associated with all the visible links on the screen

Don't Lazy-Load the Default Route

Let's suppose we have the following routing configuration:

// Bad practice
const routes: Routes = [
  { path: '', redirectTo: '/dashboard', pathMatch: 'full' },
  { path: 'dashboard',  loadChildren: () => import('./dashboard.module').then(mod => mod.DashboardModule) },
  { path: 'heroes', loadChildren: () => import('./heroes.module').then(mod => mod.HeroesModule) }
];

The first time the user opens the application using the url: https://example.com/ they will be redirected to /dashboard which will trigger the lazy-route with path dashboard. In order Angular to render the bootstrap component of the module, it will has to download the file dashboard.module and all of its dependencies. Later, the file needs to be parsed by the JavaScript VM and evaluated.

Triggering extra HTTP requests and performing unnecessary computations during the initial page load is a bad practice since it slows down the initial page rendering. Consider declaring the default page route as non-lazy.

Caching

Caching is another common practice intending to speed-up our application by taking advantage of the heuristic that if one resource was recently been requested, it might be requested again in the near future.

For caching data we usually use a custom caching mechanism. For caching static assets, we can either use the standard browser caching or Service Workers with the CacheStorage API.

Use Application Shell

To make the perceived performance of your application faster, use an Application Shell.

The application shell is the minimum user interface that we show to the users in order to indicate them that the application will be delivered soon. For generating an application shell dynamically you can use Angular Universal with custom directives which conditionally show elements depending on the used rendering platform (i.e. hide everything except the App Shell when using platform-server).

Tooling

Resources

Use Service Workers

We can think of the Service Worker as an HTTP proxy which is located in the browser. All requests sent from the client are first intercepted by the Service Worker which can either handle them or pass them through the network.

You can add a Service Worker to your Angular project by running ng add @angular/pwa

Tooling

Resources

Runtime Optimizations

This section includes practices that can be applied in order to provide smoother user experience with 60 frames per second (fps).

Use enableProdMode

In development mode, Angular performs some extra checks in order to verify that performing change detection does not result in any additional changes to any of the bindings. This way the frameworks assures that the unidirectional data flow has been followed.

In order to disable these changes for production do not forget to invoke enableProdMode:

import { enableProdMode } from '@angular/core';

if (ENV === 'production') {
  enableProdMode();
}

Ahead-of-Time Compilation

AoT can be helpful not only for achieving more efficient bundling by performing tree-shaking, but also for improving the runtime performance of our applications. The alternative of AoT is Just-in-Time compilation (JiT) which is performed runtime, therefore we can reduce the amount of computations required for the rendering of our application by performing the compilation as part of our build process.

Tooling

Resources

Web Workers

The usual problem in the typical single-page application (SPA) is that our code is usually run in a single thread. This means that if we want to achieve smooth user experience with 60fps we have at most 16ms for execution between the individual frames are being rendered, otherwise, they'll drop by half.

In complex applications with a huge component tree, where the change detection needs to perform millions of checks each second it will not be hard to start dropping frames. Thanks to the Angular's agnosticism and being decoupled from DOM architecture, it's possible to run our entire application (including change detection) in a Web Worker and leave the main UI thread responsible only for rendering.

Tooling

  • The module which allows us to run our application in a Web Worker is supported by the core team. Examples of how it can be used can be found here.
  • Webpack Web Worker Loader - A Web Worker Loader for webpack.

Resources

Server-Side Rendering

A big issue of the traditional SPA is that they cannot be rendered until the entire JavaScript required for their initial rendering is available. This leads to two big problems:

  • Not all search engines are running the JavaScript associated with the page so they are not able to index the content of dynamic apps properly.
  • Poor user experience, since the user will see nothing more than a blank/loading screen until the JavaScript associated with the page is downloaded, parsed and executed.

Server-side rendering solves this issue by pre-rendering the requested page on the server and providing the markup of the rendered page during the initial page load.

Tooling

  • Angular Universal - Universal (isomorphic) JavaScript support for Angular.
  • Preboot - Library to help manage the transition of state (i.e. events, focus, data) from a server-generated web view to a client-generated web view.
  • Scully - Static site generator for Angular projects looking to embrace the JAMStack.

Resources

Change Detection

On each asynchronous event, Angular performs change detection over the entire component tree. Although the code which detects for changes is optimized for inline-caching, this still can be a heavy computation in complex applications. A way to improve the performance of the change detection is to not perform it for subtrees which are not supposed to be changed based on the recent actions.

ChangeDetectionStrategy.OnPush

The OnPush change detection strategy allows us to disable the change detection mechanism for subtrees of the component tree. By setting the change detection strategy to any component to the value ChangeDetectionStrategy.OnPush will make the change detection perform only when the component has received different inputs. Angular will consider inputs as different when it compares them with the previous inputs by reference, and the result of the reference check is false. In combination with immutable data structures, OnPush can bring great performance implications for such "pure" components.

Resources

Detaching the Change Detector

Another way of implementing a custom change detection mechanism is by detaching and reattaching the change detector (CD) for given a component. Once we detach the CD Angular will not perform check for the entire component subtree.

This practice is typically used when user actions or interactions with external services trigger the change detection more often than required. In such cases we may want to consider detaching the change detector and reattaching it only when performing change detection is required.

Run outside Angular

The Angular's change detection mechanism is being triggered thanks to zone.js. Zone.js monkey patches all asynchronous APIs in the browser and triggers the change detection at the end of the execution of any async callback. In rare cases, we may want the given code to be executed outside the context of the Angular Zone and thus, without running change detection mechanism. In such cases, we can use the method runOutsideAngular of the NgZone instance.

Example

In the snippet below, you can see an example for a component that uses this practice. When the _incrementPoints method is called the component will start incrementing the _points property every 10ms (by default). The incrementation will make the illusion of an animation. Since in this case, we don't want to trigger the change detection mechanism for the entire component tree, every 10ms, we can run _incrementPoints outside the context of the Angular's zone and update the DOM manually (see the points setter).

@Component({
  template: '<span #label></span>'
})
class PointAnimationComponent {

  @Input() duration = 1000;
  @Input() stepDuration = 10;
  @ViewChild('label') label: ElementRef;

  @Input() set points(val: number) {
    this._points = val;
    if (this.label) {
      this.label.nativeElement.innerText = this._pipe.transform(this.points, '1.0-0');
    }
  }
  get points() {
    return this._points;
  }

  private _incrementInterval: any;
  private _points: number = 0;

  constructor(private _ngZone: NgZone, private _pipe: DecimalPipe) {}

  ngOnChanges(changes: any) {
    const change = changes.points;
    if (!change) {
      return;
    }
    if (typeof change.previousValue !== 'number') {
      this.points = change.currentValue;
    } else {
      this.points = change.previousValue;
      this._ngZone.runOutsideAngular(() => {
        this._incrementPoints(change.currentValue);
      });
    }
  }

  private _incrementPoints(newVal: number) {
    const diff = newVal - this.points;
    const step = this.stepDuration * (diff / this.duration);
    const initialPoints = this.points;
    this._incrementInterval = setInterval(() => {
      let nextPoints = Math.ceil(initialPoints + diff);
      if (this.points >= nextPoints) {
        this.points = initialPoints + diff;
        clearInterval(this._incrementInterval);
      } else {
        this.points += step;
      }
    }, this.stepDuration);
  }
}

Warning: Use this practice very carefully only when you're sure what you are doing because if not used properly it can lead to an inconsistent state of the DOM. Also, note that the code above is not going to run in WebWorkers. In order to make it WebWorker-compatible, you need to set the label's value by using the Angular's renderer.

Coalescing event change detections

Angular uses zone.js to intercept events that occurred in the application and runs a change detection automatically. By default this happens when the microtask queue of the browser is empty, which in some cases may call redundant cycles. From v9, Angular provides a way to coalesce event change detections by turning ngZoneEventCoalescing on, i.e

platformBrowser()
  .bootstrapModule(AppModule, { ngZoneEventCoalescing: true });

The above configuration will schedule change detection with requestAnimationFrame, instead of plugging into the microtask queue, which will run checks less frequently and consume fewer computational cycles.

Warning: ngZoneEventCoalescing: true may break existing apps that relay on consistently running change detection.

Resources

Use pure pipes

As argument the @Pipe decorator accepts an object literal with the following format:

interface PipeMetadata {
  name: string;
  pure: boolean;
}

The pure flag indicates that the pipe is not dependent on any global state and does not produce side-effects. This means that the pipe will return the same output when invoked with the same input. This way Angular can cache the outputs for all the input parameters the pipe has been invoked with, and reuse them in order to not have to recompute them on each evaluation.

The default value of the pure property is true.

*ngFor directive

The *ngFor directive is used for rendering a collection.

Use trackBy option

By default *ngFor identifies object uniqueness by reference.

Which means when a developer breaks reference to object during updating item's content Angular treats it as removal of the old object and addition of the new object. This effects in destroying old DOM node in the list and adding new DOM node on its place.

The developer can provide a hint for angular how to identify object uniqueness: custom tracking function as the trackBy option for the *ngFor directive. The tracking function takes two arguments: index and item. Angular uses the value returned from the tracking function to track items identity. It is very common to use the ID of the particular record as the unique key.

Example

@Component({
  selector: 'yt-feed',
  template: `
  <h1>Your video feed</h1>
  <yt-player *ngFor="let video of feed; trackBy: trackById" [video]="video"></yt-player>
`
})
export class YtFeedComponent {
  feed = [
    {
      id: 3849, // note "id" field, we refer to it in "trackById" function
      title: "Angular in 60 minutes",
      url: "http://youtube.com/ng2-in-60-min",
      likes: "29345"
    },
    // ...
  ];

  trackById(index, item) {
    return item.id;
  }
}

Minimize DOM elements

Rendering the DOM elements is usually the most expensive operation when adding elements to the UI. The main work is usually caused by inserting the element into the DOM and applying the styles. If *ngFor renders a lot of elements, browsers (especially older ones) may slow down and need more time to finish rendering of all elements. This is not specific to Angular.

To reduce rendering time, try the following:

  • Apply virtual scrolling via CDK or ngx-virtual-scroller
  • Reducing the amount of DOM elements rendered in *ngFor section of your template. Usually, unneeded/unused DOM elements arise from extending the template again and again. Rethinking its structure probably makes things much easier.
  • Use ng-container where possible

Resources

Optimize template expressions

Angular executes template expressions after every change detection cycle. Change detection cycles are triggered by many asynchronous activities such as promise resolutions, http results, timer events, keypresses, and mouse moves.

Expressions should finish quickly or the user experience may drag, especially on slower devices. Consider caching values when their computation is expensive.

Resources

Conclusion

The list of practices will dynamically evolve over time with new/updated practices. In case you notice something missing or you think that any of the practices can be improved do not hesitate to fire an issue and/or a PR. For more information please take a look at the "Contributing" section below.

Contributing

In case you notice something missing, incomplete or incorrect, a pull request will be greatly appreciated. For discussion of practices that are not included in the document please open an issue.

License

MIT

More Repositories

1

javascript-algorithms

💻 JavaScript implementations of computer science algorithms
JavaScript
7,836
star
2

angularjs-style-guide

📚 Community-driven set of best practices for AngularJS application development
4,984
star
3

revive

🔥 ~6x faster, stricter, configurable, extensible, and beautiful drop-in replacement for golint
Go
4,764
star
4

angular-seed

🌱 [Deprecated] Extensible, reliable, modular, PWA ready starter project for Angular (2 and beyond) with statically typed build and AoT compilation
TypeScript
4,572
star
5

google-interview-preparation-problems

leetcode problems I solved to prepare for my Google interview.
JavaScript
3,124
star
6

codelyzer

Static analysis for Angular projects.
TypeScript
2,446
star
7

angularjs-in-patterns

AngularJS in patterns - this repository provides different look into AngularJS. It contains information where different design patterns are used inside the framework or any Angular application.
JavaScript
1,956
star
8

ngrev

Tool for reverse engineering of Angular applications
TypeScript
1,553
star
9

mk.js

Canvas implementation of basic fighting game which allows multiplayer over the network.
JavaScript
1,504
star
10

angular2-style-guide

[Deprecated] Community-driven set of best practices and style guidelines for Angular 2 application development
1,203
star
11

injection-js

Dependency injection library for JavaScript and TypeScript in 5.1K. It is an extraction of the Angular's ReflectiveInjector which means that it's well designed, feature complete, fast, reliable and well tested.
TypeScript
1,149
star
12

jscapture

Screen recording and capturing with pure client-side JavaScript.
JavaScript
797
star
13

tiny-compiler

A tiny evaluator and compiler of arithmetic expressions.
JavaScript
768
star
14

ngx-quicklink

Quicklink prefetching strategy for the Angular router
TypeScript
749
star
15

guess-next

🔮 Demo application showing the integration of Guess.js with Next.js
JavaScript
526
star
16

aspect.js

JavaScript library for aspect-oriented programming using modern syntax.
TypeScript
474
star
17

angular-webrtc

Demo for my blog post at http://goo.gl/LCOSsI
ApacheConf
307
star
18

switching-to-angular2

TypeScript
285
star
19

memo-decorator

Decorator which applies memoization to a method of a class.
TypeScript
256
star
20

js-vnc-demo-project

Demo project for the class Advanced JavaScript at the department mathematics and informatics in Sofia University.
JavaScript
186
star
21

is-esm

🌳 CLI tool which checks if a package is distributed in ECMAScript module format. Helps you reason if the package is tree-shakable.
JavaScript
184
star
22

angular-immutable

Simple directive, which allows binding to Immutable.js collections.
JavaScript
166
star
23

ngast

Parser for Angular projects.
TypeScript
164
star
24

angular-aop

Library for aspect-oriented programming with AngularJS.
JavaScript
161
star
25

tslint-angular

Recommended tslint configuration for Angular applications.
161
star
26

ngx-hover-preload

🖱 Preload Angular lazy-loaded routes on mouse over
TypeScript
160
star
27

mk-tfjs

Play MK.js with TensorFlow.js
JavaScript
156
star
28

ReactChat

WebRTC chat with ReactJS
JavaScript
153
star
29

ngworld

Generate a Minecraft/Christmas-like world out of an Angular application.
TypeScript
142
star
30

scalable-architecture-demo

TypeScript
134
star
31

github-contributors-list

Node.js script, which outputs all the contributors for given open GitHub project
JavaScript
133
star
32

ngresizable

Simple, tree-shakable, AoT, Universal and Web Worker friendly resizable component for Angular (2 and beyond).
TypeScript
117
star
33

angular2-hot-loader

[NOT MAINTAINED] Angular 2 hot loader
TypeScript
115
star
34

light-angularjs

Light AngularJS implementation for my slides "Lightweight AngularJS"
JavaScript
110
star
35

movement.js

Gesture recognition with JavaScript and HTML5.
JavaScript
106
star
36

angular-vnc

VNC client implemented with AngularJS and Yeoman
JavaScript
99
star
37

ngx-tfjs

🤖 TensorFlow.js bindings for Angular
TypeScript
95
star
38

real-world-bazel

The real world Angular example app moved to Bazel
TypeScript
90
star
39

angular-transitions

Pre-defined set of CSS3 transformation which can be used with ng-view, ui-view, ng-repeat, ng-show, ng-hide. Both the 1.1.5 and 1.2.0 APIs are supported.
CSS
90
star
40

angular-tfjs-demo

A demo application with TensorFlow.js bindings for Angular.
TypeScript
85
star
41

angular2-ngc-rollup-build

Simple build for "Hello world!" Angular 2 application with ngc and rollup.
HTML
81
star
42

angular2-github-app-bootstrap

Exercise for building simple Angular 2 apps
JavaScript
79
star
43

blog.mgechev.com

My personal blog.
JavaScript
70
star
44

dotfiles

My dot files.
Shell
67
star
45

react-reorderable

Simple react sortable component (for more advanced cases use react-dnd).
JavaScript
63
star
46

devtools-vnc

VNC client for Chrome Devtools
JavaScript
61
star
47

cli-builders-demo

Demo showing how to develop a builder using the Angular CLI Architect API.
TypeScript
59
star
48

ngx-flamegraph

Flame graph for stack trace visualization written in Angular
TypeScript
57
star
49

electron-typescript-boilerplate

Electron TypeScript starter (intended mostly for personal projects). Fork of https://github.com/szwacz/electron-boilerplate.
JavaScript
54
star
50

angular-ivy-demo

Demo repository showing how ivy allows significant API simplification.
TypeScript
53
star
51

mlx

Data-driven bundling
TypeScript
48
star
52

optimizing-an-angular-application

Code for my ngconf talk "Optimizing an Angular Application".
TypeScript
48
star
53

ngx-gh

Automatic deployments to GitHub pages directly from the Angular CLI 🚀
TypeScript
45
star
54

data-adapter

Data adapter useful in data serialization when talking with external services.
TypeScript
45
star
55

react-pstate

Persistence of the state of ReactJS component
JavaScript
43
star
56

hybrid-rendering

TypeScript
42
star
57

playground

Initial experience with different programming languages
JavaScript
40
star
58

bazel-demo

Simple demo for building a TypeScript project with Bazel.
TypeScript
40
star
59

angular-hybrid-rendering

TypeScript
39
star
60

plainvm

plainvm allows you to control multiple virtual machines which are distributed among many hosts through your browser.
JavaScript
38
star
61

gemini-angular-drawing-demo

TypeScript
38
star
62

angular2-simple-build

Simple build for "Hello world!" Angular 2 application.
TypeScript
37
star
63

versionable-collections

Collection optimized for AngularJS 1.x one-way bindings
JavaScript
33
star
64

typed-calc

Interpreter for simply typed lambda calculus implemented in JavaScript λ
JavaScript
33
star
65

ngx-circular-player

Circular player for Angular
TypeScript
32
star
66

swagger-typescript-fetch-api

Swagger codegen for TypeScript Fetch API.
HTML
32
star
67

angular2-stripe-demo

TypeScript
30
star
68

blobreader

Simple interface for reading blobs sequentially
JavaScript
28
star
69

ts-rpc

RPC protocol with services defined via TypeScript interfaces.
TypeScript
27
star
70

performance-patterns

TypeScript
27
star
71

podcast

Website of the Programming Podcast
TypeScript
26
star
72

dots

Implements the wildcard file matching in Go used by golint, go test etc.
Go
25
star
73

ng-tutorial

Platform for AngularJS interactive tutorials
JavaScript
25
star
74

purely-fast

TypeScript
25
star
75

ELang

Simple programming language created for educational purpose
Java
24
star
76

gently-js

Module which returns the offensive words in a string. A soft reminder to be nicer to each other ❤️.
JavaScript
23
star
77

angular-realworld-example-app-qucklink

TypeScript
22
star
78

optimizing-apps-angular-demo

Demo application for my talk on optimizing Angular apps
TypeScript
21
star
79

ngmigrate

Automated migration of <template> to <ng-template> for Angular 4+
JavaScript
20
star
80

dynamic-route-creator

[DEPRECATED] Demo for dynamically defining routes in Angular 2
TypeScript
19
star
81

guess-js-angular-demo

TypeScript
18
star
82

lazy-loading-routes-angular2

WARNING: Uses deprecated APIs.
JavaScript
18
star
83

angular2-hot-loader-demo

Demo of the Angular 2 hot loader prototype
TypeScript
18
star
84

guess-js-react-demo

JavaScript
17
star
85

angular2-rollup-build

Simple build for "Hello world!" Angular 2 application with rollup.
HTML
17
star
86

getting-started-with-angular

Code for the second edition of the book "Switching to Angular 2", with title "Getting started with Angular".
TypeScript
17
star
87

svg-design-patterns

This repository contains UML class diagrams of some design and architectural patterns.
17
star
88

kitty-cinema

HTML
16
star
89

programming-podcast-samples

TypeScript
16
star
90

react-di-demo

Demo for my blog post "Implementing Angular's Dependency Injection in React. Understanding Element Injectors."
JavaScript
16
star
91

code-splitting-web-dev

TypeScript
15
star
92

react-drag

JavaScript
15
star
93

ivy-library-distribution-demo

TypeScript
14
star
94

angular-bazel-hello-world

Simple Angular app with Bazel configuration
HTML
13
star
95

viewchildren-contentchildren-demo

TypeScript
12
star
96

photos.mgechev.com

Website for my personal photography.
TypeScript
12
star
97

top-packages

TypeScript
12
star
98

v8-sorting-test

Testing the sorting performance of Google's V8 JavaScript engine.
Perl
12
star
99

immutable-differ

Work in progress.
TypeScript
11
star
100

guess-angular

TypeScript
11
star