游牧周记第48期
标签 Tags
陈志
影视
近期没啥好的剧...电影就看了一站再战,科恩兄弟加昆汀的即视感,但内容节奏确实不错,2:44一点不觉得拖沓,全程精神十足(我可是看漫威都要睡着的人)。创作者似乎讽刺了所有方,其实没有明说自己的观点,现在要表态好难。

关注
硅谷101,以前听过他们的博客,但真的没有视频效果好。内容选题制作都很棒,算是中文同类频道的高水平。因为有很多嘉宾会话、现场采访,内容也需要图表啥的来配合,所以不适合纯音频。 (以前blog推荐过...不知为啥algolia搜不出来。)
思考
自学转码可行吗
某人的视频推荐:https://csdiy.wiki/。 其实是一本电子书,markdown做的网站,我看了它的技术是用Material for MkDocs, python的,算了。 项目在gitHub,我觉得可以当一个贡献者。 他最近的提法似乎和他之前提倡转码有点矛盾,因为不是科班出身始终在求职市场和行业中低人一等,这点没法回避甚至被强调,其实是非常实际的,经过的都懂。 我当年因为稀缺才进入这个行业,后来招人确实也以能力为准,后来人多了,想法也就有点变了。 但我深信这个行业是少数的非科班可以做得很好的领域,因为现在科班也学不到啥真本事(懂得都懂),主要是弯路走得少,以及意识和氛围带来的加成和优势。
有点像看麻瓜进入魔法行业的感觉,虽然也有赫敏这样的努力型人才。
颠覆导游解说行业的想法
方向是对的,但时机错过了
智能景点解说app都写到一半了,才想去来去看看微信小程序,人家不但成熟而且免费。 这件事给我几个启示:
- 自己的体验未必靠谱,出去玩了2年,都没想过看看现成产品和服务?
- 这么多产品了,说明这不是一个伪需求。
- AI的市场分析有时很不靠谱,覆盖面很窄。
- 不要只关注App,我总是忘了国内环境要看微信小程序。
- 巅峰一个行业的想法,方向是对的,格局也是对的,这样才能让人有持续目标和动力。
- 自己也想用才做,这点至少在动力和产品研究层面是对的。 不管怎么说,我写了一周代码的这个玩意,先停下来。 至少其中的ai和树形结构部分是可以复用的,还 不错。
开发
松耦合多项目共享资源的前端开发
我想同步开发“学易”的网站(nextjs)和app(expo),其中有很多共享资源。 目标是尽量降低耦合度,各自开发特性和流程不变,极其灵活。 同时大量的资源如多语言,style常数,环境变量等共享,并同步更新。 现在拿下一个版本的学易来做实验。 新建一个目录yi,在其下建立一个目录share,放locale,style,assets等资源。 在根目录下执行expo和next的新建项目命令。 开发时,还是进入yi目录,打开ide。 但测试运行时,要cd进入具体的app目录,执行pnpm dev等。 vercel的部署就不靠github了,免得修改mobile app时被误触发,这次使用vercel cli。
后来我放弃了。
新的策略:
- npmjs包,包含多语言,常量,utils。
- 大量的json数据改用云数据库。
nextjs的双层缓存技巧
目标是既要控制内部调用量,又要限制对外(supabase)调用频率。 一句话就是限制网站内外部对网站api的调用频率。
- 内部调用api缓存
try {
	const response = await fetch(`${PUBLIC_ENV.BASE_URL}/api/hg/by-hgi/${hgi}?lang=${lang}`, {
	next: {
		revalidate: REVALIDATE_SECONDS // 一小时
	}
	});
	// ...
但此措施仅限制了网站UI发起的访问频率。 如果有人(包括app)直接调用api呢。
- api route的缓存设计 route.ts文件中加入两行。
// 缓存,Next.js 15 自带「段级缓存」——给路由加一条导出即可
export const dynamic = 'force-static';
export const revalidate = 86400; // 一天
就可以实现了,太神奇。
- 第 1 次访问:走 Supabase,结果自动被 Next.js 缓存到 内存 + CDN(Vercel)。
- 缓存时间内再访问:直接返回缓存,0 数据库查询。
- 缓存时间后:后台静默重新拉取,用户无感知(stale-while-revalidate)。 这是目前 Next.js 里最零成本的接口缓存方案。
整体看来,缓存生效逻辑:
- 首次请求:
- fetch缓存:未命中 → 调用API
- API路由:未命中 → 查询Supabase
- 结果:两层都存储缓存
- 1小时内的请求:
- fetch缓存:命中 ✅ → 直接返回
- API路由不会被调用
- 1小时后,1天内的请求:
- fetch缓存:过期 → 调用API
- API路由:命中 ✅ → 返回静态缓存(不查Supabase)
- 1天后的请求:
- 两层缓存都过期 → 重新查询Supabase
nextjs的loading
page.tsx是服务端组件的话,没法在一堆await动作下设置state,并加入loading组件。 其实nextjs建议这样,在page.tsx同级目录加入loading.tsx页面,内容大体如下,就搞定了。
export default function Loading() {
return (
<div className="flex flex-col w-md animate-pulse">
<div className="h-8 w-20 bg-gray-200 rounded mb-4" />
<div className="h-6 w-32 bg-gray-200 rounded mb-2" />
<div className="space-y-2">
{Array.from({ length: 6 }).map((_, i) => (
<div key={i} className="h-10 bg-gray-200 rounded" />
))}
</div>
</div>
);
}
animate-pulse, 这个是骨架loading效果的关键。

