Open8

Angular+TailwindのOptimizationメモ

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

テンプレート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}'],
  },

クラスバインディング

<div [class.block]="true">

認識された。

クラスバインディング(Key-Value)

<div [class]="{ block: true }">

https://github.com/tailwindlabs/tailwindcss/blob/master/src/lib/purgeUnusedStyles.js#L27

: がデリミタに含まれるのでこれは block が認識される

クラスバインディング(配列)

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

これもクォートで囲まれていれば認識される

ホストバインディング

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

認識された

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

最適化メモ

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

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

コンポーネント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を書く
ログインするとコメントできます