diff options
| author | Claude <noreply@anthropic.com> | 2026-02-16 18:15:47 +0000 |
|---|---|---|
| committer | Claude <noreply@anthropic.com> | 2026-02-16 18:15:47 +0000 |
| commit | d4caf45b2b9ea6a3276de792cf6f73085e66b1ae (patch) | |
| tree | 3a8b7b1d9277ba0db4c946fea43043d65220fd8d /frontend-vanilla/src/perf/renderItems.perf.test.ts | |
| parent | c9c5def76c3a3340373143f846454b795d296c82 (diff) | |
| download | neko-d4caf45b2b9ea6a3276de792cf6f73085e66b1ae.tar.gz neko-d4caf45b2b9ea6a3276de792cf6f73085e66b1ae.tar.bz2 neko-d4caf45b2b9ea6a3276de792cf6f73085e66b1ae.zip | |
Add performance benchmarks, stress tests, and frontend perf tests
Go benchmarks cover item CRUD/filter/sanitization, API endpoints (stream,
item update, feed list), middleware stack (gzip, security headers, CSRF),
and crawler pipeline (feed parsing, mocked crawl). Stress tests verify
concurrent reads/writes and large dataset handling. Frontend perf tests
measure template generation, DOM insertion, and store event throughput.
New Makefile targets: bench, bench-short, stress, test-perf.
https://claude.ai/code/session_01ChDVWFDrQoFjMYHpaLGr9s
Diffstat (limited to 'frontend-vanilla/src/perf/renderItems.perf.test.ts')
| -rw-r--r-- | frontend-vanilla/src/perf/renderItems.perf.test.ts | 90 |
1 files changed, 90 insertions, 0 deletions
diff --git a/frontend-vanilla/src/perf/renderItems.perf.test.ts b/frontend-vanilla/src/perf/renderItems.perf.test.ts new file mode 100644 index 0000000..3dd2ed7 --- /dev/null +++ b/frontend-vanilla/src/perf/renderItems.perf.test.ts @@ -0,0 +1,90 @@ +import { describe, it, expect } from 'vitest'; +import { createFeedItem } from '../components/FeedItem'; +import type { Item } from '../types'; + +function makeItem(id: number): Item { + return { + _id: id, + feed_id: 1, + title: `Test Item ${id}`, + url: `https://example.com/item/${id}`, + description: `<p>Description for item ${id} with <b>bold</b> and <a href="https://example.com">link</a></p>`, + publish_date: '2024-01-01T00:00:00Z', + read: id % 3 === 0, + starred: id % 5 === 0, + feed_title: 'Test Feed', + }; +} + +describe('renderItems performance', () => { + it('createFeedItem renders 100 items under 50ms', () => { + const items = Array.from({ length: 100 }, (_, i) => makeItem(i)); + + const start = performance.now(); + const html = items.map(item => createFeedItem(item)).join(''); + const elapsed = performance.now() - start; + + expect(html).toBeTruthy(); + expect(html).toContain('feed-item'); + expect(elapsed).toBeLessThan(50); + }); + + it('createFeedItem renders 500 items under 200ms', () => { + const items = Array.from({ length: 500 }, (_, i) => makeItem(i)); + + const start = performance.now(); + const html = items.map(item => createFeedItem(item)).join(''); + const elapsed = performance.now() - start; + + expect(html).toBeTruthy(); + expect(elapsed).toBeLessThan(200); + }); + + it('createFeedItem renders 1000 items under 100ms', () => { + const items = Array.from({ length: 1000 }, (_, i) => makeItem(i)); + + const start = performance.now(); + const results: string[] = []; + for (const item of items) { + results.push(createFeedItem(item)); + } + const elapsed = performance.now() - start; + + expect(results.length).toBe(1000); + expect(elapsed).toBeLessThan(100); + }); + + it('DOM insertion of 100 items under 200ms', () => { + const items = Array.from({ length: 100 }, (_, i) => makeItem(i)); + const html = items.map(item => createFeedItem(item)).join(''); + + const container = document.createElement('ul'); + document.body.appendChild(container); + + const start = performance.now(); + container.innerHTML = html; + const elapsed = performance.now() - start; + + expect(container.children.length).toBe(100); + expect(elapsed).toBeLessThan(200); + + document.body.removeChild(container); + }); + + it('DOM insertion of 500 items under 500ms', () => { + const items = Array.from({ length: 500 }, (_, i) => makeItem(i)); + const html = items.map(item => createFeedItem(item)).join(''); + + const container = document.createElement('ul'); + document.body.appendChild(container); + + const start = performance.now(); + container.innerHTML = html; + const elapsed = performance.now() - start; + + expect(container.children.length).toBe(500); + expect(elapsed).toBeLessThan(500); + + document.body.removeChild(container); + }); +}); |
