首页的星海最初有六万个粒子。它们在屏幕上翻滚,像一场过度热情的烟火。性能测试的结果不算差,但阅读标题时,我总觉得有什么东西在抢话。
后来我把数量降到九千,去掉镜头光晕,只留下三条缓慢旋转的旋臂。星海终于安静下来,开始像一片背景,而不是一场表演。
粒子不是越多越好
粒子系统的密度应该服务于叙事。这里的主角是文字,星海只需要提供一种“深空”的空间感。因此我让中心更亮、边缘更疏,并用颜色区分温度:核心偏暖,中段是极光绿,外圈过渡到暮蓝。
const geometry = new THREE.BufferGeometry();
geometry.setAttribute('position', new THREE.BufferAttribute(positions, 3));
geometry.setAttribute('aColor', new THREE.BufferAttribute(colors, 3));
const material = new THREE.ShaderMaterial({
uniforms: { uTime: { value: 0 }, uPixelRatio: { value: ratio } },
vertexShader,
fragmentShader,
transparent: true,
blending: THREE.AdditiveBlending,
depthWrite: false
});
让动效学会安静
鼠标视差被限制在很小的幅度,滚动时星海不会跟着疯狂位移。系统开启“减少动态效果”时,场景只渲染一帧静态画面,随后停止动画循环。
这不是技术上的妥协,而是设计上的礼貌。不是每个人都能忍受持续运动的背景,阅读也不应该以眩晕为代价。
好的动效应该像呼吸:你注意到它时,它已经发生了。
性能预算也是设计预算
整个场景打包后约 530KB,只在首页加载,并在离开视口时暂停渲染。移动端减少粒子数量、限制像素比。首屏文字永远先于画布出现,即使 WebGL 不可用,渐变背景也能完成叙事。
最后留下的不是一段炫技代码,而是一种节奏:星海缓慢旋转,文字保持不动,读者可以随时离开,也可以随时回来。



原来粒子数量减少之后反而更有空间感。作为读者,确实更容易把注意力放在标题上了。