问题
在服务器端执行以下Mixpanel跟踪代码时,事件仅间歇性地被记录。
mixpanel.track(event, { distinct_id: userId, properties }, err => {
if (err) {
reject(err);
} else {
resolve("success");
}
});
在本地环境中,所有事件都能正常记录,但在Vercel部署环境中,只有部分事件被记录的问题。
原因
在查看原因之前,让我们了解一下Vercel Functions。Vercel为部署到Vercel的环境提供了一个称为Vercel Functions的功能。
简单地解释Vercel Functions,在Vercel部署环境中的所有服务器端代码执行都在Vercel的基础设施环境下运行。也就是说,应用了FaaS(Function as a Service)。
什么是FaaS?
FaaS是Function as a Service的缩写,是实现无服务器计算的一种方式。这里的Function指的就是我们在开发中使用的那个Function,这个概念是将这些函数上传到云服务,只在需要时调用。
换句话说,FaaS允许你无需开发服务器就能执行函数。
正是由于Vercel的这一功能,我们无需特别进行服务器设置就能使用API Routes或SSR等功能。
Note
Vercel的无服务器架构通过AWS Lambda运行。
出现问题的代码也被设置为**服务器操作(Server Action)**并在服务器上执行,由于Vercel基于无服务器运行,代码被注册为无服务器函数。
然而,无服务器函数在执行过程中可能会终止进程,在这种情况下,函数可能在异步任务完成前就终止了。也就是说,callback
函数没有被执行,所以事件没有被正确传输。
解决方案
因此,我们将代码用Promise
包装,如下所示,所有事件都能正常记录了。
return new Promise((resolve, reject) => {
mixpanel.track(event, { distinct_id: userId, properties }, (err) => {
if (err) {
reject(err)
} else {
resolve('success')
}
})
})
为什么在服务器端执行跟踪代码
那么,为什么不在客户端执行像mixpanel.track这样的跟踪代码呢?
- 数据完整性:当从客户端直接发送事件时,由于用户的浏览器设置(例如:广告拦截器)或网络问题,事件可能会丢失。在服务器端执行可以减少这些外部因素,实现更可靠的数据收集。
- 与业务逻辑集成:当跟踪事件与服务器端逻辑(例如:支付处理、用户认证等)密切相关时,在服务器上直接处理更自然、更高效。例如,要在支付完成后记录事件,在服务器上确认支付成功后再跟踪是合适的。
- 性能优化:在客户端处理跟踪请求会导致额外的网络调用,增加页面加载时间。在服务器端处理可以减轻客户端负担,改善用户体验。
由于这些原因,如果可能的话,在服务器端而不是客户端执行可以获得更准确、更稳定的指标。
参考