koa-classic-server 3.0.0 → 3.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (105) hide show
  1. package/README.md +44 -120
  2. package/index.cjs +236 -21
  3. package/package.json +10 -5
  4. package/.github/workflows/npm-publish.yml +0 -98
  5. package/CLAUDE.md +0 -101
  6. package/__tests__/benchmark-results-baseline-v1.2.0.txt +0 -354
  7. package/__tests__/benchmark-results-optimized-v2.0.0.txt +0 -354
  8. package/__tests__/benchmark-results-v3.0.0.txt +0 -372
  9. package/__tests__/benchmark.js +0 -239
  10. package/__tests__/caching-headers.test.js +0 -556
  11. package/__tests__/compression-fixtures/data.json +0 -1
  12. package/__tests__/compression-fixtures/large.txt +0 -1
  13. package/__tests__/compression-fixtures/small.txt +0 -1
  14. package/__tests__/compression.test.js +0 -284
  15. package/__tests__/customTest/README.md +0 -6
  16. package/__tests__/customTest/loadConfig.util.js +0 -41
  17. package/__tests__/customTest/serversToLoad.util.js +0 -93
  18. package/__tests__/demo-regex-index.js +0 -140
  19. package/__tests__/deprecation-warnings.test.js +0 -105
  20. package/__tests__/directory-sorting-links.test.js +0 -135
  21. package/__tests__/dt-unknown.test.js +0 -635
  22. package/__tests__/ejs.test.js +0 -299
  23. package/__tests__/hidden-fixtures/.dot-dir/inside.txt +0 -1
  24. package/__tests__/hidden-fixtures/.env +0 -2
  25. package/__tests__/hidden-fixtures/.well-known/acme-challenge.txt +0 -1
  26. package/__tests__/hidden-fixtures/config/secrets/password.txt +0 -1
  27. package/__tests__/hidden-fixtures/data.key +0 -1
  28. package/__tests__/hidden-fixtures/file.secret +0 -1
  29. package/__tests__/hidden-fixtures/index.html +0 -1
  30. package/__tests__/hidden-fixtures/normal.txt +0 -1
  31. package/__tests__/hidden-fixtures/subdir/.env +0 -1
  32. package/__tests__/hidden-fixtures/subdir/regular.txt +0 -1
  33. package/__tests__/hidden-option.test.js +0 -407
  34. package/__tests__/hideExtension.test.js +0 -607
  35. package/__tests__/index-option.test.js +0 -449
  36. package/__tests__/index.test.js +0 -345
  37. package/__tests__/listing.test.js +0 -437
  38. package/__tests__/logger.test.js +0 -232
  39. package/__tests__/performance.test.js +0 -370
  40. package/__tests__/publicWwwTest/cartella/sottocartella/ciao.html +0 -11
  41. package/__tests__/publicWwwTest/cartella/sottocartella/provaEjs/testEjs.ejs +0 -11
  42. package/__tests__/publicWwwTest/cartella vuota con spazi nel nome/file con spazio nel nome .txt +0 -1
  43. package/__tests__/publicWwwTest/cartella vuota con spazi nel nome /file con spazio nel nome .txt +0 -1
  44. package/__tests__/publicWwwTest/ejs-templates/complex.ejs +0 -56
  45. package/__tests__/publicWwwTest/ejs-templates/index.ejs +0 -30
  46. package/__tests__/publicWwwTest/ejs-templates/simple.ejs +0 -13
  47. package/__tests__/publicWwwTest/ejs-templates/with-conditional.ejs +0 -28
  48. package/__tests__/publicWwwTest/ejs-templates/with-escaping.ejs +0 -26
  49. package/__tests__/publicWwwTest/ejs-templates/with-loop.ejs +0 -16
  50. package/__tests__/publicWwwTest/hideext-test/about/index.html +0 -1
  51. package/__tests__/publicWwwTest/hideext-test/about.EJS +0 -1
  52. package/__tests__/publicWwwTest/hideext-test/about.ejs +0 -2
  53. package/__tests__/publicWwwTest/hideext-test/blog/articolo.ejs +0 -2
  54. package/__tests__/publicWwwTest/hideext-test/conflict-test/pagina +0 -1
  55. package/__tests__/publicWwwTest/hideext-test/conflict-test/pagina.ejs +0 -1
  56. package/__tests__/publicWwwTest/hideext-test/file.ejs.bak +0 -1
  57. package/__tests__/publicWwwTest/hideext-test/index.ejs +0 -2
  58. package/__tests__/publicWwwTest/hideext-test/photo.txt +0 -1
  59. package/__tests__/publicWwwTest/hideext-test/sezione/index.ejs +0 -1
  60. package/__tests__/publicWwwTest/hideext-test/style.css +0 -1
  61. package/__tests__/publicWwwTest/ile_vuoto.txt +0 -0
  62. package/__tests__/publicWwwTest/index.html +0 -11
  63. package/__tests__/publicWwwTest/prova file .txt +0 -2
  64. package/__tests__/publicWwwTest/semplicetxt.txt +0 -1
  65. package/__tests__/publicWwwTest/test-page.html +0 -1
  66. package/__tests__/publicWwwTest/test.txt +0 -1
  67. package/__tests__/range-fixtures/sample.txt +0 -1
  68. package/__tests__/range.test.js +0 -223
  69. package/__tests__/security-headers.test.js +0 -165
  70. package/__tests__/security.test.js +0 -322
  71. package/__tests__/server-cache-fixtures/large.txt +0 -1
  72. package/__tests__/server-cache-fixtures/small.txt +0 -1
  73. package/__tests__/server-cache.test.js +0 -594
  74. package/__tests__/setup-benchmark.js +0 -178
  75. package/__tests__/symlink.test.js +0 -441
  76. package/__tests__/template-timeout.test.js +0 -321
  77. package/__tests__/test-regex-quick.js +0 -158
  78. package/__tests__/useOriginalUrl.test.js +0 -213
  79. package/docs/ACTION_PLAN.md +0 -293
  80. package/docs/BENCHMARKS.md +0 -317
  81. package/docs/CHANGELOG.md +0 -880
  82. package/docs/CODE_REVIEW.md +0 -300
  83. package/docs/DEBUG_REPORT.md +0 -593
  84. package/docs/DOCUMENTATION.md +0 -1864
  85. package/docs/EXAMPLES_INDEX_OPTION.md +0 -395
  86. package/docs/FLOW_DIAGRAM.md +0 -954
  87. package/docs/INDEX_OPTION_PRIORITY.md +0 -527
  88. package/docs/OPTIMIZATION_HTTP_CACHING.md +0 -689
  89. package/docs/OPTIMIZATION_ROADMAP_for_V3.md +0 -864
  90. package/docs/PERFORMANCE_ANALYSIS.md +0 -839
  91. package/docs/PERFORMANCE_COMPARISON.md +0 -388
  92. package/docs/noteExports.md +0 -148
  93. package/docs/security_improvement_for_V3.md +0 -421
  94. package/docs/template-engine/TEMPLATE_ENGINE_GUIDE.md +0 -1734
  95. package/docs/template-engine/esempi-incrementali.js +0 -192
  96. package/docs/template-engine/examples/esempio1-nessun-dato.ejs +0 -12
  97. package/docs/template-engine/examples/esempio2-una-variabile.ejs +0 -11
  98. package/docs/template-engine/examples/esempio3-piu-variabili.ejs +0 -15
  99. package/docs/template-engine/examples/esempio4-condizionale.ejs +0 -18
  100. package/docs/template-engine/examples/esempio5-loop.ejs +0 -18
  101. package/docs/template-engine/examples/index-esempi.html +0 -181
  102. package/docs/template-engine/examples/index.html +0 -40
  103. package/docs/template-engine/examples/test.ejs +0 -64
  104. package/eslint.config.mjs +0 -17
  105. package/jest.config.js +0 -18
@@ -1,293 +0,0 @@
1
- # Piano d'Azione — koa-classic-server
2
-
3
- > Documento di lavoro per il miglioramento progressivo del progetto.
4
- > Ogni fase segue il ciclo: **Descrizione → Soluzioni proposte → Domande → Implementazione → Test → Avanzamento**
5
-
6
- ---
7
-
8
- ## Indice delle fasi
9
-
10
- | # | Fase | Priorità | Stato |
11
- |---|------|----------|-------|
12
- | 1 | [File nascosti nel directory listing](#fase-1--file-nascosti-nel-directory-listing) | Alta | ⬜ Da fare |
13
- | 2 | [Opzione glob per escludere file sensibili](#fase-2--opzione-glob-per-escludere-file-sensibili) | Alta | ⬜ Da fare |
14
- | 3 | [Content-Security-Policy nell'HTML generato](#fase-3--content-security-policy-nellhtml-generato) | Media | ⬜ Da fare |
15
- | 4 | [Aggiunta ESLint e standardizzazione `===`](#fase-4--aggiunta-eslint-e-standardizzazione-) | Media | ⬜ Da fare |
16
- | 5 | [Range Requests HTTP 206](#fase-5--range-requests-http-206) | Media | ⬜ Da fare |
17
- | 6 | [Gzip / Brotli compression](#fase-6--gzip--brotli-compression) | Media | ⬜ Da fare |
18
- | 7 | [Traduzione commenti in inglese nei test](#fase-7--traduzione-commenti-in-inglese-nei-test) | Bassa | ⬜ Da fare |
19
- | 8 | [Roadmap rimozione opzioni deprecate (v3.0.0)](#fase-8--roadmap-rimozione-opzioni-deprecate-v300) | Bassa | ⬜ Da fare |
20
-
21
- ---
22
-
23
- > **Legenda stato:** ⬜ Da fare · 🔄 In corso · ✅ Completato · ⏸️ In pausa
24
-
25
- ---
26
-
27
- ## Processo standard per ogni fase
28
-
29
- Per ogni fase si segue sempre questo ciclo:
30
-
31
- 1. **Descrizione** — Spiegazione del problema e del suo impatto
32
- 2. **Soluzioni proposte** — Almeno 2 alternative valutate con pro/contro
33
- 3. **Domande** — Se le informazioni disponibili sono < 90%, si chiedono chiarimenti prima di procedere
34
- 4. **Implementazione** — Modifica del codice sul branch `claude/project-review-EN6kt`
35
- 5. **Test** — Esecuzione della suite di test e verifica regressioni
36
- 6. **Avanzamento** — Aggiornamento dello stato in questo file e passaggio alla fase successiva
37
-
38
- ---
39
-
40
- ## Fase 1 — File nascosti nel directory listing
41
-
42
- **Stato:** ⬜ Da fare
43
- **Priorità:** Alta
44
- **File coinvolti:** `index.cjs` (funzione `show_dir`)
45
-
46
- ### Descrizione del problema
47
-
48
- Il directory listing mostra **tutti** i file e le cartelle presenti nella webroot, inclusi quelli che iniziano con `.` (dot files), come:
49
-
50
- - `.env` — variabili d'ambiente con credenziali
51
- - `.gitignore`, `.gitattributes` — metadati Git
52
- - `.htpasswd` — password Apache
53
- - `.DS_Store` — metadati macOS
54
- - `.npmrc` — configurazioni npm con token
55
-
56
- Server come Apache e Nginx nascondono questi file per default. Un file dimenticato nella webroot potrebbe esporre informazioni sensibili agli utenti del browser.
57
-
58
- ### Soluzioni proposte
59
-
60
- *Da definire nella sessione di lavoro dedicata a questa fase.*
61
-
62
- ### Domande
63
-
64
- *Da porre prima dell'implementazione se necessario.*
65
-
66
- ### Implementazione
67
-
68
- *Da eseguire dopo la scelta della soluzione.*
69
-
70
- ### Test
71
-
72
- *Da verificare dopo l'implementazione.*
73
-
74
- ---
75
-
76
- ## Fase 2 — Opzione glob per escludere file sensibili
77
-
78
- **Stato:** ⬜ Da fare
79
- **Priorità:** Alta
80
- **File coinvolti:** `index.cjs` (opzioni di configurazione + `show_dir`)
81
-
82
- ### Descrizione del problema
83
-
84
- Non esiste un'opzione per escludere file o cartelle specifici dal serving e dal directory listing tramite pattern (glob o RegExp). Se un file come `config.json`, `secrets.yaml` o qualsiasi altro file sensibile si trova nella webroot, viene servito senza restrizioni.
85
-
86
- Esempi di pattern utili:
87
- - `*.env` — tutti i file .env
88
- - `**/*.secret` — file con estensione .secret
89
- - `private/**` — intera cartella private
90
-
91
- ### Soluzioni proposte
92
-
93
- *Da definire nella sessione di lavoro dedicata a questa fase.*
94
-
95
- ### Domande
96
-
97
- *Da porre prima dell'implementazione se necessario.*
98
-
99
- ### Implementazione
100
-
101
- *Da eseguire dopo la scelta della soluzione.*
102
-
103
- ### Test
104
-
105
- *Da verificare dopo l'implementazione.*
106
-
107
- ---
108
-
109
- ## Fase 3 — Content-Security-Policy nell'HTML generato
110
-
111
- **Stato:** ⬜ Da fare
112
- **Priorità:** Media
113
- **File coinvolti:** `index.cjs` (funzione `show_dir`)
114
-
115
- ### Descrizione del problema
116
-
117
- Le pagine HTML generate dal directory listing non includono un header `Content-Security-Policy`. Senza CSP, il browser non ha indicazioni su quali risorse sono autorizzate, aumentando il rischio di attacchi XSS in caso di eventuali vulnerabilità future nel codice di generazione HTML.
118
-
119
- Il progetto già implementa l'escape HTML (funzione `escapeHtml`), ma aggiungere CSP è un ulteriore livello di difesa in profondità.
120
-
121
- ### Soluzioni proposte
122
-
123
- *Da definire nella sessione di lavoro dedicata a questa fase.*
124
-
125
- ### Domande
126
-
127
- *Da porre prima dell'implementazione se necessario.*
128
-
129
- ### Implementazione
130
-
131
- *Da eseguire dopo la scelta della soluzione.*
132
-
133
- ### Test
134
-
135
- *Da verificare dopo l'implementazione.*
136
-
137
- ---
138
-
139
- ## Fase 4 — Aggiunta ESLint e standardizzazione `===`
140
-
141
- **Stato:** ⬜ Da fare
142
- **Priorità:** Media
143
- **File coinvolti:** `index.cjs`, `package.json`, nuovi file di config
144
-
145
- ### Descrizione del problema
146
-
147
- Il codice usa `==` (uguaglianza debole con coercizione di tipo) in circa 25 punti, documentati in `docs/CODE_REVIEW.md`. Anche se nel contesto attuale non causano bug, l'uso di `===` è la best practice JavaScript e previene errori sottili in futuro.
148
-
149
- Inoltre il progetto non ha alcun linter o formatter configurato, il che rende difficile mantenere la coerenza stilistica nel tempo e nelle contribuzioni esterne.
150
-
151
- ### Soluzioni proposte
152
-
153
- *Da definire nella sessione di lavoro dedicata a questa fase.*
154
-
155
- ### Domande
156
-
157
- *Da porre prima dell'implementazione se necessario.*
158
-
159
- ### Implementazione
160
-
161
- *Da eseguire dopo la scelta della soluzione.*
162
-
163
- ### Test
164
-
165
- *Da verificare dopo l'implementazione.*
166
-
167
- ---
168
-
169
- ## Fase 5 — Range Requests HTTP 206
170
-
171
- **Stato:** ⬜ Da fare
172
- **Priorità:** Media
173
- **File coinvolti:** `index.cjs` (logica di file serving)
174
-
175
- ### Descrizione del problema
176
-
177
- Il middleware non supporta l'header `Range` delle richieste HTTP. Questo significa che:
178
-
179
- - File audio e video non possono essere riprodotti in streaming dai browser
180
- - Download di file grandi non possono essere ripresi dopo interruzione
181
- - Strumenti come `curl --range` non funzionano
182
-
183
- Il supporto HTTP 206 (Partial Content) è lo standard per la distribuzione di contenuti multimediali e file di grandi dimensioni.
184
-
185
- ### Soluzioni proposte
186
-
187
- *Da definire nella sessione di lavoro dedicata a questa fase.*
188
-
189
- ### Domande
190
-
191
- *Da porre prima dell'implementazione se necessario.*
192
-
193
- ### Implementazione
194
-
195
- *Da eseguire dopo la scelta della soluzione.*
196
-
197
- ### Test
198
-
199
- *Da verificare dopo l'implementazione.*
200
-
201
- ---
202
-
203
- ## Fase 6 — Gzip / Brotli compression
204
-
205
- **Stato:** ⬜ Da fare
206
- **Priorità:** Media
207
- **File coinvolti:** `index.cjs`, `package.json`
208
-
209
- ### Descrizione del problema
210
-
211
- Il middleware serve tutti i file senza compressione. Per file di testo (HTML, CSS, JS, JSON, SVG), la compressione può ridurre le dimensioni del 60-80%, con impatto diretto su:
212
-
213
- - Velocità di caricamento per gli utenti
214
- - Consumo di banda del server
215
- - Score Lighthouse / Web Vitals
216
-
217
- ### Soluzioni proposte
218
-
219
- *Da definire nella sessione di lavoro dedicata a questa fase.*
220
-
221
- ### Domande
222
-
223
- *Da porre prima dell'implementazione se necessario.*
224
-
225
- ### Implementazione
226
-
227
- *Da eseguire dopo la scelta della soluzione.*
228
-
229
- ### Test
230
-
231
- *Da verificare dopo l'implementazione.*
232
-
233
- ---
234
-
235
- ## Fase 7 — Traduzione commenti in inglese nei test
236
-
237
- **Stato:** ⬜ Da fare
238
- **Priorità:** Bassa
239
- **File coinvolti:** `__tests__/dt-unknown.test.js` e altri
240
-
241
- ### Descrizione del problema
242
-
243
- Alcuni file di test contengono commenti in italiano, il che riduce l'accessibilità del codice per i contribuenti internazionali. Per un progetto open source pubblicato su npm, la lingua standard della codebase dovrebbe essere l'inglese.
244
-
245
- ### Soluzioni proposte
246
-
247
- *Da definire nella sessione di lavoro dedicata a questa fase.*
248
-
249
- ### Domande
250
-
251
- *Da porre prima dell'implementazione se necessario.*
252
-
253
- ### Implementazione
254
-
255
- *Da eseguire dopo la scelta della soluzione.*
256
-
257
- ### Test
258
-
259
- *Da verificare dopo l'implementazione.*
260
-
261
- ---
262
-
263
- ## Fase 8 — Roadmap rimozione opzioni deprecate (v3.0.0)
264
-
265
- **Stato:** ⬜ Da fare
266
- **Priorità:** Bassa
267
- **File coinvolti:** `index.cjs`, `docs/CHANGELOG.md`, `README.md`
268
-
269
- ### Descrizione del problema
270
-
271
- Le opzioni legacy `cacheMaxAge` ed `enableCaching` sono ancora supportate con deprecation warning ma non hanno una data di rimozione pianificata. Mantenerle a tempo indeterminato appesantisce il codice e può confondere i nuovi utenti che leggono la documentazione.
272
-
273
- Una roadmap chiara verso `v3.0.0` con breaking changes definiti aiuta gli utenti a pianificare la migrazione.
274
-
275
- ### Soluzioni proposte
276
-
277
- *Da definire nella sessione di lavoro dedicata a questa fase.*
278
-
279
- ### Domande
280
-
281
- *Da porre prima dell'implementazione se necessario.*
282
-
283
- ### Implementazione
284
-
285
- *Da eseguire dopo la scelta della soluzione.*
286
-
287
- ### Test
288
-
289
- *Da verificare dopo l'implementazione.*
290
-
291
- ---
292
-
293
- *Documento aggiornato: 2026-03-21*
@@ -1,317 +0,0 @@
1
- # Performance Benchmarks
2
-
3
- This directory contains comprehensive performance benchmarks for `koa-classic-server`.
4
-
5
- ## Purpose
6
-
7
- These benchmarks measure:
8
- - **Response times** for different file sizes
9
- - **Directory listing performance** for various sizes
10
- - **Concurrent request handling**
11
- - **Memory usage**
12
- - **Throughput** (requests/second, MB/second)
13
-
14
- ## Quick Start
15
-
16
- ### 1. Setup Benchmark Data
17
-
18
- First, create the test files and directories:
19
-
20
- ```bash
21
- npm run benchmark:setup
22
- ```
23
-
24
- This creates:
25
- - `benchmark-data/small-files/` - 100 files × 1KB
26
- - `benchmark-data/medium-files/` - 50 files × 100KB
27
- - `benchmark-data/large-files/` - 10 files × 1MB
28
- - `benchmark-data/large-directory/` - 1,000 files for listing test
29
- - `benchmark-data/very-large-directory/` - 10,000 files for stress test
30
- - `benchmark-data/nested/` - 5 levels deep directory structure
31
-
32
- Total: ~15 MB of test data
33
-
34
- ### 2. Run Jest Performance Tests
35
-
36
- ```bash
37
- npm run test:performance
38
- ```
39
-
40
- This runs comprehensive tests measuring:
41
- - Individual file serving times
42
- - Directory listing times
43
- - Concurrent request handling
44
- - 404 error handling
45
- - Memory usage
46
-
47
- **Save results:**
48
- ```bash
49
- npm run test:performance > results-baseline-v1.2.0.txt
50
- ```
51
-
52
- ### 3. Run HTTP Load Tests (autocannon)
53
-
54
- ```bash
55
- npm run benchmark
56
- ```
57
-
58
- This performs realistic load testing with:
59
- - 10 seconds per scenario
60
- - 5-10 concurrent connections
61
- - Measures requests/sec, latency, throughput
62
-
63
- **Save results for comparison:**
64
- ```bash
65
- npm run benchmark:save baseline-v1.2.0.json
66
- ```
67
-
68
- ## Workflow: Before/After Optimization
69
-
70
- ### Step 1: Baseline (BEFORE optimization)
71
-
72
- ```bash
73
- # Setup test data
74
- npm run benchmark:setup
75
-
76
- # Run tests and save results
77
- npm run test:performance > results-before.txt
78
- npm run benchmark:save baseline-before.json
79
- ```
80
-
81
- ### Step 2: Apply Optimizations
82
-
83
- Make code changes to improve performance...
84
-
85
- ### Step 3: Compare (AFTER optimization)
86
-
87
- ```bash
88
- # Run tests again
89
- npm run test:performance > results-after.txt
90
- npm run benchmark:save baseline-after.json --compare baseline-before.json
91
- ```
92
-
93
- ### Step 4: Analyze Differences
94
-
95
- ```bash
96
- # Compare test results
97
- diff results-before.txt results-after.txt
98
-
99
- # Benchmark comparison is shown automatically
100
- ```
101
-
102
- ## Expected Improvements
103
-
104
- After implementing the optimizations from `PERFORMANCE_ANALYSIS.md`:
105
-
106
- | Metric | Before | After | Improvement |
107
- |--------|--------|-------|-------------|
108
- | Small file (1KB) | ~2.5ms | ~0.5ms | **80% faster** |
109
- | Directory (1,000 files) | ~120ms | ~40ms | **67% faster** |
110
- | Directory (10,000 files) | ~1,800ms | ~450ms | **75% faster** |
111
- | Concurrent requests | Sequential | Parallel | **5-10x faster** |
112
- | Memory (10k directory) | ~25MB | ~15MB | **40% less** |
113
-
114
- With HTTP caching enabled:
115
- | Metric | Before | After | Improvement |
116
- |--------|--------|-------|-------------|
117
- | Cached file | 2.5ms | 0.1ms | **96% faster** |
118
- | Bandwidth | 100% | 5% | **95% reduction** |
119
-
120
- ## Understanding the Results
121
-
122
- ### Jest Performance Tests
123
-
124
- Output includes:
125
- - **Average time**: Mean across all iterations
126
- - **Median time**: 50th percentile (less affected by outliers)
127
- - **Min/Max time**: Range of values
128
- - **Warnings**: Areas where optimizations will have big impact
129
-
130
- Example output:
131
- ```
132
- 📊 Large Directory (1,000 files) Benchmark:
133
- Average: 123.45ms
134
- Median: 120.30ms
135
- Min: 110.20ms
136
- Max: 145.80ms
137
- ⚠️ WARNING: This will be MUCH faster after async optimization
138
- ```
139
-
140
- ### Autocannon Load Tests
141
-
142
- Output includes:
143
- - **Requests/sec**: How many requests the server can handle per second
144
- - **Latency**: Response time (avg, p50, p99)
145
- - **Throughput**: Data transferred per second (MB/sec)
146
-
147
- Example output:
148
- ```
149
- Scenario | Req/sec | Latency (avg) | Throughput
150
- ----------------------------------|---------|---------------|-------------
151
- Small file (1KB) | 2500 | 4.00ms | 2.44 MB/s
152
- Directory listing (1,000 files) | 80 | 125.00ms | 15.60 MB/s
153
- ```
154
-
155
- Higher **Requests/sec** = Better ✅
156
- Lower **Latency** = Better ✅
157
- Higher **Throughput** = Better ✅
158
-
159
- ## Interpreting Latency Percentiles
160
-
161
- - **p50 (median)**: 50% of requests complete in this time
162
- - **p75**: 75% of requests complete in this time
163
- - **p90**: 90% of requests complete in this time
164
- - **p99**: 99% of requests complete in this time
165
- - **p999**: 99.9% of requests complete in this time
166
-
167
- **Why p99 matters:**
168
- - p50 might be 10ms, but p99 could be 100ms
169
- - This means 1% of users experience 10× slower responses
170
- - Optimizations should improve both average AND p99
171
-
172
- ## Memory Usage Tests
173
-
174
- Memory tests show:
175
- - **Heap used**: JavaScript objects, strings, arrays
176
- - **External**: Buffers, native objects
177
- - **Response size**: Size of HTML/data generated
178
-
179
- **What to look for:**
180
- - Large heap increase = memory leaks or inefficient allocation
181
- - After optimization: should see 30-40% reduction
182
-
183
- ## Directory Structure
184
-
185
- ```
186
- koa-classic-server/
187
- ├── benchmark-data/ # Test data (git-ignored, ~15MB)
188
- │ ├── small-files/
189
- │ ├── medium-files/
190
- │ ├── large-files/
191
- │ ├── large-directory/
192
- │ └── very-large-directory/
193
- ├── scripts/
194
- │ └── setup-benchmark.js # Creates test data
195
- ├── __tests__/
196
- │ └── performance.test.js # Jest performance tests
197
- ├── benchmark.js # Autocannon load tests
198
- └── BENCHMARKS.md # This file
199
- ```
200
-
201
- ## Troubleshooting
202
-
203
- ### "Benchmark data not found"
204
-
205
- Run: `npm run benchmark:setup`
206
-
207
- ### Tests timeout
208
-
209
- Increase Jest timeout in `performance.test.js`:
210
- ```javascript
211
- test('...', async () => { ... }, 60000); // 60 seconds
212
- ```
213
-
214
- ### Out of memory
215
-
216
- Reduce iterations or skip very-large-directory tests:
217
- ```javascript
218
- test.skip('Very large directory...', async () => { ... });
219
- ```
220
-
221
- ### Inconsistent results
222
-
223
- - Close other applications
224
- - Run multiple times and average results
225
- - Check system load: `top` or `htop`
226
- - Disable CPU throttling
227
-
228
- ## Best Practices
229
-
230
- 1. **Run on idle system**: Close browsers, apps
231
- 2. **Run multiple times**: Results vary, average 3+ runs
232
- 3. **Same environment**: Use same machine for before/after
233
- 4. **Document environment**: Note CPU, RAM, Node version
234
- 5. **Save results**: Use `> file.txt` to save for comparison
235
-
236
- ## Example: Complete Before/After Test
237
-
238
- ```bash
239
- # === BEFORE OPTIMIZATION ===
240
-
241
- # Setup
242
- npm run benchmark:setup
243
-
244
- # Jest tests
245
- npm run test:performance > results-v1.2.0-before.txt
246
-
247
- # Load tests
248
- npm run benchmark:save baseline-v1.2.0.json
249
-
250
- # === APPLY OPTIMIZATIONS ===
251
- # Edit index.cjs...
252
-
253
- # === AFTER OPTIMIZATION ===
254
-
255
- # Jest tests
256
- npm run test:performance > results-v1.3.0-after.txt
257
-
258
- # Load tests with comparison
259
- node benchmark.js --save baseline-v1.3.0.json --compare baseline-v1.2.0.json
260
-
261
- # Review differences
262
- diff results-v1.2.0-before.txt results-v1.3.0-after.txt
263
- ```
264
-
265
- ## Environment Information
266
-
267
- When reporting results, include:
268
-
269
- ```bash
270
- node --version
271
- npm --version
272
- cat /proc/cpuinfo | grep "model name" | head -n 1
273
- free -h
274
- ```
275
-
276
- Example:
277
- ```
278
- Node.js: v20.10.0
279
- npm: 10.2.3
280
- CPU: Intel(R) Core(TM) i7-9750H @ 2.60GHz
281
- RAM: 16GB
282
- OS: Ubuntu 22.04 LTS
283
- ```
284
-
285
- ## Next Steps
286
-
287
- After running baseline benchmarks:
288
-
289
- 1. Review `PERFORMANCE_ANALYSIS.md` for optimization recommendations
290
- 2. Review `OPTIMIZATION_HTTP_CACHING.md` for HTTP caching details
291
- 3. Implement Priority 1 optimizations:
292
- - Convert sync operations to async
293
- - Fix string concatenation in `show_dir()`
294
- - Add HTTP caching headers
295
- 4. Re-run benchmarks to measure improvements
296
- 5. Update to v1.3.0 "Performance Edition"
297
-
298
- ## Contributing
299
-
300
- When submitting performance improvements:
301
-
302
- 1. Run baseline benchmarks BEFORE changes
303
- 2. Apply your optimization
304
- 3. Run benchmarks AFTER changes
305
- 4. Include both results in PR
306
- 5. Document the optimization approach
307
-
308
- ## Resources
309
-
310
- - [autocannon documentation](https://github.com/mcollina/autocannon)
311
- - [Jest performance testing](https://jestjs.io/docs/timer-mocks)
312
- - [Node.js performance best practices](https://nodejs.org/en/docs/guides/simple-profiling/)
313
-
314
- ---
315
-
316
- **Last updated**: 2025-11-18
317
- **Version**: 1.2.0 (baseline)