perf(compression): pre-compute MIME type byte slices for isCompressible
Add typesBytes and typesWildcardPrefix fields to Middleware, built once at construction. isCompressible now uses pre-converted byte slices instead of allocating []byte(t) per comparison per request.
This commit is contained in:
parent
bd97c05d0d
commit
e5fa9fe9de
@ -112,6 +112,10 @@ type Middleware struct {
|
|||||||
brotliPool *compressorPool
|
brotliPool *compressorPool
|
||||||
// types 可压缩的 MIME 类型列表
|
// types 可压缩的 MIME 类型列表
|
||||||
types []string
|
types []string
|
||||||
|
// typesBytes 预计算的小写 MIME 类型字节切片
|
||||||
|
typesBytes [][]byte
|
||||||
|
// typesWildcardPrefix 预计算的通配符前缀字节切片
|
||||||
|
typesWildcardPrefix [][]byte
|
||||||
|
|
||||||
// level 压缩级别(1-9)
|
// level 压缩级别(1-9)
|
||||||
level int
|
level int
|
||||||
@ -171,6 +175,15 @@ func New(cfg *config.CompressionConfig) (*Middleware, error) {
|
|||||||
algorithm: algo,
|
algorithm: algo,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
for _, t := range m.types {
|
||||||
|
lower := strings.ToLower(t)
|
||||||
|
if base, found := strings.CutSuffix(lower, "/*"); found {
|
||||||
|
m.typesWildcardPrefix = append(m.typesWildcardPrefix, []byte(base))
|
||||||
|
} else {
|
||||||
|
m.typesBytes = append(m.typesBytes, []byte(lower))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// 初始化缓冲池
|
// 初始化缓冲池
|
||||||
m.gzipPool = newGzipPool(cfg.Level)
|
m.gzipPool = newGzipPool(cfg.Level)
|
||||||
m.brotliPool = newBrotliPool(cfg.Level)
|
m.brotliPool = newBrotliPool(cfg.Level)
|
||||||
@ -296,22 +309,20 @@ func (m *Middleware) Process(next fasthttp.RequestHandler) fasthttp.RequestHandl
|
|||||||
// 返回值:
|
// 返回值:
|
||||||
// - bool: 是否可压缩
|
// - bool: 是否可压缩
|
||||||
func (m *Middleware) isCompressible(contentType []byte) bool {
|
func (m *Middleware) isCompressible(contentType []byte) bool {
|
||||||
// 移除 charset 等参数
|
|
||||||
ct := contentType
|
ct := contentType
|
||||||
if idx := bytes.IndexByte(ct, ';'); idx >= 0 {
|
if idx := bytes.IndexByte(ct, ';'); idx >= 0 {
|
||||||
ct = ct[:idx]
|
ct = ct[:idx]
|
||||||
}
|
}
|
||||||
ct = bytes.TrimSpace(ct)
|
ct = bytes.TrimSpace(ct)
|
||||||
|
|
||||||
for _, t := range m.types {
|
for _, t := range m.typesBytes {
|
||||||
if bytes.Equal(bytes.ToLower([]byte(t)), ct) {
|
if bytes.Equal(t, ct) {
|
||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
// 支持通配符匹配
|
|
||||||
if base, found := strings.CutSuffix(t, "/*"); found {
|
|
||||||
if bytes.HasPrefix(ct, []byte(base)) {
|
|
||||||
return true
|
|
||||||
}
|
}
|
||||||
|
for _, prefix := range m.typesWildcardPrefix {
|
||||||
|
if bytes.HasPrefix(ct, prefix) {
|
||||||
|
return true
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return false
|
return false
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user