fasthttp icon indicating copy to clipboard operation
fasthttp copied to clipboard

Share a case: fasthttp + `page partial gziped cache` to improve page out performance up to 20%

Open ahfuzhang opened this issue 2 years ago • 0 comments

In my case, I need to output a html page, and the top half page is not change, so I gziped top half page and cached. Then I write gzip header, and directly write gziped cache data, and write rest of page data at last. Because of this way, my qps increase 20%. I think fasthttp could support page partial gziped cache API to speed up page output.

Those are my codes:

1.use compress lib:

go get github.com/ahfuzhang/[email protected]

2.replace in go.mod:

replace (
	github.com/klauspost/compress => github.com/ahfuzhang/compress v1.17.2
)
 
require (
	github.com/klauspost/compress v1.16.3
        github.com/valyala/bytebufferpool v1.0.0
	github.com/valyala/fasthttp v1.50.0
)

3.golang code:

package main
 
import (
	"bytes"
	_ "embed"
	"fmt"
	"log"
	"os"
 
	"github.com/klauspost/compress/gzip"
	"github.com/valyala/bytebufferpool"
	"github.com/valyala/fasthttp"
)
 
//go:embed raw.html
var html string
 
//go:embed raw.js
var js string
 
 
func testGzipedHttp() {
    // cache the top half page
    // digest is the crc32 code of content
    topHalf, digest := gzip.GetGzipedData([]byte(html))
	requestHandler := func(ctx *fasthttp.RequestCtx) {
		ctx.Response.Header.Add("Content-Type", "text/plain")
		ctx.Response.Header.Add("Content-Encoding", "gzip")
 
		switch string(ctx.Request.URI().RequestURI()) {
		case "/1":   // direct output
			w, _ := gzip.NewWriterLevel(ctx, gzip.BestCompression)
			w.Write([]byte(html))
			w.Write([]byte(js))
			w.Close()
		case "/2":
			w := gzip.GetWriter(ctx)  // use pool
		        w.WriteHeader()  // write gzip header
                         w.WriteGzipedData([]byte(html), topHalf, digest)    // use cached data
                         w.Write([]byte(js))  
                         gzip.PutWriter(w)  // write gzip tail, and put back to pool
		}
	}
 
	s := &fasthttp.Server{
		Handler: requestHandler,
	}
	if err := s.ListenAndServe(":8080"); err != nil {
		log.Fatalf("error in ListenAndServe: %v", err)
	}
}
 
func main() {
	testGzipedHttp()
}

see this article for more detail(Chinese): https://www.cnblogs.com/ahfuzhang/p/17755400.html

ahfuzhang avatar Oct 10 '23 10:10 ahfuzhang