admin管理员组文章数量:1418592
I've just started using NextJs getStaticProps
, and static files generated at build time
is neat. But my contents just don't stay unchanged, I need static files to be updated but rebuilding the app everytime there's a modification is costly. Is there a way to generate new static files only. getServerSideProps
turned out to be taking a big amount of time til first byte.
I've just started using NextJs getStaticProps
, and static files generated at build time
is neat. But my contents just don't stay unchanged, I need static files to be updated but rebuilding the app everytime there's a modification is costly. Is there a way to generate new static files only. getServerSideProps
turned out to be taking a big amount of time til first byte.
- 3 I'm not sure I get this right - you say your content changes, but then you say it's taking time to rebuild. I'm not sure there's any other option here, as the modified content needs to be rebuild :) – Andrey Popov Commented Jun 11, 2021 at 14:09
- @AndreyPopov Yeah I meant rerun the static-file-generating function for new records. Sorry for the confusion :'D – Yves Ng Commented Jun 11, 2021 at 21:40
2 Answers
Reset to default 4Depending on type of you content Incremental Statatic Regeneration could be a good solution. But in my experience it introduced other problems when rendering catalog/category pages. As nextjs has no idea if one part of you data is dependent on some other it may render an old catalog page with a link to post or product which no longer exists. This usually happens in bination with a 'fallback' feature for dynamic routes.
It also won't refresh you page right after you made changes so you will see a result only after some time.
Possible workaround is to load posts/product on category page dynamically via ajax. You will lose a part of UX and SEO but on the other hand this solution is relatively easy to maintain.
There is also an option or rather hack to rebuild parts of saved content by directly accessing the cache in custom server. Add 'purge=1' to the page address you want to refreshed.
const { ServerResponse, createServer } = require('http')
const next = require('next')
const { promises } = require('fs')
const path = require('path')
const dev = process.env.NODE_ENV !== 'production'
const app = next({ dev })
const handle = app.getRequestHandler()
const purgeByPath = async url => {
const pathname = url == '/' ? '/index' : url
const fullPathname = `.next/server/pages${pathname}`
const fullPathHTML = `${fullPathname}.html`
const fullPathJSON = `${fullPathname}.json`
try {
await promises.unlink(fullPathHTML)
await promises.unlink(fullPathJSON)
} catch (err) {
console.log(`Could not unlink cache files: ${err}`)
}
await app.incrementalCache.cache.del(pathname)
let req = new Request(process.env.BASE_HOST + url)
let res = new ServerResponse(req)
await app.renderToHTML(req, res, url, { _nextDataReq: true })
}
app.prepare().then(() => {
createServer(async (req, res) => {
const url = new URL(req.url, "http://localhost:3000/")
if (req.method == 'POST' && req.url == '/purge-cache') {
let raw = ''
req.on('data', chunk => raw += chunk)
req.on('end', async () => {
const data = JSON.parse(raw)
if (!data || !data.urls) {
res.statusCode = 400
res.end()
return
}
for (let url of data.urls) {
console.log(`Cleaning cache on: ${url}`)
await purgeByPath(url)
}
res.end()
})
} else if (url.searchParams.get('purge') == '1') {
await purgeByPath(req.url)
res.end()
} else {
handle(req, res)
}
}).listen(3000, (err) => {
if (err) throw err
console.log(`> Ready on http://localhost:3000/`)
})
})
The static cache consists of two parts:
- Static cache files located at
.next/server/pages
where each route will probably have two files html and json. Most likely you'll need to delete both. - In-memory cache. Once you app cached a page and saved it to memory it won't go to files on hard drive but instead will load content from memory. So you need to delete it as well.
Cache implementation is not documented an might be swapped or removed in future versions.
This won't work on vercel and has some issues with scaling. You should also add some kind of security token to purge routes.
If I understand it correctly, you are looking for Incremental Statatic Regeneration.
To enable it, you need to add a revalidate
time in getStaticProps
. As your content is changed and after the revalidation time is reached, a new static page will be generated and served by the server. Depends on how often your content changes, you can change the revalidation time accordingly.
export async function getStaticProps() {
const res = await fetch('https://.../posts')
const posts = await res.json()
return {
props: {
posts,
},
// Next.js will attempt to re-generate the page:
// - When a request es in
// - At most once every 10 seconds
revalidate: 10, // In seconds
}
}
Reference
https://nextjs/docs/basic-features/data-fetching#incremental-static-regeneration
本文标签:
版权声明:本文标题:javascript - Is it possible to not rebuild the whole app but generate new static files only in Nextjs? - Stack Overflow 内容由网友自发贡献,该文观点仅代表作者本人, 转载请联系作者并注明出处:http://www.betaflare.com/web/1745296976a2652138.html, 本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌抄袭侵权/违法违规的内容,一经查实,本站将立刻删除。
发表评论