如何优雅的部署一个 Serverless Next.js 应用( 二 )

上面配置中的 STATIC_URL 就是静态资源托管服务提供的访问 url,示例中是腾讯云对应的 COS 访问 url 。
那么针对第二种资源我们如何处理呢?这里就需要对业务代码进行稍微改造了 。
首先,需要在 next.config.js 中添加 env.STATIC_URL 环境变量:
const isProd = process.env.NODE_ENV === "production";const STATIC_URL ="https://serverless-nextjs-xxx.cos.ap-guangzhou.myqcloud.com";module.exports = {env: {// 3000 为本地开发时的端口,这里是为了本地开发时,也可以正常运行STATIC_URL: isProd ? STATIC_URL : "http://localhost:3000",},assetPrefix: isProd ? STATIC_URL : "",};然后,在项目中修改引入 public 中静态资源的路径,比如:
<!-- before --><head><title>Create Next App</title><link rel="icon" href=https://www.isolves.com/it/cxkf/bk/2020-07-24/"/favicon.ico" />Create Next App_江苏龙网最后,在 serverless.yml 中新增静态资源相关配置 staticConf,如下:
org: orgDemoapp: appDemostage: devcomponent: nextjsname: nextjsDemoinputs:src:dist: ./hook: npm run buildexclude:- .envregion: ap-guangzhouruntime: Nodejs10.15apigatewayConf:# 此处省略....# 静态资源相关配置staticConf:cosConf:# 这里是创建的 COS 桶名称bucket: serverless-nextjs通过配置 staticConf.cosConf 指定 COS 桶,执行部署时,会默认自动将编译生成的 .next 和 public 文件夹静态资源上传到指定的 COS 。
修改好配置后,再次执行 serverless deploy 进行部署:
$ serverless deployserverless ?frameworkAction: "deploy" - Stage: "dev" - App: "appDemo" - Instance: "nextjsDemo"region:ap-guangzhou# 此处省略......staticConf:cos:region:ap-guangzhoucosOrigin: serverless-nextjs-xxx.cos.ap-guangzhou.myqcloud.combucket:serverless-nextjs-xxx浏览器访问,打开调试控制台,可以看到访问的静态资源请求路径如下:

如何优雅的部署一个 Serverless Next.js 应用

文章插图
 
上图可以看出,静态资源均通过访问 COS 获取,现在云函数只需要渲染入口文件,而不需要像之前,静态资源全部通过云函数返回 。
备注:之前由于都是将 .next 部署到了云函数,所以没法访问页面后,页面中的静态资源,如图片,都需要再次访问云函数,然后获取 。于是看似我们请求了一次云函数,而实际上云函数单位时间并发数,会根据页面静态资源请求数而增加,从而造成冷启动问题 。
静态资源配置 CDN【如何优雅的部署一个 Serverless Next.js 应用】上面我们已经将静态资源都部署到 COS 了,页面访问也快了很多 。但是对于生产环境,还需要给静态资源配置 CDN 的 。通过 COS 控制台已经可以很方便的配置 CDN 加速域名了 。但是还是需要手动去配置,作为一名懒惰的程序员,我还是不能接受的 。而 Next.js 组件正好提供了给静态资源配置 CDN 的能力,只需要在 serverless.yml 中新增 staticConf.cdnConf 配置即可,如下所示:
# 此处省略....inputs:# 此处省略....# 静态资源相关配置staticConf:cosConf:# 这里是创建的 COS 桶名称bucket: serverless-nextjscdnConf:domain: static.test.yuga.chathttps:certId: abcdefg这里使用 https 协议,所以也添加了 https 的 certId 证书 ID 配置 。此外静态资源域名也需要修改为 CDN 域名,修改 next.config.js 如下:
const isProd = process.env.NODE_ENV === "production";const STATIC_URL = "https://static.test.yuga.chat";module.exports = {env: {STATIC_URL: isProd ? STATIC_URL : "http://localhost:3000",},assetPrefix: isProd ? STATIC_URL : "",};配置好后,再次执行部署,结果如下:
$ serverless deployserverless ?frameworkAction: "deploy" - Stage: "dev" - App: "appDemo" - Instance: "nextjsDemo"region:ap-guangzhouapigw:# 省略...scf:# 省略...staticConf:cos:region:ap-guangzhoucosOrigin: serverless-nextjs-xxx.cos.ap-guangzhou.myqcloud.combucket:serverless-nextjs-xxxcdn:domain: static.test.yuga.chaturl:https://static.test.yuga.chat
注意:这里虽然添加了 CDN 域名,但是还是需要手动配置 CNAME static.test.yuga.chat.cdn.DNSv1.com 解析记录 。
优化前后对比到这里,Serverless Next.js 应用体验已经优化了很多,我们可以使用 Lighthouse 进行性能测试,来验证下我们的收获 。测试结果如下:
优化前:
如何优雅的部署一个 Serverless Next.js 应用


推荐阅读