路由器

路由器是 Hono 最重要的特性之一。

Hono 内置了五种路由器。


RegExpRouter

RegExpRouter 是 JavaScript 世界中最快的路由器。

虽然名字里有 “RegExp”,但它并不是像 path-to-regexp 那样的 Express 风格实现。后者使用线性循环,因此每次都会对所有路由进行正则匹配,随着路由增多性能会显著下降。

路由 - 图1

Hono 的 RegExpRouter 会将路由模式转换成 “一个大型正则表达式”,然后通过一次匹配就能得到结果。

路由 - 图2

这种方法在大多数情况下比使用基于树结构的算法(如 radix-tree)更快。

不过,RegExpRouter 不支持所有路由模式,因此通常会与下面支持完整模式的其他路由器组合使用。


TrieRouter

TrieRouter 使用 Trie 树算法 实现,与 RegExpRouter 一样,它不采用线性循环。

路由 - 图3

虽然它没有 RegExpRouter 快,但仍然比 Express 的路由器快得多,并且 支持所有路由模式


SmartRouter

SmartRouter 用于在使用多个路由器时选择最佳方案。它会根据注册的路由自动推断并选择最合适的路由器。

Hono 默认使用 SmartRouter + RegExpRouter + TrieRouter

  1. // Hono 核心实现
  2. readonly defaultRouter: Router = new SmartRouter({
  3. routers: [new RegExpRouter(), new TrieRouter()],
  4. })

当应用启动时,SmartRouter 会根据路由检测最佳路由器,并在整个生命周期中持续使用它。


LinearRouter

RegExpRouter 虽然查询快,但路由注册阶段略慢,因此不适合每次请求都初始化的环境。

LinearRouter 为“一次性”场景做了优化。它使用线性方式添加路由,不编译字符串,因此路由注册速度比 RegExpRouter 快得多。

以下是包含路由注册阶段的基准测试结果:

  1. GET /user/lookup/username/hey
  2. ----------------------------------------------------- -----------------------------
  3. LinearRouter 1.82 µs/iter (1.7 µs 2.04 µs) 1.84 µs 2.04 µs 2.04 µs
  4. MedleyRouter 4.44 µs/iter (4.34 µs 4.54 µs) 4.48 µs 4.54 µs 4.54 µs
  5. FindMyWay 60.36 µs/iter (45.5 µs 1.9 ms) 59.88 µs 78.13 µs 82.92 µs
  6. KoaTreeRouter 3.81 µs/iter (3.73 µs 3.87 µs) 3.84 µs 3.87 µs 3.87 µs
  7. TrekRouter 5.84 µs/iter (5.75 µs 6.04 µs) 5.86 µs 6.04 µs 6.04 µs
  8. summary for GET /user/lookup/username/hey
  9. LinearRouter
  10. 2.1x faster than KoaTreeRouter
  11. 2.45x faster than MedleyRouter
  12. 3.21x faster than TrekRouter
  13. 33.24x faster than FindMyWay

对于像 Fastly Compute 这样的环境,建议使用 LinearRouter 搭配 hono/quick 预设。


PatternRouter

PatternRouter 是 Hono 中最小的路由器。

虽然 Hono 本身已经很轻量,但如果需要在资源极其有限的环境中进一步缩小体积,可以选择 PatternRouter。

仅使用 PatternRouter 的应用体积可以保持在 15KB 以下

  1. $ npx wrangler deploy --minify ./src/index.ts
  2. ⛅️ wrangler 3.20.0
  3. -------------------
  4. Total Upload: 14.68 KiB / gzip: 5.38 KiB