我看到了这个使用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)
这让我想知道,有没有一种方法可以在客户端生成所述css?网络带宽的节省难道不会超过生成css的(微小的(成本吗?
我找不到这样一个用例的例子,网络流量的压缩会让这变得无关紧要吗?
我不一定要专门问这个案子。更多关于带宽与计算时间的关系将被考虑在内(如果有的话(。js框架可以在客户端使用更简洁的语法(如Angular中的ngFor
(生成HTML。
Sass编译器是用C++编写的,所以在浏览器中运行它或多或少是不可能的。
相反,你可以使用Less,它在浏览器中运行得很好。
index.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>
多框阴影.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(',');
});
}
});
样式较少
@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;
}
对于您的具体示例:
- styles.css:41'277 B(压缩5'936 B(
- Styles.less:1'856 B(586 B压缩(
在控制台中,输出更少的生成时间,在我的计算机上,它需要100毫秒到200毫秒。
我认为在客户端进行编译的好处非常低。编译后的CSS比其源代码大是非常罕见的,这主要是因为CSS编译器缩小了它们的输出。
网络带宽的节省难道不会超过生成css的(微不足道的(成本吗?
反对这样做的一个可能的论点是,是的,与CSS相比,下载更小的SCSS文件可能会节省带宽,但也必须向客户端提供编译器代码,这(假设(超过了与CSS相比文件大小的差异。
在没有更好的例子的情况下,我以Yann的数字和LESS为例,假设一个假想的SCSS编译器会显示模拟行为:
对于您的特定示例:
-styles.css:41'277 B(5'936 B压缩(
-styles.less:1'856 B(586 B压缩(
- less.min.js:167'812 B
除非浏览器预先配备了SCSS编译器,否则首先会质疑CSS文件类型的必要性。
正如@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));
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>
正如您所看到的,我使用CSS自定义属性将生成的box-shadow
值传递给CSS,这样我也可以在伪元素中使用它。如果您不喜欢使用CSS变量,可以使用6个<div>
s而不是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);
此外,如果动画本身的性能不够好,您可能会很容易地调整此代码,以便在<canvas>
上绘制起点(实际上是圆形或正方形(,并使用Window.requestAnimationFrame()
对其进行动画处理。