perf: shrink data.json

/dashboard/data.json?benchmark=all reduced from 7.8MB to 2.0MB with gzip
compression, and from 2.0MB to 1.1MB by removing the indentation.

For golang/go#48803.

Change-Id: I9031d23b1b751e130521658fd45551771cec04da
Reviewed-on: https://go-review.googlesource.com/c/build/+/413576
Run-TryBot: Michael Pratt <mpratt@google.com>
Reviewed-by: Michael Knyszek <mknyszek@google.com>
TryBot-Result: Gopher Robot <gobot@golang.org>
diff --git a/perf/app/dashboard.go b/perf/app/dashboard.go
index 84b3157..0474cd0 100644
--- a/perf/app/dashboard.go
+++ b/perf/app/dashboard.go
@@ -5,6 +5,7 @@
 package app
 
 import (
+	"compress/gzip"
 	"context"
 	"embed"
 	"encoding/json"
@@ -14,6 +15,7 @@
 	"net/http"
 	"regexp"
 	"sort"
+	"strings"
 	"time"
 
 	"github.com/influxdata/influxdb-client-go/v2/api"
@@ -329,6 +331,15 @@
 	return s, nil
 }
 
+type gzipResponseWriter struct {
+	http.ResponseWriter
+	w *gzip.Writer
+}
+
+func (w *gzipResponseWriter) Write(b []byte) (int, error) {
+	return w.w.Write(b)
+}
+
 // search handles /dashboard/data.json.
 //
 // TODO(prattmic): Consider caching Influx results in-memory for a few mintures
@@ -372,8 +383,15 @@
 	}
 
 	w.Header().Set("Content-Type", "application/json")
+
+	if strings.Contains(r.Header.Get("Accept-Encoding"), "gzip") {
+		w.Header().Set("Content-Encoding", "gzip")
+		gz := gzip.NewWriter(w)
+		defer gz.Close()
+		w = &gzipResponseWriter{w: gz, ResponseWriter: w}
+	}
+
 	w.WriteHeader(http.StatusOK)
 	e := json.NewEncoder(w)
-	e.SetIndent("", "\t")
 	e.Encode(benchmarks)
 }