问题所在
当我在服务器端运行以下 Mixpanel 跟踪代码时,只能断断续续地记录事件。
mixpanel.track(event, { distinct_id: userId, properties }, err => {
if (err) {
reject(err);
} else {
resolve("success");
}
});
在本地环境中,所有事件都被正确记录,但在 Vercel 部署中,只有部分事件被记录。
原因
在了解原因之前,我们先来了解一下 Vercel 功能。Vercel 为部署在 Vercel 上的环境提供了一种名为 Vercel Function的功能。
简而言之,Vercel Function 就是部署在 Vercel 上的所有服务器端代码都在 Vercel 的基础架构下运行,这意味着它是FaaS。
FaaS 是 "功能即服务"(Function as a Service)的缩写,是实现无服务器计算的方法之一。其理念是,功能是我们在开发中使用的函数,我们把它们放在云服务上,只有在需要时才调用它们。 换句话说,FaaS 允许我们编写和执行函数,而无需开发服务器。 得益于 Vercel 的这一功能,我们可以使用 API Routes、SSR 等,而无需架设服务器。
✏️了解更多 Vercel 的无服务器架构由 AWS 上的 Lambda 提供支持。
导致问题的代码也被设置为Server Action并在服务器上执行,由于 Vercel 基于无服务器,因此代码被注册为无服务器函数。
但是,无服务器函数有可能在执行过程中终止进程,在这种情况下,函数可能在异步操作完成之前就终止了,这意味着回调函数
没有执行,事件也没有正确发送。
解决方法
我们将代码封装在一个 Promise 中
,如下所示,所有事件都能正确发送。
return new Promise((resolve, reject) => {
mixpanel.track(event, { distinct_id: userId, properties }, (err) => {
if (err) {
reject(err)
} else {
resolve('success')
}
})
})
为什么要在服务器端运行跟踪代码?
那我们为什么不在客户端运行类似 mixpanel.track 这样的跟踪代码呢?
- 数据完整性:当事件直接从客户端发送时,它们可能会因用户浏览器设置(如广告拦截器)或网络问题而被遗漏。在服务器端运行可减少这些外部因素的影响,使数据收集更加可靠。
- 与业务逻辑集成:当跟踪事件与服务器端逻辑(如支付处理、用户身份验证等)密切相关时,直接在服务器上进行处理会更自然、更高效。例如,如果您想在支付完成后记录一个事件,那么在服务器上检查支付是否成功,然后再进行跟踪就比较合理。
- 优化性能:在客户端处理跟踪请求会导致额外的网络调用,从而增加页面加载时间。在服务器端处理可减轻客户端的负担,改善用户体验。
因此,尽可能在服务器端而不是客户端运行,可以获得更准确、更可靠的指标。
🔎 另请参见