DEV Community

Brian Michalski
Brian Michalski

Posted on

GRPC Performance in Flutter

Firebase Performance Monitoring is a quick and easy way to get started monitoring the performance of your apps. It automatically monitors a variety of metrics, including HTTP(S) requests which is a great way to compliment your server-side metrics and understand how your app's users are actually feeling.

That magic doesn't kick in automatically if you're using GRPC to make requests in your Flutter app. Instead, you can drop in a quick interceptor to measure the performance of GRPC requests and report them to Firebase:

lib/performance_interceptor.dart

import 'package:firebase_performance/firebase_performance.dart';
import 'package:grpc/grpc.dart';

class PerformanceInterceptor implements ClientInterceptor {
  FirebasePerformance _performance = FirebasePerformance.instance;
  Map<String, String> attributes;

  PerformanceInterceptor([this.attributes = const {}]);

  @override
  ResponseFuture<R> interceptUnary<Q, R>(ClientMethod<Q, R> method, Q request,
      CallOptions options, ClientUnaryInvoker<Q, R> invoker) {
    Trace metric = _performance.newTrace(method.path);
    metric.start();
    this.attributes.forEach((key, value) => metric.putAttribute(key, value));

    ResponseFuture<R> resp = invoker(method, request, options);
    resp.then((_) {
      metric.stop();
    });
    return resp;
  }

  @override
  ResponseStream<R> interceptStreaming<Q, R>(
      ClientMethod<Q, R> method,
      Stream<Q> requests,
      CallOptions options,
      ClientStreamingInvoker<Q, R> invoker) {
    return invoker(method, requests, options);
  }
}
Enter fullscreen mode Exit fullscreen mode

This class is super simple to use, just pass it alongside the options and channel when constructing your GRPC client:

import 'performance_interceptor.dart';

...

client = GreeterClient(
  channel,
  interceptors: [
    PerformanceInterceptor()
  ],
);
Enter fullscreen mode Exit fullscreen mode

You can also pass attributes (dimensions) that should be passed with each request. I like to pass the server I'm connecting to:

client = GreeterClient(
  channel,
  interceptors: [
    PerformanceInterceptor({'host': hostname})
  ],
);
Enter fullscreen mode Exit fullscreen mode

Presto! You've now got performance metric for all your simple GRPC requests!

Firebase Performance console showing a GRPC-based metric

Discussion (0)