V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
V2EX  ›  epiloguess  ›  全部回复第 6 页 / 共 6 页
回复总数  118
1  2  3  4  5  6  
2024-03-30 19:45:55 +08:00
回复了 lazyczx 创建的主题 程序员 关于 Next.js 最新的特性, Partial Pre-Rendering 和 SSR 之间的问题
更正:
1. 我看到一个 noStore() 标注的方法执行的时候,别的 API 方法也跟着被调用,但是作为 cache fallback 的方法不被调用。
第一点讨论的有点多余,因为我把 fallback 看成 callback 了

2.但是这并意味着我们就没有 data cache 了
“并”改成“并不”
2024-03-30 19:30:40 +08:00
回复了 lazyczx 创建的主题 程序员 关于 Next.js 最新的特性, Partial Pre-Rendering 和 SSR 之间的问题
忘了发 fork 地址了抱歉,https://github.com/epiloguess/nextjs-dashboard
2024-03-30 19:28:23 +08:00
回复了 lazyczx 创建的主题 程序员 关于 Next.js 最新的特性, Partial Pre-Rendering 和 SSR 之间的问题
前提:canary 但是 config 里面注释掉 ppr = 正式版

1.
> 我看到一个 noStore() 标注的方法执行的时候,别的 API 方法也跟着被调用,但是作为 cache fallback 的方法不被调用。我觉得这个就是 ppr 了对吗? canary 的支持只不过让这个实现更加简单了一点而已:不需要 cache 方法包裹,而是没有使用 noStore 就默认为 cache 。

ppr 指的是部分预渲染,相当于默认一切都是静态的,只要 suspense 里面没有 no store,但是这里有坑,最后说。

在正式版/canary without ppr 中,
这个 noStore 是不是 cache 的 callback,都没有关系,只要你这个路线中,任意一个地方出现了 noStore,next 在 build 的时候,就等价于路由段配置中的 force-dynamic 或者 fetch 中的 no-store,相当于退出静态渲染,改用动态。

当你刷新的时候,为什么另外两个组件都去获取数据了,有 cache 的却没反应呢,因为 unstable_cache 它 cache 的函数的返回值。

所以这跟 ppr 有什么关系?重要的是要把 ppr 和 cache 分开。

你加 cache,只是为了优化,降低它查询数据库的频率。

2.
有一点非常值得注意的是,在 nextjs 中的 fetch,和 unstale_cache 表现是不一样的,

fetch 缓存的是 fetch 请求的返回值,也就是说,为什么在没有 unstable_cache 的时候,你会看到你写的测试时间的方法被调用,因为整个请求数据+计算时间的函数都会被执行,只不过 await sql`` 的时候,直接从缓存中给你值了(这里也有坑)

而 unstable_cache 缓存的是给定函数的返回值,(请求数据+计算时间)这个函数的返回值被缓存了,里面的计算时间自然不会被执行了。

3.
> 但是我发现,如果页面是 static 的,肯定就不会有问题。但是我猜大概从表现的危害上来说也可以接受吧,毕竟页面都是 dynamic 的,让它每点一下就调一次又怎么样了呢,但是原因还是不清楚。

static 的时候,直接就是 html 了,肯定不会调用你写的计时方法。
你需要确保的是,如果函数都加上 unstable_cache 了,你这个问题应该就不会出现了吧。


4.
> 关于第 5 点,我不知道你是怎么测试的,但是我测试的情况下,如果 API 方法里使用了 noStore ,然后把这个方法作为 cache 的 fallback 的话,确实不会退出静态生成。build 的时候显示的 tree 也显示页面仍然是 static ,

你这个是在什么条件下测试的?

> 如果不用 cache 的话,tree 马上变为动态 λ 的了。
在正式版中,任意组件任意位置存在 noStore ,是的,路线就会退出静态渲染,跟 cache 没什么关系。

> 我感觉正式版里只要用 cache 了,noStore 就跟没有调用一样,好像 cache 这个缓存,会直接接管这整个方法调用的结果,然后选择是否缓存。

正如我前面所说,这事儿跟 cache 没什么关系,cache 只是为了降低 动态组件 查询数据库的频率,在静态路线里写不写 cache 没什么意义,是同一个结果

5.一些坑以及一些猜测
深入理解 nextjs 的缓存,
我 fork 了你的项目,RevenueChart 没有 cache,另外两个有,build,start
当你刷新页面的时候,你会发现 RevenueChart 在获取数据,你的终端上出现 fetching data,另外两个数据立刻就有了
这中间发生了什么?

> unstable_noStore can be used to declaratively opt out of static rendering and indicate a particular component should not be cached.
> unstable_noStore 优于 export const dynamic = 'force-dynamic' ,因为它更细粒度并且可以在每个组件的基础上使用

unstable_noStore 是用来配合部分预渲染,实现细粒度的控制组件的渲染方式,当你在另外两个组件中声明 noStore 的时候,就成了一个动态组件
> unstable_noStore is equivalent to cache: 'no-store' on a fetch
> no-store - Next.js 在每次请求时从远程服务器获取资源,而不查看缓存,并且不会使用下载的资源更新缓存。

但是这并意味着我们就没有 data cache 了

> Next.js 有一个内置的数据缓存(data cache),可以在传入的服务器请求和部署中保留数据获取的结果。这是可能的,因为 Next.js 扩展了本机 fetch API 以允许服务器上的每个请求设置自己的持久缓存语义。


---以下为猜测---
假如我们的组件声明了 noStore,组件内部 fetch 了一个资源,没有理由这个 fetch 会退出 nextjs 的 data cache.

我们声明了 noStore,只表达了这是个动态组件,它不是网页静态的一部分,当你访问/刷新网页的时候,你应该永远从服务器获取组件的内容(这里先不提客户端缓存)


因为 @vervel/postgre 的 sql 也是基于 fetch 的
这一点很奇怪,完全想不通,但是参考
https://github.com/orgs/vercel/discussions/4696
https://nextjs.org/docs/messages/ppr-caught-error
> Database Error: NeonDbError: Error connecting to database: Route /dashboard needs to bail out of prerendering at this point because it used revalidate: 0. React throws this special object to indicate where. It should not be caught by your own try/catch. Learn more: https://nextjs.org/docs/messages/ppr-caught-error
> As a convenience, it is not necessary to set the cache option if revalidate is set to a number since 0 implies cache: 'no-store' and a positive value implies cache: 'force-cache'.
> 为方便起见,如果 revalidate 设置为数字,则无需设置 cache 选项,因为 0 隐含 cache: 'no-store' 且正值意味着 cache: 'force-cache'

sql 的内部实现可能用的是 fetch(``, { next: { revalidate: 0 } })

一个悲伤的事情是,正式版的静态渲染和 revalidate 0 配合工作良好,ppr 却不行,这也就意味着,对于带有数据库查询的组件,你并不能 ppr 它们变成完全静态的

当然,这个问题是可以被解决的,配合 router handle,你其实可以用 fetch 获取某些数据库的信息(安全吗?)

---接下来让我们回到刷新后的渲染过程---

为了解决 sql 的 revalidate0,我们引入了 unstable_cache 。

当我们刷新页面的时候,服务器上已经有了那两个组件 cache 的 RSCP,直接就发送过来了,内容是立即出现的
而 RevenueChart 没有 cache,并且由于 sql 的 revalidate0 ,需要重新查询数据库,终端上出现 fetching data

为什么第一次慢后面快?所以给你一种查询没有发出去的错觉?
猜测 1:可能确实没发出去,毕竟 revalidate0 是我的猜测
猜测 2:发出去了,第一次慢是因为网络问题,vercel 在国外,tcp 慢启动,第二次第三次就快了

这一点其实也很好验证,你一边刷新(可以用插件自动刷新),一边在 vercel 数据库中新建一个数据就可以判断了,交给你了,等你反馈

---客户端缓存/路由器缓存---

> 当用户在路线之间导航时,Next.js 会缓存访问过的路线段并预取用户可能导航到的路线(基于视口中的 <Link> 组件)。
> 导航之间不会重新加载整页,并且会保留 React 状态和浏览器状态。
> 会话:缓存在整个导航过程中持续存在。但是,它会在页面刷新时被清除

这一点也很好验证,当你刷新的时候,RevenueChart 会重新获取数据,当你点击左边导航随便一个再点回来,不会触发重新获取,终端上也不会有 fetching data


---最后---

目前你这个例子有一点小,还都是获取 db ,可能无法明显看出 ppr 的优势

对于 ppr 和 sql revalidate 0 的问题,如果真的有想要完全静态的组件还带有 db 查询,
我的建议是 unstable_cache 梭哈,不设置过期时间,算是一种半静态吧,除了第一次比较慢,后面其他用户第二次访问就很快了
2024-03-30 14:14:25 +08:00
回复了 hypnosj 创建的主题 程序员 请教有后端基础如何学习前端开发
可以先看一些高屋建瓴的文章
https://frontendmastery.com/posts/the-new-wave-of-javascript-web-frameworks/

https://frontendmastery.com/posts/navigating-the-future-of-frontend/

https://frontendmastery.com/posts/building-future-facing-frontend-architectures/

你贴的帖子里面也有一个 roadmap ,基本上按照那个学没问题。

不过里面的技术都是国外的主流,国内其实还是有一些差别的。

可以去这里比较,比如说 vue ,
https://npmstats.com/package/vue
2024-03-30 12:22:57 +08:00
回复了 lazyczx 创建的主题 程序员 关于 Next.js 最新的特性, Partial Pre-Rendering 和 SSR 之间的问题
这里补充一下,为什么 unstable_noStore 在正式版和 canary 里表现不一致,可能是因为这个 function 就是为了后续的功能开发的,当前版本可以通过配置路由段,或者 fetch 一个空数据加上 no-store 来退出静态渲染
2024-03-30 10:46:03 +08:00
回复了 lazyczx 创建的主题 程序员 关于 Next.js 最新的特性, Partial Pre-Rendering 和 SSR 之间的问题
这个问题比较复杂,我一点一点回答你。
先讨论正式版,再讨论部分预预渲染
1.next dev 和 build 的渲染逻辑是不一样的,如果你把 data.ts 中 dashboard 相关的那三个组件的 noStore 注释掉,然后 build 一下,你会发现 /dashboard 生成的是静态页面,因为页面没有动态函数而且数据都 cached 了,但 dev 的时候情况可能不一样,数据可能没有全部 cache 完,或者说每次刷新的时候都会重新请求相关数据,这样其实更符合逻辑。注意,你加不加 suspense 都不会影响静态渲染
2.在正式版中,如果你给那三个组件中任意一个加上了 noStore ,整个 dashboard 页面,包括那三个组件都会退出静态渲染,这一点也并不难理解,回顾官方定义,再考虑一下目前渲染路线其实就两种,组件又在页面之中,next 在 build 的时候遇到 noStore 就知道下一步该选什么渲染路线。
> unstable_noStore 可用于以声明方式选择退出静态渲染并指示不应缓存特定组件。

3.你希望达成什么?我想应该是不能够每次刷新都去查询数据,最好可以手动 revalidateTag 。
有两个函数,可能可以帮到你,react cache 和 unstable_cache
https://nextjs.org/docs/app/building-your-application/caching#react-cache-function
https://nextjs.org/docs/app/api-reference/functions/unstable_cache

你可以现在就试试,记得随便一个组件上加上 noStore,然后在 RevenueChart 组件上创建一个函数,
import { unstable_cache} from 'next/cache';

const getCachedRevenue = unstable_cache(
async () => fetchRevenue(),
['Revenue']
);
组件内部开头删掉
const revenue = await fetchRevenue()
然后这样写,
const revenue = await getCachedRevenue()

先 build,start,然后进 dashboard ,在刷新的时候,你会发现,Revenue 组件会保持不变,另外两个出现了骨架屏,可以换个浏览器或者进隐私窗口,一样是秒开。
4.关于你的第二点,没看太明白,这个 30s,5 分钟之类的,都是客户端缓存,你在开发者工具的网络选项卡把选一下禁用缓存,第三点的效果不会变,多看看文档这一节,https://nextjs.org/docs/app/building-your-application/caching#overview
5.最后再来说一下部分预渲染,

根据,https://nextjs.org/docs/app/api-reference/functions/unstable_noStore
在 unstable_cache 内使用 unstable_noStore 不会选择退出静态生成。相反,它将根据缓存配置来确定是否缓存结果。

这句话不太好懂,不过我实测的结果就是,如果你是正式版,那么无论你任何地方使用了 noStore ,在 build 的时候,路线都会变成动态,而如果你是 canary,想要使用部分预渲染,最好还是不要在 unstable_cache 缓存的函数内使用 noStore,参考 https://nextjs.org/docs/messages/ppr-caught-error
> 确保您没有将选择动态渲染的 Next.js API 包装在 try/catch 块中。
尽管官方建议,可以在 try...catch 前插入 noStore, 但后面实现缓存函数不太方便,所以我个人建议,可以在组件的第一行,也就是 const revenue = await getCachedRevenue()的上面一行,使用 noStore ,第二行用 cache,逻辑也比较清晰。


同时,根据,https://nextjs.org/docs/app/api-reference/next-config-js/partial-prerendering
你需要 npm install next@canary ,然后改 config (这个我看有注释),记得每个组件都要加上 noStore ,不然参考第一条,就会被当成静态内容一次生成哦(关于哪些内容被生成静态的了,你可以去开发者工具的网络选项卡,预览第一个送过来的 Document ),然后可以 build 了哦。

祝好!

其他参考(不分先后,我也没看(完),不过很值得看):
- https://github.com/vercel-labs/next-partial-prerendering
- https://github.com/orgs/vercel/discussions/4696
- https://codedrivendevelopment.com/posts/rarely-known-nextjs-features
- https://github.com/vercel/next.js/pull/56930
- https://stackoverflow.com/questions/76829076/in-next-js-13-app-router-how-can-i-use-data-caching-when-not-using-fetch-but
- https://github.com/vercel/next.js/discussions/54075
2024-03-29 22:30:32 +08:00
回复了 Licsber 创建的主题 程序员 人月神话的困境
今天读过一篇类似的文章,项目的压力往往不仅项目本身,管理能力也是必不可少的

https://frontendmastery.com/posts/the-three-ds-of-frontend-feature-leading/
2024-03-29 13:22:17 +08:00
回复了 fen 创建的主题 程序员 大家写静态博客是否会搭配 Headless CMS 使用?
我用的 astro+obsidian,没有用 cms,通过 frontmatter 的字段控制元信息,obsidian 自带 git 插件可以在修改之后推送的远程 git,通过模板自动插入 frontmatter,包括标题日期标签,默认 featured 为 false,draft 为 true,感觉挺自动化的,好像用不上 cms
2024-03-28 13:49:20 +08:00
回复了 zhuqingyuuu 创建的主题 程序员 独立开发者,都是在哪里寻找产品灵感的?
hackernews ?
2024-03-25 20:52:10 +08:00
回复了 xiaoguaiwu 创建的主题 程序员 可以看看各位大佬的博客吗, 4042 年还有人写博客吗?
https://wunhao.com
有是有,就是不怎么更新,主要是自己水平不够 hhh
至于怎么帮助到人,大概别人搜 bug 的时候能在你这里搜到解决思路,就算有所帮助了吧。
关于推广,说实话,如果为了流量,个人运营,选择一些自带信息流的平台会更好,坚守博客的大多还是有个人的想法吧。

附上我比较喜欢的博客,https://www.taniarascia.com/me

> This site has no ads, no affiliate links, no tracking or analytics, no sponsored posts, and no paywall. My motivation for this site is to have a space for self-expression and to share what I've learned with the world. I hope I will inspire others to make their own creative corner on the web as well.
> 该网站没有广告,没有会员链接,没有跟踪或分析,没有赞助帖子,也没有付费墙。我创建这个网站的动机是有一个自我表达的空间,并与世界分享我所学到的东西。我希望我能激励其他人在网络上也创造自己的创意角落。
2024-03-23 19:25:54 +08:00
回复了 LawlietZ 创建的主题 程序员 4202 年了,前端开发一定必须要用 mac 吗
我用的 debian testing, 日常开发预览用 firefox,最后才用 chromium 跑一下 lighthouse,顺便看看哪里有什么布局 bug
基数大,升级成本高,基本上大部分软件版本都和主流版本分布有差异
2024-03-21 17:24:16 +08:00
回复了 xsjyvi 创建的主题 前端开发 现在开发第三方库是不是很少人用 gulp 了,感觉都是 rollup
确实,gulp 没什么人用了
https://npmstats.com/tags/bundler
2024-03-21 17:19:27 +08:00
回复了 zxy23 创建的主题 前端开发 VUE3 的前端开源框架推荐一下?
可以看看我最近在做的网站,https://npmstats.com/tags/vue ,不过可能帮不到你什么,更适合新手,你已经有很多经验了。
2024-03-16 15:14:18 +08:00
回复了 rowink 创建的主题 前端开发 前端这么多轮子,大家是怎么找到好用的轮子的?
@rowink 是的,这个数据来自国内的 npmmirror ,淘宝镜像,后期再添加 npm 的。
不做动态获取,因为这个 api 返回的数据太大了,Next.js 缓存不了,不想从客户端发请求滥用 api ,考虑成本,使用场景,还是选择构建纯静态的,维护一个{"pkg":[tags]} json 就可以搞定,每个月定期更新。
类似的网站有,npm trends ,best of js ,说不定能满足你的需求。

我有考虑过引入时间成本,用 下载量/包创建后的时间 ,这样可以选择更新更好用的轮子,慢慢搞
2024-03-15 22:31:36 +08:00
回复了 rowink 创建的主题 前端开发 前端这么多轮子,大家是怎么找到好用的轮子的?
https://npmstats.com/ 最近在做一个类似的网站,不过还在早期,而且可能和你的需求不完全一致
1  2  3  4  5  6  
关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   实用小工具   ·   2562 人在线   最高记录 6679   ·     Select Language
创意工作者们的社区
World is powered by solitude
VERSION: 3.9.8.5 · 27ms · UTC 01:59 · PVG 09:59 · LAX 18:59 · JFK 21:59
Developed with CodeLauncher
♥ Do have faith in what you're doing.