web-dev-qa-db-ja.com

ネットワーク上に保存するためにクライアント側でscssをコンパイルする

私は この例 を使用してcssを使用したアニメーションの星の背景を確認しましたが、sassがループで1000の星を生成するため、この場合、コンパイルされたcssは大幅に小さくなっています。

// n is number of stars required
@function multiple-box-shadow ($n) 
  $value: '#{random(2000)}px #{random(2000)}px #FFF'
  @for $i from 2 through $n
    $value: '#{$value} , #{random(2000)}px #{random(2000)}px #FFF'

  @return unquote($value)

それは私に不思議に思いました、クライアント側で言ったCSSを生成する方法はありますか?ネットワーク帯域幅の節約は、CSSを生成する(最小限の)コストを上回らないのでしょうか。

このようなユースケースの例を見つけることができませんでしたが、ネットワークトラフィックの圧縮はこれを無関係にしていますか?

私は必ずしもこのケースについて具体的に尋ねているわけではありません。帯域幅と計算時間の関係が考慮されます(もしあれば)。クライアント側でより簡潔な構文(AngularのngForなど)を使用してHTMLを生成する方法を備えたjsフレームワークについても、同じことが言えます。

5
O. Aroesti

@onewaveadrianが指摘したように、ブラウザでCSSを生成してバイト数を節約しようとしても、代わりにSCSSまたはLESSコンパイラをダウンロードするのは意味がありません。

ただし、追加の依存関係を含めることなく、ブラウザーでバニラJSのみを使用してこれらのCSSシャドウを生成できます。これにより、大量のバイトが節約され、おそらく完全なコンパイラーよりも高速に実行されます。

さらに高速にするために、multipleBoxShadow関数は単純なwhileループ、 string concatenationbitwise OR演算子 (_|_) Math.floor() よりもはるかに高速にフロア番号に.

_const MAX_Y_OFFSET = 2000;
const MAX_X = window.innerWidth;
const MAX_Y = window.innerHeight + MAX_Y_OFFSET;

function multipleBoxShadow(n) {
  let boxShadow = '';
  
  // Let's use a simple while loop and the bitwise OR operator (`|`) to round up values here
  // to run this as fast as possible:
  while (n--) {
    boxShadow += `,${ Math.random() * MAX_X | 0 }px ${ Math.random() * MAX_Y | 0 }px #FFF`;
  }
  
  return boxShadow.slice(1);
}

const { documentElement } = document;

documentElement.style.setProperty('--shadows-small', multipleBoxShadow(700));
documentElement.style.setProperty('--shadows-medium', multipleBoxShadow(200));
documentElement.style.setProperty('--shadows-big', multipleBoxShadow(100));_
_body {
  min-height: 100vh;
  background: radial-gradient(ellipse at bottom, #1b2735 0%, #090a0f 100%);
  overflow: hidden;
}

#stars {
  width: 1px;
  height: 1px;
  background: transparent;
  animation: animStar 50s linear infinite;
  box-shadow: var(--shadows-small);
}

#stars:after {
  content: " ";
  position: absolute;
  top: 2000px;
  width: 1px;
  height: 1px;
  background: transparent;
  box-shadow: var(--shadows-small);
}

#stars2 {
  width: 2px;
  height: 2px;
  background: transparent;
  animation: animStar 100s linear infinite;
  box-shadow: var(--shadows-medium);
}

#stars2:after {
  content: " ";
  position: absolute;
  top: 2000px;
  width: 2px;
  height: 2px;
  background: transparent;
  box-shadow: var(--shadows-medium);
}

#stars3 {
  width: 3px;
  height: 3px;
  background: transparent;
  animation: animStar 150s linear infinite;
  box-shadow: var(--shadows-big);
}

#stars3:after {
  content: " ";
  position: absolute;
  top: 2000px;
  width: 3px;
  height: 3px;
  background: transparent;
  box-shadow: var(--shadows-big);
}

@keyframes animStar {
  from {
    transform: translateY(0px);
  }
  to {
    transform: translateY(-2000px);
  }
}_
_<div id='stars'></div>
<div id='stars2'></div>
<div id='stars3'></div>_

ご覧のとおり、生成された_box-shadow_値をCSSに渡すために CSSカスタムプロパティ を使用しているため、疑似要素でも使用できます。 CSS変数を使用したくない場合は、3ではなく6 _<div>_ sを使用し、style属性を次のように使用できます。

_document.getElementById('stars').style.boxShadow = multipleBoxShadow(700);
document.getElementById('stars2').style.boxShadow = multipleBoxShadow(700);
document.getElementById('stars3').style.boxShadow = multipleBoxShadow(200);
document.getElementById('stars4').style.boxShadow = multipleBoxShadow(200);
document.getElementById('stars5').style.boxShadow = multipleBoxShadow(100);
document.getElementById('stars6').style.boxShadow = multipleBoxShadow(100);
_

また、アニメーション自体のパフォーマンスが十分でない場合は、このコードを簡単に調整して、代わりに_<canvas>_で開始(実際には円または四角)を描画し、 Window.requestAnimationFrame()

2
Danziger