使用apollo graphql客户端记录请求时间的正确方法是什么?

时间:2019-06-08 01:35:24

标签: graphql apollo-client

我正在对React本机应用程序进行一些应用程序性能分析,我发现使用apollo-link-logger的请求时间之间有很大的不同(以及我滚动的链接)我自己的)和Android分析器的联网通道。对于探查器中大约600毫秒的请求,我发现使用阿波罗链接系统的中间件需要2秒钟以上的时间。

我自己的链接中没有什么事情(如下)

const metricsLink = new ApolloLink((operation, forward) => {

    const { operationName } = operation
    const startTime = new Date().getTime()
    const observable = forward(operation)
    observable.subscribe({
        complete: () => {
            const elapsed = new Date().getTime() - startTime
            console.warn(`[METRICS][${operationName}] (${elapsed}) complete`)
        }
    })

    return observable
})

似乎还要考虑到阿波罗管理该请求链所花费的时间。我已经通过直接从其他端点获取数据并将这些时间与探查器时间(匹配)进行比较,从而确认这不是应用程序的普遍问题。

我应该希望这能真正反映请求时间吗?其余时间可能会在本地网络请求和我在apollo客户端中看到的时间之间去?

2 个答案:

答案 0 :(得分:0)

问题(至少在我使用的版本中)是Zen Observable(在这些链接中由Apollo使用)在每次进行订阅调用时都执行其逻辑。这意味着我收到了两次重复请求,因为我有两个链接,每个链接都称为订阅,并转发了已创建的可观察对象。我的解决方法是每次创建新的可观察对象,并将它们连接到先前链接传递下来的可观察对象。

const metricsLink = new ApolloLink((operation, forward) => {

    const { operationName } = operation
    const startTime = new Date().getTime()
    const observable = forward(operation)

    // Return a new observable so no other links can call .subscribe on the
    // the one that we were passsed.
    return new Observable(observer => {
        observable.subscribe({
            complete: () => {
                const elapsed = new Date().getTime() - startTime
                console.warn(`[METRICS][${operationName}] (${elapsed}) complete`)
                observer.complete()
            },
            next: observer.next.bind(observer),
            error: error => {
                // ...
                observer.error(error)
            }
        })
    })
})

这对我来说似乎是一个疏忽,但至少我有一种解决方法。

答案 1 :(得分:0)

Apollo Link docs中,有一个使用链接组合来测量时间的示例

注意:我已基于this other SO answer

修改了示例,以使用performance.now()代替new Date()
const timeStartLink = new ApolloLink((operation, forward) => {
  operation.setContext({ start: performance.now() })
  return forward(operation)
})

const logTimeLink = new ApolloLink((operation, forward) => {
  return forward(operation).map(data => {
    // data from a previous link
    const time = performance.now() - operation.getContext().start
    console.log(`operation ${operation.operationName} took ${time} to complete`)
    return data
  })
})

const link = timeStartLink.concat(logTimeLink)