惯性聚合 高效追踪和阅读你感兴趣的博客、新闻、科技资讯
阅读原文 在惯性聚合中打开

推荐订阅源

爱范儿
爱范儿
Forbes - Security
Forbes - Security
Help Net Security
Help Net Security
cs.CV updates on arXiv.org
cs.CV updates on arXiv.org
Hacker News: Ask HN
Hacker News: Ask HN
TaoSecurity Blog
TaoSecurity Blog
IT之家
IT之家
Microsoft Azure Blog
Microsoft Azure Blog
云风的 BLOG
云风的 BLOG
博客园 - 司徒正美
B
Blog
阮一峰的网络日志
阮一峰的网络日志
H
Hackread – Cybersecurity News, Data Breaches, AI and More
Google DeepMind News
Google DeepMind News
Microsoft Security Blog
Microsoft Security Blog
The Register - Security
The Register - Security
美团技术团队
C
CERT Recently Published Vulnerability Notes
I
Intezer
C
Cybersecurity and Infrastructure Security Agency CISA
Google Online Security Blog
Google Online Security Blog
B
Blog RSS Feed
PCI Perspectives
PCI Perspectives
C
Cyber Attacks, Cyber Crime and Cyber Security
Threat Intelligence Blog | Flashpoint
Threat Intelligence Blog | Flashpoint
MyScale Blog
MyScale Blog
S
Securelist
Recorded Future
Recorded Future
Know Your Adversary
Know Your Adversary
Security Archives - TechRepublic
Security Archives - TechRepublic
M
MIT News - Artificial intelligence
C
Check Point Blog
T
Threat Research - Cisco Blogs
博客园 - Franky
P
Proofpoint News Feed
人人都是产品经理
人人都是产品经理
U
Unit 42
F
Fortinet All Blogs
S
Security @ Cisco Blogs
The GitHub Blog
The GitHub Blog
Apple Machine Learning Research
Apple Machine Learning Research
MongoDB | Blog
MongoDB | Blog
The Hacker News
The Hacker News
酷 壳 – CoolShell
酷 壳 – CoolShell
F
Full Disclosure
aimingoo的专栏
aimingoo的专栏
大猫的无限游戏
大猫的无限游戏
D
Docker
让小产品的独立变现更简单 - ezindie.com
让小产品的独立变现更简单 - ezindie.com
L
LINUX DO - 热门话题

BlogFinder

日常漫步 Vol.24 之漫步前山河 - 雅余 周报 #1-聊聊本周的收获 - Edwin's Blog 我的OpenCode必装插件与Skill Write Something 掌中之物未必在掌握之中 · CRIVU PiliNara,一个更顺手的 PiliPlus 分支 「NekoEcho」:做一个必有回响的猫娘主题博客 2026-05 书影音总结 简化博客主题 - 安迪 我第一次发布 npm 包 拾花小记#45:中考前的二三事 – 小改学习志 黛西花园5月游 #18 枇杷又熟了的五月月报 一些奇奇怪怪的需求?word仿方正书版的几个小操作 - Xiobb's Blog 0419 御温泉之旅 修复了一些bug,网站基本上趋于稳定了 - 新锐博客 又回到四十年前 如何定义成功 迷鹿屋2026已重新上线 科技冰火两重天+一周回顾 ${title} 热度退了,我反而用得更深了-咕咚同学 我到底该不该换个域名? 随身WIFI折腾记 - 安迪 博客撰写体验提升——hexo pro插件 为什么不用相机把屏幕上的接关密码拍下来? 国清寺与天台山 – Ouroboros ★★★★☆《挽救计划》——久违的经济上行感 - Davidの3号基地 删除右键“打开方式”里多余选项 第三周刊_No.53|一切都会被支付两次 安卓APP通话记录与录音上传踩坑记录 - 子舒的博客 天量下跌 inBox 笔记 2.3.8,把工具栏交给了你-咕咚同学 我把小龙虾搬到了微信-咕咚同学 安好 - 响石潭 Compound Engineering Plugin:让每个工程单元都比上一个更容易 MOSS-TTS Family:开源高质量语音与声音生成模型家族深度解析 Crawl4AI:专为 LLM 设计的开源 Web 爬虫与数据抓取工具 Build Your Own X:从零实现你最喜欢的技术——程序员进阶的终极资源清单 Anthropic Skills:用文件夹教 Claude 专业技能的开源框架 1年的去月球(下) - 梅之夏 欢迎回来。 简单讲讲 ASN.1 与 OID DTV - 直播聚合客户端 5.22-5.27 – 不兴江 还没去过鸭川 – 不兴江 张晶晶同学三刷林志颖 关于我 – 不兴江 爱与嫉妒 – 不兴江 港股被持续做空 备案码花了四百块-咕咚同学 一句话生成封面:我给公众号做了4种风格的AI封面生成技能 「官」方認證 再谈费曼学习法 2026-05-28T00:34:11+08:00 2026-05-28T00:28:45+08:00 离谱的英语学习指南:基于AI的英语进阶系统方法论 iii:零集成架构的后端统一运行时 Claude Code Harness:让 Claude Code 工作有迹可循的工程化框架 Heretic:全自动移除大语言模型审查机制的开源工具 MarkItDown:微软开源的万能文档转 Markdown 利器 Harness:让 Claude Code 秒变多智能体协作工厂 这段时间尽折腾AI Agent了,确实极大地提高了效率 近期动态:两个新站点正式上线啦 误判解除!zhouayuan.com 腾讯安全申诉成功 - 周阿源|玩具设计・插画日常・生活随笔 Ralph:让 AI 编码工具自主循环跑完所有 PRD 任务的量产神器 全都违法 – 个人工作记录 关于zhouayuan.com被误判 “含违规信息” 的说明与申诉记录 - 周阿源|玩具设计・插画日常・生活随笔 小米 MiMo v2.5 Pro 白嫖 最大的人间清醒,兜里有钱,但是不花。 夜晚靓歌(12):于文文现场solo - 王志勇的Blog 今日插画:风扬起的倔强 - 周阿源|玩具设计・插画日常・生活随笔 回门习俗 独立网卡 - 忘记了回忆 500亿入股人工智能企业 从命令行到桌面智能体-咕咚同学 第一性原理读书笔记 行者微评论223-加班の守株待兔-博客|政治与时事-风雨行者 ZOZO开源物理接触求解器:GPU加速的可扩展仿真引擎 OpenStock:开源股票市场交易平台技术深度解析 MoneyPrinterTurbo:基于AI的全自动短视频生成工具深度解析 Claude-Mem:为 Claude Code 构建的持久化记忆压缩系统 Twenty:可代码化定制的企业级开源 CRM 平台技术深度解析 2026-05-26T22:59:17+08:00 企业级开源大模型部署平台 GPUStack 实战教程 1年的去月球(上) - 梅之夏 Sevalla - 静态网站托管服务 不用翻墙、不用注册、不用月费,普通人也能用上 Claude Code 装修灯具要注意⚠️ 黄梅天先锋 - 游子微博 公安备案顺利办结,站点备案全部完成 - 周阿源|玩具设计・插画日常・生活随笔 第三次兑换天猫超市卡了宗宗酱-三维狐少儿编程 Don't think, feel. - Rolen's Blog 人这一辈子,到底图个什么 博客迁移 - Edwin's Blog 情感赛道写作模板 再现本轮行情的典型特征 裁员与平常心-咕咚同学 别让“偷懒”,成为隐私泄露的破绽 片刻 - Jdeal | Life is like a Design.
d3-force-3d 构建时预计算 3D 网络布局,减少客户端渲染压力 | 姓王者的博客
作者:xingwangzhe · 2026-06-28 · via BlogFinder

🕒 阅读时间:4 分钟📝 字数:1237👀 阅读量:Loading...

前言

友链图谱 是一个汇聚了 1600+ 节点2200+ 连接的 3D 友链网络可视化项目。数据源是 links/*.yml 文件,渲染层基于 3d-force-graph(Three.js + d3-force-3d)。

上一篇文章中,我介绍了友链图谱从 2D 升级到 3D 的整体架构——包括 3D 力导布局的数学原理、节点渲染和高亮系统。但那时的方案是:构建时只输出数据,客户端自行跑力导仿真

这个方案有两个痛点:

痛点 表现
加载慢 每次刷新都要从 [-5,5] 随机位置重新跑动画
hover 卡顿 每次悬停触发 Graph.refresh() → 遍历 1600 节点计算颜色
构建浪费 构建 2 秒完成,但客户端要跑 5-10 秒动画

声明:本文在撰写过程中使用了 AI 工具辅助分析技术资料、整理踩坑经验及润色排版。

思路:构建时预计算位置

「既然 d3-force-3d 在客户端跑,那在构建时(Node.js)也跑一遍不就提前拿到位置了吗?」

d3-force-3d 官方文档明确支持这种做法:

simulation.tick() — "This method can be used in conjunction with simulation.stop to compute a static force layout."

于是我在 Astro API 端点 graph.json.ts 中加入了构建时预计算:

import { forceSimulation, forceLink, forceManyBody, forceCenter } from "d3-force-3d";

const sim = forceSimulation(nodes, 3) // 明确 3 维!

.force(

"link",

forceLink(links)

.id((d) => d.id)

.distance(30),

)

.force("charge", forceManyBody().strength(-60))

.force("center", forceCenter(0, 0, 0)) // 默认 strength=1

.alphaDecay(0.02)

.velocityDecay(0.3);

for (let i = 0; i < 300; i++) sim.tick();

sim.stop();

客户端改成加载预计算位置,直接冻结:

.cooldownTicks(0)

.cooldownTime(0)

然而……事情没那么简单。

踩坑 1:平面坍塌

跑出来的效果:

X: std=635 范围 [-1780, 1594]

Y: std=523 范围 [-2107, 1317]

Z: std=141 范围 [-200, 200] ← 被压扁了!

3D ratio = 0.223 ⚠️ 扁平

Z 轴被压到只有 ±200,不管怎么调参数——distance=30 还是 40charge=-60 还是 -120alphaDecay=0.02 还是 0.005——Z 永远塌在初始半径以内。

原因forceCenter(0,0,0) 的默认强度是 1.0,而 charge 只有 -60link 只有 distance=30。center 力比其他力大了两个数量级,强行把所有节点往原点拉,Z 轴首当其冲被消解。

有趣的是,客户端渲染时同样的参数看起来却是"3D 网络"——因为客户端跑到 200 tick 就停了(cooldownTicks),还没收敛到平面,停在了一个好看的暂态。但构建时要的是一劳永逸,不能依赖"没跑完"。

踩坑 2:花哨尝试一一失败

方案 结果
forceRadial(800).strength(0.05) 强制球壳,不是网络
自定义 zBias 力(随机 Z 扰动) 被 alpha 衰减消解,Z 还是塌
去掉 forceCenter,只用 forceX/forceY 中心节点子节点形成圆盘
forceCenter.strength(0.3) 0.651,不够

每次调整都离目标差一点,走了很多弯路。

最终方案:三轴等强 + 弱居中

关键洞察是:不要对抗 forceCenter,而是把它减弱到和其他力一个量级

const sim = forceSimulation(nodes, 3)

.force(

"link",

forceLink(links)

.id((d) => d.id)

.distance(40),

)

.force("charge", forceManyBody().strength(-120))

.force("center", forceCenter(0, 0, 0).strength(0.02)) // ← 关键!

.alphaDecay(0.01)

.velocityDecay(0.4);

for (let i = 0; i < 500; i++) sim.tick();

sim.stop();

参数 作用
link.distance 40 连接节点间距
charge -120 排斥力(比默认强一倍)
center.strength 0.02 极弱居中,仅防漂移
alphaDecay 0.01 慢冷却,充分收敛
velocityDecay 0.4 与 3d-force-graph 默认对齐
tick 500 完全跑完

为什么 0.02 有效?

strength=0.02 意味着每 tick 所有节点只向中心移动 2% 的距离。这刚好抵消整体漂移,但完全不足以压倒 link 和 charge 力。三种力在同一个量级上互相平衡,自然形成 3D 散布。

结果:

X: std=478 范围 [-1288, 1265]

Y: std=312 范围 [-640, 1315]

Z: std=357 范围 [-1076, 802]

3D ratio = 0.747 ✅ 良好的 3D 网络

三轴散布均衡,没有平面、没有球壳、没有圆盘,是一个真正的体积网络(volumetric network)。

客户端配置

客户端直接加载预计算位置,不再跑额外仿真:

.graphData(graphData)

.warmupTicks(0)

.cooldownTicks(0)

.cooldownTime(0)

.d3AlphaDecay(0.02)

.d3VelocityDecay(0.3);

注意 linkcharge不能禁用d3Force(null)),否则 3d-force-graph 的连线渲染会丢失。只要 cooldownTicks(0),仿真在一 tick 后立即冻结,位置不会被挪动。

效果对比

指标 客户端渲染 构建时预计算
页面加载 等 5-10 秒动画 即开即用
构建时间 2 秒 20 秒(一次编译,永久使用)
hover 卡顿 有(Graph.refresh) 无(已优化)
3D 散布 暂态,依赖 timing 稳定
布局可复现 ❌ 每次随机 ✅ 固定(只要 seed 不变)

总结

构建时预计算 3D 力导布局完全可行,关键不是"要不要用 forceCenter",而是把 forceCenter 的强度降到和其他力一个量级

center.strength 结果
1.0 平面(center 主宰)
0.0 漂移(无约束)
0.02 3D 网络 ✅(三种力平衡)

项目仓库:xingwangzhe/FriendLinks — 欢迎 star 和 PR!

友链图谱在线体验:https://links.needhelp.icu/