Fiber v1.9.6 🔥 How to improve performance by 817% and stay fast, flexible and friendly?
Tags: go, fiber, changelog, node
Published: 2020-05-09 08:50:10

## Introduction

Hey, gophers and **Fiber** community 👋 

I missed the beginning of the `v1.9.x` branch of our favorite framework... but the news I will bring you today is worth all the waiting! I promise, you'll _be a happy_ gopher!

OK! Let's go to `v1.9.6` 🚀

### 📝 Table of contents

- [Fast part](#ch-1)
  - [New router](#ch-1-1)
  - [Remove dependencies](#ch-1-2)
  - [Dependency graph](#ch-1-3)
- [Flexible part](#ch-2)
  - [Official middlewares](#ch-2-1)
  - [Third-party middlewares](#ch-2-2)
- [Friendly part](#ch-3)
  - [Discord channel](#ch-3-1)
  - [Translation](#ch-3-2)
  - [Startup message](#ch-3-3)
- [My (short) story about Fiber](#ch-4)
- [Do you like Fiber?](#ch-5)
- [Your assistance to project](#ch-6)

<a name="ch-1"></a>
## Fast part

<a name="ch-1-1"></a>
### ✅ New router

Now, we improved router performance by **817%** and **removed** all allocations in hot paths.

```bash
# Fiber v1.9.4 and lower
Benchmark_Router_OLD-4      614   2467460 ns/op   68902 B/op   600 allocs/op

# Fiber from v1.9.6 and higher
Benchmark_Router_NEW-4     3429    302033 ns/op       0 B/op     0 allocs/op
```

> How did we do that? 🤷 Oh, let me explain!

As you know, we used Go's regex package to parse routes with parameters. But Go's regex is not optimized compared to other languages. Therefore, we used experience of the [ucarion/urlpath](https://github.com/ucarion/urlpath) package to rethink a route matching strategy for **Fiber**. With the help of [@renewerner87](https://github.com/renewerner87) we manged to ditch regexp completely.

> But, how does it really works? 🤔 Let's check out the original repo [docs](https://github.com/ucarion/urlpath#how-it-works)...

**urlpath** operates on the basis of "_segments_", which is basically the result of splitting a path by slashes. When you call `urlpath.New`, each of the segments in the input is treated as either:

- A parameterized segment, like `:user`. All segments starting with `:` are considered parameterized. Any corresponding segment in the input (_even the empty string!_) will be satisfactory, and will be sent to Params in the outputted Match. For example, data corresponding to `:user` would go in `Params["user"]`.
- An exact-match segment, like users. Only segments exactly equal to users will be satisfactory.
- A "_trailing_" segment, `*`. This is only treated specially when it's the last segment — otherwise, it's just a usual exact-match segment. Any leftover data in the input, after all previous segments were satisfied, goes into Trailing in the outputted Match.

> We're very grateful to **ucarion/urlpath** authors!

Example code to reproduce benchmark, you can see on **Fiber** [repository tests](https://github.com/gofiber/fiber/blob/master/router_bench_test.go) for the router. Just install `v1.9.6` or higher, run benchmark and then, downgrade to lower version and run again.

<a name="ch-1-2"></a>
### 💡 Remove dependencies

Branch `v1.9.x` focused on speed and simplicity. Therefore, all maintainers are looking for different ways to remove unnecessary dependencies. And, unfortunately, we would like to say "_thank you and good bye_" to [json-iterator/go](https://github.com/json-iterator/go) package... because, what could be better than a faster **built-in package** for working with JSON in Go `1.14` 😉

```bash
# goos: linux/amd64
BenchmarkJsoniter-4    980358     1061 ns/op   72 B/op    3 allocs/op
BenchmarkJson-4        1177653    1007 ns/op   64 B/op    2 allocs/op

# goos: windows/amd64
BenchmarkJsoniter-4    4473760    259 ns/op    72 B/op    3 allocs/op
BenchmarkJson-4        4625077    251 ns/op    64 B/op    2 allocs/op

# goos: darwin/amd64
BenchmarkJsoniter-4    2059158    801 ns/op    72 B/op    3 allocs/op
BenchmarkJson-4        2738658    400 ns/op    64 B/op    2 allocs/op
```

Example code to reproduce benchmark:

```go
import (
	"testing"
	json "encoding/json"
	jsoniter "github.com/json-iterator/go"
)

type JSONData struct {
	Name string
	Age  uint8
}

var jsoniterParser = jsoniter.ConfigCompatibleWithStandardLibrary

func BenchmarkJsoniter(b *testing.B) {
	for n := 0; n < b.N; n++ {
		data := JSONData{
			Name: "John",
			Age:  20,
		}
		_, _ = jsoniterParser.Marshal(&data)
	}
}

func BenchmarkJson(b *testing.B) {
	for n := 0; n < b.N; n++ {
		data := JSONData{
			Name: "John",
			Age:  20,
		}
		_, _ = json.Marshal(&data)
	}
}
```

Run benchmark to see result for your PC/Mac:

```bash
go test -benchmem -run=^$ -bench .
```

<a name="ch-1-3"></a>
### ⚙️ Dependency graph for `v1.9.x`

When you execute `go get -u github.com/gofiber/fiber` command, you will see only such dependencies:

![dependency graph](https://dev-to-uploads.s3.amazonaws.com/i/qt6doaua7ir9s5w047ih.png)

<a name="ch-2"></a>
## Flexible part

<a name="ch-2-1"></a>
### 🧬 Official middlewares

For an more _maintainable_ middleware _ecosystem_, we've put official [middlewares](https://docs.gofiber.io/middleware) into separate repositories:

- [gofiber/compression](https://github.com/gofiber/compression)
- [gofiber/basicauth](https://github.com/gofiber/basicauth)
- [gofiber/requestid](https://github.com/gofiber/requestid)
- [gofiber/websocket](https://github.com/gofiber/websocket)
- [gofiber/keyauth](https://github.com/gofiber/keyauth)
- [gofiber/rewrite](https://github.com/gofiber/rewrite)
- [gofiber/recover](https://github.com/gofiber/recover)
- [gofiber/limiter](https://github.com/gofiber/limiter)
- [gofiber/session](https://github.com/gofiber/session)
- [gofiber/adaptor](https://github.com/gofiber/adaptor)
- [gofiber/logger](https://github.com/gofiber/logger)
- [gofiber/helmet](https://github.com/gofiber/helmet)
- [gofiber/embed](https://github.com/gofiber/embed)
- [gofiber/pprof](https://github.com/gofiber/pprof)
- [gofiber/cors](https://github.com/gofiber/cors)
- [gofiber/csrf](https://github.com/gofiber/csrf)
- [gofiber/jwt](https://github.com/gofiber/jwt)

<a name="ch-2-2"></a>
### 🌱 Third-party middlewares

This is a list of middlewares, that are created by the Fiber community:

- [arsmn/fiber-swagger](https://github.com/arsmn/fiber-swagger)
- [arsmn/fiber-casbin](https://github.com/arsmn/fiber-casbin)
- [arsmn/fiber-introspect](https://github.com/arsmn/fiber-introspect)
- [shareed2k/fiber_tracing](https://github.com/shareed2k/fiber_tracing)
- [shareed2k/fiber_limiter](https://github.com/shareed2k/fiber_limiter)
- [thomasvvugt/fiber-boilerplate](https://github.com/thomasvvugt/fiber-boilerplate)
- [arsmn/gqlgen](https://github.com/arsmn/gqlgen)

<a name="ch-3"></a>
## Friendly part

<a name="ch-3-1"></a>
### 🎙 Discord channel

Oh, yes! It finally happened! 🎉 **Fiber** community now has a place to communicate and share experiences — official Discord [channel](https://gofiber.io/discord).

![discord channel](https://dev-to-uploads.s3.amazonaws.com/i/ex8w8flv9q27qiatbwi9.png)

> Come on in, it'll be nice to talk to you! 😉

<a name="ch-3-2"></a>
### 🈯️ Translation

Special greetings, I would like to give a shoutout to all the people who helped translating the fiber documentation. You're **awesome**, thank you so much! 👍

![translation](https://dev-to-uploads.s3.amazonaws.com/i/3p4yjcufpzpen3jbifwk.png)

> If you would like to help translate and/or improve an existing translation, then welcome to our [Crowdin](https://crowdin.com/project/gofiber)!

<a name="ch-3-3"></a>
### ⭐️ Startup message

Sometimes, they come back 🤣

```
        _______ __
  ____ / ____(_) /_  ___  _____
_____ / /_  / / __ \/ _ \/ ___/
  __ / __/ / / /_/ /  __/ /
    /_/   /_/_.___/\___/_/ v1.9.6
Started listening on 0.0.0.0:3000
```

> When `Settings.DisableStartupMessage` set to `true`, it will not print out the **Fiber** ASCII logo and "listening on ..." message.

<a name="ch-4"></a>
## 😋 My short history with the Fiber project

My story with **Fiber** web framework doesn't end with "consumption" alone. After translating _README_ into Russian and creating the first concepts of the [official logo](https://gofiber.io/assets/images/logo.svg), I got acquainted with the author and invited to be an official maintainer. Our route to bring Fiber to the public begon.

> @Fenny, if you're reading this, know you're really awesome! 😘

Let's go back to early February 2020, **Fiber** had:

- No more than _120_ GitHub stars;
- A weird logo (as Fenny suggested: "_gopher holding a fiber optic cable?_");
- No translations

Decisions on architecture, naming, versioning, code & method design, testing and benchmarks of web framework... were discussed every evening directly on messenger with a cup of coffee in the best possible way.

> Here's a `v1.3.0` release showing how much Fenny adores me 😂:
>
> ![release 1.3.0](https://dev-to-uploads.s3.amazonaws.com/i/g04ihyz1g6le5gxgnt7c.jpeg)

I still cannot believe that after _2,5 months_ since the first release, **Fiber** web framework has:

🎯 5,200+ stars on GitHub;
🎯 Stably gets into GitHub [Trending](https://github.com/trending/go?since=weekly) page of Golang (weekly, daily);
🎯 Big, friendly (and alive) community coming from all over the world;
🎯 Documentation, translated into 12 languages (and preparing another six);
🎯 Identical API and method names as [Express](https://expressjs.com/en/4x/api.html);
🎯 An actively developing middleware ecosystem;
🎯 TOP-2 status among all Go web frameworks and TOP-10 among all other programming languages, according to different benchmarks ([TechEmpower](https://www.techempower.com/benchmarks/#section=test&runid=c7152e8f-5b33-4ae7-9e89-630af44bc8de&hw=ph&test=plaintext), [The Benchmarker](https://github.com/the-benchmarker/web-frameworks) and not so);

![release 1.9.6](https://dev-to-uploads.s3.amazonaws.com/i/hft5aqf78sazap91gncn.png)

<a name="ch-5"></a>
## 💬 Do you like Fiber? Tell about it!

Fiber authors are **always** listening to its users in [issues](https://github.com/gofiber/fiber/issues), Discord [channel](https://gofiber.io/discord) and all over the Internet. Therefore, it would be great, if you could share your opinion or/and experience with **Fiber** to authors in [GitHub](https://github.com/gofiber/fiber) repository!

> [...] because it's only right way to create a **fast**, **flexible** and **friendly** Go web framework for any tasks, deadlines and developer skills!
>
> _— Fiber Authors_

![Do you like Fiber?](https://dev-to-uploads.s3.amazonaws.com/i/v22vk8sjujiixm7i1jfg.jpg)

<a name="ch-6"></a>
## Your assistance to project 👍

1. Add a [GitHub Star](https://github.com/gofiber/fiber) to the project.
2. Tweet about the project [on your Twitter](https://twitter.com/intent/tweet?text=Fiber%20is%20an%20Express%20inspired%20%23web%20%23framework%20built%20on%20top%20of%20Fasthttp%2C%20the%20fastest%20HTTP%20engine%20for%20%23Go.%20Designed%20to%20ease%20things%20up%20for%20%23fast%20development%20with%20zero%20memory%20allocation%20and%20%23performance%20in%20mind%20%F0%9F%9A%80%20https%3A%2F%2Fgithub.com%2Fgofiber%2Ffiber).
3. Write a review or tutorial on [Medium](https://medium.com/), [Dev.to](https://dev.to/) or personal blog.
4. Help us to translate our API Documentation via [Crowdin](https://crowdin.com/project/gofiber).

## Photo by

[Title] Matthew Brodeur ([link](https://unsplash.com/photos/eJ9mX6yEbAw)) & Vic Shóstak ([link](https://github.com/koddr))
[1] Discord https://discord.com/download
[2] Ashley McNamara https://github.com/ashleymcnamara/gophers

<a name=""></a>
## P.S.

If you want more articles (like this) on this blog, then post a comment below and subscribe to me. Thanks! 😻

And of course, you can help me make developers' lives even better! Just connect to one of my projects as a contributor. It's easy!

My projects that need your help (and stars) 👇

- 🔥 [gowebly][gowebly_url]: A next-generation CLI tool for easily build amazing web applications with Go on the backend, using htmx & hyperscript and the most popular atomic/utility-first CSS frameworks on the frontend.
- ✨ [create-go-app][cgapp_url]: Create a new production-ready project with Go backend, frontend and deploy automation by running one CLI command.
- 🏃 [yatr][yatr_url]: Yet Another Task Runner allows you to organize and automate your routine operations that you normally do in Makefile (or else) for each project.
- 📚 [gosl][gosl_url]: The Go Snippet Library provides snippets collection for working with routine operations in your Go programs with a super user-friendly API and the most efficient performance.
- 🏄‍♂️ [csv2api][csv2api_url]: The parser reads the CSV file with the raw data, filters the records, identifies fields to be changed, and sends a request to update the data to the specified endpoint of your REST API.
- 🚴 [json2csv][json2csv_url]: The parser can read given folder with JSON files, filtering and qualifying input data with intent & stop words dictionaries and save results to CSV files by given chunk size.

<!-- Footer links -->

[gowebly_url]: https://github.com/gowebly
[cgapp_url]: https://github.com/create-go-app
[yatr_url]: https://github.com/koddr/yatr
[gosl_url]: https://github.com/koddr/gosl
[csv2api_url]: https://github.com/koddr/csv2api
[json2csv_url]: https://github.com/koddr/json2csv