Next.js 是一款优秀的 React 框架,其最大的优点就是支持服务器端渲染(SSR),从而提升网页的加载速度和 SEO 效果,但是在使用过程中可能会遇到一些问题,其中比较常见的就是 SSR 渲染白屏问题,本文将介绍 5 种解决方法,帮助大家快速定位和解决问题。
1. 使用 headless Chrome 进行 SSR 渲染
Next.js 官方推荐使用 Puppeteer 库,使用 headless Chrome 浏览器来渲染页面,并将渲染结果返回到客户端,避免白屏问题。具体实现可以参考官方文档:
// www.javascriptcn.com code example
import puppeteer from 'puppeteer'
async function ssr(url) {
const browser = await puppeteer.launch()
const page = await browser.newPage()
await page.goto(url)
const html = await page.content()
await browser.close()
return html
}需要注意的是,Puppeteer 是一个比较重量级的库,需要额外安装 Chromium 浏览器,并且启动浏览器需要一定的时间,对服务器资源有一定的消耗。
2. 修改 webpack 配置
在项目根目录新建 next.config.js 文件,覆盖 Next.js 默认的 webpack 配置,并设置构建服务器端代码的所需的最小 Node.js 版本。启用 webpackbar 插件,方便查看 webpack 编译进度。具体代码如下:
// www.javascriptcn.com code example
module.exports = {
webpack: (config, { isServer }) => {
if (isServer) {
config.node = {
fs: 'empty'
}
config.module.rules.push({
test: /\.(j|t)sx?$/,
exclude: /node_modules/,
use: 'babel-loader'
})
}
return config
},
webpackDevMiddleware: config => {
return config
},
serverRuntimeConfig: {
// 将适当修改本地文件系统 URL,比如 dev 或测试环境下指向临时目录
FOLDER_URL: ''
},
// 指定构建服务器端代码的所需的最小 Node.js 版本
// 可以根据实际项目需求调整
target: 'experimental-serverless-trace'
}3. 使用 no-ssr 组件
no-ssr 是 Next.js 官方提供的组件,可以用于在客户端进行组件的渲染。具体代码如下:
// www.javascriptcn.com code example
import dynamic from 'next/dynamic'
const MyComponent = dynamic(() => import('../components/MyComponent'), { ssr: false })
function HomePage() {
return (
<div>
<MyComponent />
</div>
)
}需要注意的是,使用 no-ssr 组件可能会影响 SEO 效果,需要权衡利弊。
4. 使用 React.lazy 和 Suspense 进行懒加载
React.lazy 是 React 16.6 中推出的懒加载组件的 API,与之配合使用的 Suspense 可以实现在组件加载完成前显示一些占位符内容,避免 SSR 渲染白屏问题。具体代码如下:
// www.javascriptcn.com code example
import React, { lazy, Suspense } from 'react'
const MyComponent = lazy(() => import('../components/MyComponent'))
function HomePage() {
return (
<div>
<Suspense fallback={<div>正在加载...</div>}>
<MyComponent />
</Suspense>
</div>
)
}需要注意的是,React.lazy 和 Suspense 需要支持异步加载的组件才能工作,因此需要使用异步加载的组件。
5. 使用服务端缓存
在服务端使用缓存可以有效缓解 SSR 渲染白屏问题。可以使用 lru-cache 等第三方缓存库,将页面内容缓存到内存中,当页面被再次请求时,直接从缓存中读取并返回。具体代码如下:
// www.javascriptcn.com code example
import LRU from 'lru-cache'
const ssrCache = new LRU({
max: 100,
maxAge: 1000 * 60 * 60 // 1 小时
})
async function render(req, res) {
const key = req.path
// 从缓存中读取页面内容
if (ssrCache.has(key)) {
res.setHeader('x-cached', 'true')
res.send(ssrCache.get(key))
return
}
const html = await app.renderToHTML(req, res, req.path, req.query)
if (res.statusCode === 200) {
// 将页面内容缓存到 LRU Cache 中
ssrCache.set(key, html)
}
res.send(html)
}需要注意的是,服务端缓存需要根据实际业务场景和服务器性能,慎重选择缓存的方式和缓存的时间。
以上就是 5 种解决 Next.js SSR 渲染白屏问题的方法,每种方法都有其特点和适用场景,大家可以根据自己的需要进行选择。
来源:JavaScript中文网 ,转载请注明来源 https://www.javascriptcn.com/post/67d6bd95a941bf7134c98d21