Open8

Angular+TailwindのOptimizationメモ

lacolacolacolaco

どこにどう書かれたクラスが最適化時にどう扱われるかをまとめたい

lacolacolacolaco

テンプレートHTML

普通のclass属性

<div class="block">

普通にPurgeCSSに認識される。使用したクラスはグローバルCSSに残る

バインディング + 文字列リテラル

<div [class]="'block'">

PurgeCSSは ' もデリミタに含まれるので正しく認識される

バインディング + プロパティ参照

<div [class]="classStr">

export class AppComponent {
  classStr = 'block';
}

Tailwindの purge コンフィグの contentにtsファイルが含まれていれば正しく認識される。

  purge: {
    content: ['./apps/**/*.{html,ts}', './libs/**/*.{html,ts}'],
  },
lacolacolacolaco

ホストバインディング

host メタデータ + class 属性 + インライン

@Component({
  selector: 'app-root',
  templateUrl: './app.component.html',
  styleUrls: ['./app.component.scss'],
  host: {
    class: 'h-screen max-h-screen',
  },
})
export class AppComponent {}

認識された。デリミタ的に当然

host メタデータ + クラスバインディング

@Component({
  selector: 'app-root',
  templateUrl: './app.component.html',
  styleUrls: ['./app.component.scss'],
  host: {
    '[class.h-screen]': 'true',
  },
})
export class AppComponent {}

認識された

HostBinding + クラスバインディング

@Component({
  selector: 'app-root',
  templateUrl: './app.component.html',
  styleUrls: ['./app.component.scss'],
})
export class AppComponent {
  @HostBinding('class.h-screen') hScreen = true;
}

認識された

lacolacolacolaco

interpolationなど使った動的なクラス文字列生成は当然無理として、これ以外にクラスを指定する手段があれば検証したい

lacolacolacolaco

最適化メモ

コンポーネントスタイルとの併用について

  • *.component.css などで @apply を使うとビルド時に指定したクラスのスタイルがマージされる(インライン化される)
  • @apply でも参照され、テンプレートからもクラスとして参照されるとバイナリ的には重複が発生する
    • 重複した分だけトータルのCSSペイロードサイズが増える
  • @apply を使った構造化を行うならば、ビルド時の解決側に倒し切る(HTMLからは参照しない)ほうがバンドルサイズの観点からは望ましいか
    • とはいえ複数のコンポーネントが同じクラスをapplyするとそれぞれのコンポーネントスタイルにインライン化されるので、これもバンドルサイズ的には望ましくない。
      • 同一部分はある程度gzipなどの圧縮は効くだろうが...
    • ユーティリティクラスセットとスコープ化CSSの噛み合わせはあまりよくなさそう。
    • コンポーネントスタイルでのapplyの多用を防ぐためにも、Angular CLIのComponent Style Budgetと併用して防御しておくのがいいだろう
lacolacolacolaco

コンポーネントCSSと @apply について

大体ここに書いてある
https://tailwindcss.com/docs/extracting-components

  • やはりコンポーネントCSS内で @apply は避けるべきだろう
    • 複数のコンポーネントCSSにインライン化された同じスタイルがCSSサイズを肥大化する
  • 再利用可能にする単位はAngularコンポーネントにする
    • .btn クラスが欲しくなったということは ButtonComponent を作る時が来たということ
  • どうしても再利用可能なクラスセットを@apply で定義したい場合はグローバルCSS(styles.css )を使おう
  • Tailwindをがっつり使うプロジェクトではAngularが用意するコンポーネントCSSはほとんど使わないほうがスタイリングの情報源が一貫するだろう
    • 強いて言うなら :host { display: block;} 程度か
    • コンポーネントCSSを使うときには、Tailwindには依存せずピュアなCSSを書く