microsoft / microsoft/TypeScript

Feedback on Standard Decorators emit size

Open
#55,688 8 comments 0 reactions 0 assignees View on GitHub

Nobody has claimed this yet.

Discussion
Dominant language
Go
Stars
111k
Forks
14.3k
Avg merge
1d 19h
Merged PRs (30d)
117

Description

Acknowledgement
  • I acknowledge that issues using this template may be closed without further explanation at the maintainer's discretion.
Comment

This GitHub issue contains feedback on the Standard Decorators emit size from the Lit team.

Summary

It is difficult to recommend usage of Standard Decorators with the current JavaScript emit size.

Background

Lit supplies a set of decorators that reduce the amount of boilerplate code you need to write when defining a component.

For example, the material web button component implementation, uses Lit’s @property decorator to annotate a field that triggers a reactive update.

Measurement

The Material Web repository was used to test the emit size when using Standard Decorators. Note, this was done quite naively to get ballpark figures.

The following table has emitted JavaScript target as “es2022”, and no emitted JavaScript minification:

Name Size Gzipped Brotli
Total size (experimental decorators) 650.66 kB 172.29 kB 143.65 kB
Total size (standard decorators) 871.46 kB (+34%) 209.85 kB (+21.8) 175.98 kB (+22.5)

Results when minifying the emitted JavaScript with Terser:

Name Size Gzipped Brotli
Total (experimental decorators + terser) 444.92 kB 120.2 kB 102.12 kB
Total (standard decorators + terser) 520.09 kB (+16.9%) 145.61 kB (+21.1%) 123.78 kB (+21.2%)
Emit size of the Material Button implementation (without styles)

The material-web repository contains a lot of styles which are also emitted as JavaScript and incorporated in the numbers above. As a smaller benchmark, here is a single file which contains a single component.

Source code: https://github.com/material-components/material-web/blob/v1.0.0-pre.16/button/internal/button.ts

Name Size Gzipped
button.js (experimental decorators) 5.13 kB 1.66 kB
button.js (standard decorators) 10.8kB (+110%) 2.53 kB (+52%)

Contents of button.js with experimental decorators here: https://pastebin.com/TiiYSDye
Contents of button.js with standard decorators here: https://pastebin.com/2nfpYApy

Lit team's perspective

At the library level we can support both experimental and standard decorator APIs in the same decorator implementations. We've got a branch that works great with the type checker and at runtime. Philosophically we're aligned with standard decorators, and in the long run they're the obvious choice. But, the size increase when downleveling standard decorators makes them a performance footgun for users, one that will need to be a prominent part of the documentation of our decorators.

One solution we're evaluating is to add a decorators pass to our optimizing TypeScript compiler plugin. A library-specific optimization pass can take advantage of the specific semantics of known decorators to produce output at least as good as the experimental decorators pass. One downside of this approach however is that it can only optimize known decorators, and many users will use decorators from other libraries, and author their own. And, since this is a new compiler from us, no one uses it yet, and uptake may be slow and incomplete.

Contributor guide

Open the contributing guide

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

Research direction

Start by reproducing the Material Web and single-file benchmark described in the issue, comparing standard and experimental decorator output with and without Terser. The issue does not name a TypeScript source file or test, so trace the standard-decorator emit path from the compiler entry points. Done would mean reducing standard-decorator output size while preserving its semantics and validating the reported measurements.

Written by the indexing model from the issue text.

Assessment

Tech stack
javascript, typescript
Domain
compilers, performance
Issue type
Feature
Difficulty
5/5
Estimated time
Over a week
Activity status
Stale
Clarity
Needs clarification
Newbie friendliness
25/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.