在客户端编译 scss 以保存在网络上

O. *_*sti 5 css compilation sass client-side-scripting network-traffic

我已经看到了这个使用 css 制作动画星星背景的例子,并注意到在这种情况下编译的 css 明显更小,因为 sass 在循环中生成了一千颗星星。

// 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)
Run Code Online (Sandbox Code Playgroud)

这让我想知道,有没有办法在客户端生成上述 css?网络带宽的节省会不会超过生成 css 的(微乎其微的)成本?

我找不到这种用例的示例,网络流量的压缩是否使这无关紧要?

我不一定要专门询问这个案例。更多关于带宽与计算时间的考虑(如果有的话)。对于ngFor在客户端使用更简洁的语法(如在 Angular 中)生成 HTML 的 js 框架,也可以这样说。

Yan*_*lin 6

Sass 编译器是用 C++ 编写的,因此在浏览器中运行它或多或少是不可能的。

相反,您可以使用Less,它在浏览器中运行良好。

索引.html

<link rel="stylesheet/less" type="text/css" href="styles.less" />
<script src="//cdnjs.cloudflare.com/ajax/libs/less.js/3.9.0/less.min.js" ></script>
Run Code Online (Sandbox Code Playgroud)

多盒shadow.js

(需要这个插件,因为Less不能自己生成随机数)

registerPlugin({
  install: function(less, pluginManager, functions) {
      functions.add('multiple-box-shadow', function(n) {
          return Array(n.value).fill().map(function() {
              var x = Math.floor(Math.random()*2000);
              var y = Math.floor(Math.random()*2000);
              return x+'px '+y+'px #FFF';
          }).join(',');
      });
  }
});
Run Code Online (Sandbox Code Playgroud)

无样式

@plugin "multiple-box-shadow";

@shadows-small:  multiple-box-shadow(700);
@shadows-medium: multiple-box-shadow(200);
@shadows-big:    multiple-box-shadow(100);

#stars {
    width: 1px;
    height: 1px;
    background: transparent;
    box-shadow: @shadows-big;
    animation: animStar 50s linear infinite;
}
Run Code Online (Sandbox Code Playgroud)

对于您的具体示例:

  • style.css: 41'277 B (5'936 B 压缩)
  • styels.less:1'856 B(压缩后 586 B)

在控制台中,较少的输出生成时间,在我的电脑上需要 100 到 200 毫秒。

我认为在客户端编译的好处非常低。编译后的 CSS 比其源代码大的情况非常罕见,主要是因为 CSS 编译器会缩小其输出。


Dan*_*ger 3

正如 @onewaveadrian 所指出的,尝试通过在浏览器上生成 CSS 来节省一些字节,然后下载 SCSS 或 LESS 编译器来这样做是没有意义的。

然而,您可以在浏览器上仅使用普通 JS 来生成这些 CSS 阴影,而不包含任何额外的依赖项,这将节省大量字节,并且可能比成熟的编译器运行得更快。

为了使其更快,该multipleBoxShadow函数使用简单的while循环、字符串连接按位 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));
Run Code Online (Sandbox Code Playgroud)
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);
  }
}
Run Code Online (Sandbox Code Playgroud)
<div id='stars'></div>
<div id='stars2'></div>
<div id='stars3'></div>
Run Code Online (Sandbox Code Playgroud)

正如您所看到的,我使用CSS 自定义属性将生成的值传递box-shadow给 CSS,以便我也可以在伪元素中使用它。如果您不想使用 CSS 变量,可以使用 6<div>而不是 3 并使用该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);
Run Code Online (Sandbox Code Playgroud)

另外,如果动画本身的性能不够好,您可能可以轻松地调整此代码以在 a 上绘制开始(实际上是圆形或正方形)<canvas>,并使用Window.requestAnimationFrame().