1
- const { Trouter } = require ( " trouter" )
2
- const qs = require ( " fast-querystring" )
3
- const next = require ( " ./../next" )
1
+ const { Trouter} = require ( ' trouter' )
2
+ const qs = require ( ' fast-querystring' )
3
+ const next = require ( ' ./../next' )
4
4
5
5
const STATUS_404 = {
6
6
status : 404 ,
@@ -12,26 +12,26 @@ const STATUS_500 = {
12
12
module . exports = ( config = { } ) => {
13
13
const cache = new Map ( )
14
14
15
- if ( ! config . defaultRoute ) {
16
- config . defaultRoute = ( ) => {
17
- return new Response ( null , STATUS_404 )
18
- }
19
- }
20
- if ( ! config . errorHandler ) {
21
- config . errorHandler = ( err ) => {
22
- return new Response ( err . message , STATUS_500 )
23
- }
24
- }
15
+ // Pre-create default responses to avoid object creation overhead
16
+ const default404Response = new Response ( null , STATUS_404 )
17
+
18
+ // Cache default functions to avoid closure creation
19
+ const defaultRouteHandler = config . defaultRoute || ( ( ) => default404Response )
20
+ const errorHandlerFn =
21
+ config . errorHandler || ( ( err ) => new Response ( err . message , STATUS_500 ) )
22
+
23
+ // Optimize empty params object reuse
24
+ const emptyParams = { }
25
25
26
26
const router = new Trouter ( )
27
27
router . port = config . port || 3000
28
28
29
29
const _use = router . use
30
30
31
31
router . use = ( prefix , ...middlewares ) => {
32
- if ( typeof prefix === " function" ) {
32
+ if ( typeof prefix === ' function' ) {
33
33
middlewares = [ prefix , ...middlewares ]
34
- prefix = "/"
34
+ prefix = '/'
35
35
}
36
36
_use . call ( router , prefix , middlewares )
37
37
@@ -40,40 +40,84 @@ module.exports = (config = {}) => {
40
40
41
41
router . fetch = ( req ) => {
42
42
const url = req . url
43
- const startIndex = url . indexOf ( "/" , 11 )
44
- const queryIndex = url . indexOf ( "?" , startIndex + 1 )
45
- const path =
46
- queryIndex === - 1
47
- ? url . substring ( startIndex )
48
- : url . substring ( startIndex , queryIndex )
49
-
50
- req . path = path || "/"
51
- req . query = queryIndex > 0 ? qs . parse ( url . substring ( queryIndex + 1 ) ) : { }
52
-
53
- const cacheKey = `${ req . method } :${ req . path } `
54
- let match = null
55
- if ( cache . has ( cacheKey ) ) {
56
- match = cache . get ( cacheKey )
43
+
44
+ // Highly optimized URL parsing - single pass through the string
45
+ let pathStart = 0
46
+ let pathEnd = url . length
47
+ let queryString = null
48
+
49
+ // Find protocol end
50
+ const protocolEnd = url . indexOf ( '://' )
51
+ if ( protocolEnd !== - 1 ) {
52
+ // Find host end (start of path)
53
+ pathStart = url . indexOf ( '/' , protocolEnd + 3 )
54
+ if ( pathStart === - 1 ) {
55
+ pathStart = url . length
56
+ }
57
+ }
58
+
59
+ // Find query start
60
+ const queryStart = url . indexOf ( '?' , pathStart )
61
+ if ( queryStart !== - 1 ) {
62
+ pathEnd = queryStart
63
+ queryString = url . substring ( queryStart + 1 )
64
+ }
65
+
66
+ const path = pathStart < pathEnd ? url . substring ( pathStart , pathEnd ) : '/'
67
+
68
+ req . path = path
69
+ req . query = queryString ? qs . parse ( queryString ) : { }
70
+
71
+ // Optimized cache lookup with method-based Map structure
72
+ const method = req . method
73
+ let methodCache = cache . get ( method )
74
+ let match_result
75
+
76
+ if ( methodCache ) {
77
+ match_result = methodCache . get ( path )
78
+ if ( match_result === undefined ) {
79
+ match_result = router . find ( method , path )
80
+ methodCache . set ( path , match_result )
81
+ }
57
82
} else {
58
- match = router . find ( req . method , req . path )
59
- cache . set ( cacheKey , match )
83
+ match_result = router . find ( method , path )
84
+ methodCache = new Map ( [ [ path , match_result ] ] )
85
+ cache . set ( method , methodCache )
60
86
}
61
87
62
- if ( match ?. handlers ?. length > 0 ) {
63
- if ( ! req . params ) {
64
- req . params = { }
88
+ if ( match_result ?. handlers ?. length > 0 ) {
89
+ // Fast path for params assignment
90
+ const params = match_result . params
91
+ if ( params ) {
92
+ // Check if params object has properties without Object.keys()
93
+ let hasParams = false
94
+ for ( const key in params ) {
95
+ hasParams = true
96
+ break
97
+ }
98
+
99
+ if ( hasParams ) {
100
+ req . params = req . params || { }
101
+ // Direct property copy - faster than Object.keys() + loop
102
+ for ( const key in params ) {
103
+ req . params [ key ] = params [ key ]
104
+ }
105
+ } else if ( ! req . params ) {
106
+ req . params = emptyParams
107
+ }
108
+ } else if ( ! req . params ) {
109
+ req . params = emptyParams
65
110
}
66
- Object . assign ( req . params , match . params )
67
111
68
112
return next (
69
- match . handlers ,
113
+ match_result . handlers ,
70
114
req ,
71
115
0 ,
72
- config . defaultRoute ,
73
- config . errorHandler
116
+ defaultRouteHandler ,
117
+ errorHandlerFn ,
74
118
)
75
119
} else {
76
- return config . defaultRoute ( req )
120
+ return defaultRouteHandler ( req )
77
121
}
78
122
}
79
123
0 commit comments