Skip to content

vite.config: optimize memory and fix symlink loop#23

Merged
pietrushnic merged 5 commits intomainfrom
feature/vite-memory-fixes
Mar 3, 2026
Merged

vite.config: optimize memory and fix symlink loop#23
pietrushnic merged 5 commits intomainfrom
feature/vite-memory-fixes

Conversation

@pietrushnic
Copy link
Copy Markdown
Member

  • Disable HMR error overlay to reduce memory consumption
  • Add file watching optimizations (disable polling, 1s interval)
  • Ignore slides/tools/** and slides/slidev-template/** patterns to prevent infinite symlink loop in file watcher (ELOOP errors)
  • Configure vendor chunk splitting to reduce memory pressure
  • Exclude @slidev/cli from pre-bundling optimization
  • Add build-time rollup optimizations for chunking

scripts/render-slides: expose GC API for better memory management

  • Add --expose-gc to NODE_OPTIONS to allow manual garbage collection
  • Helps Vite/Slidev plugins manage memory more effectively

These changes address memory exhaustion issues when running Slidev dev server with Vite 7, which has known HMR memory leaks.

@pietrushnic pietrushnic force-pushed the scripts-improve-docker-helpers branch from c3707bf to ca45381 Compare November 22, 2025 00:03
@pietrushnic pietrushnic force-pushed the feature/vite-memory-fixes branch from ae74262 to 718bc58 Compare November 22, 2025 00:05
@pietrushnic pietrushnic force-pushed the scripts-improve-docker-helpers branch from ca45381 to afa8537 Compare January 21, 2026 14:29
pietrushnic added a commit that referenced this pull request Jan 21, 2026
Add test infrastructure for validating slidev-template features:
- playwright.config.ts: Playwright test configuration
- tests/smoke.spec.ts: Validates render-slides.sh and gen_slides.sh
- tests/visual-regression.spec.ts: Screenshot comparison for layouts

Tests cover PR #22 (docker helpers) and PR #23 (vite memory fixes):
- Dev server startup validation
- Symlink creation for /slides/ paths
- Memory limit handling
- Visual regression for slide layouts

Signed-off-by: Piotr Król <piotr.krol@3mdeb.com>
@pietrushnic pietrushnic force-pushed the scripts-improve-docker-helpers branch 2 times, most recently from f491e8a to ae8bb22 Compare January 21, 2026 14:47
Base automatically changed from scripts-improve-docker-helpers to main January 21, 2026 15:40
@pietrushnic pietrushnic force-pushed the feature/vite-memory-fixes branch from 718bc58 to 6ec86f7 Compare January 23, 2026 09:31
@pietrushnic pietrushnic requested a review from macpijan January 23, 2026 09:32
@pietrushnic
Copy link
Copy Markdown
Member Author

Those are partially recommended partially AI-researched changes. I was using those changes for quite some time without any memory issues or loops for various sizes of presentations. So question what should be an evidence here to merge this?

@m-iwanicki
Copy link
Copy Markdown
Contributor

Does polling has to be disabled? I need to restart whole slidev to see updated slides, unless there is better method?

@pietrushnic
Copy link
Copy Markdown
Member Author

Does polling has to be disabled? I need to restart whole slidev to see updated slides, unless there is better method?

It really depends on the change, methods I use for refresh:

  1. for serious CSS changes or if I really can't see any update (e.g. change of image and cache reset doesn't work) I just disable
  2. I hit r in slidev render-slides.sh terminal
  3. hit ctrl+r in web browser
  4. do nothing - it works very good in most cases

I'm not sure in what part of developer workflow you see the effect you mention.

@m-iwanicki
Copy link
Copy Markdown
Contributor

I'm not sure in what part of developer workflow you see the effect you mention.

Even simple letter change requires me to restart slidev (point 2)

pietrushnic added a commit that referenced this pull request Feb 24, 2026
Add Playwright test that modifies slide content on disk and verifies
the browser picks up the change without a manual page reload.

This addresses m-iwanicki's review on PR #23 where usePolling: false
broke HMR. The previous commit removes the explicit usePolling setting,
letting Vite auto-detect. This test ensures HMR keeps working.

Mount test-repo volume into Playwright container so the HMR test
can write to the slide file that the dev server watches.

Signed-off-by: Piotr Król <piotr.krol@3mdeb.com>
@pietrushnic pietrushnic force-pushed the feature/vite-memory-fixes branch from 6ec86f7 to 2112c55 Compare February 24, 2026 08:38
@pietrushnic pietrushnic changed the base branch from main to fix/visual-regression-baselines February 24, 2026 09:18
@pietrushnic
Copy link
Copy Markdown
Member Author

@m-iwanicki I tried to fix and validated what you see. I added tests to make sure feature will not regress:

% SLIDEV_PORT=8002 ./scripts/run-tests.sh
Setting up test presentation repo...
HEAD is now at 4a079d568381 test: add HMR broken fixture for regression proof
Test repo ready
Starting dev server on port 8002...
Waiting for dev server to be ready...
Dev server is ready
Running Playwright tests...

Running 21 tests using 1 worker

  ✓   1 [chromium] › tests/hmr.spec.ts:23:3 › Hot Module Replacement › slide content updates after file change without reload (6.9s)
  ✓   2 [chromium] › tests/smoke.spec.ts:17:3 › Dev Server › responds on configured port (461ms)
  ✓   3 [chromium] › tests/smoke.spec.ts:22:3 › Dev Server › theme loads without console errors (2.6s)
  ✓   4 [chromium] › tests/smoke.spec.ts:44:3 › Dev Server › src: directive renders content (1.5s)
  ✓   5 [chromium] › tests/smoke.spec.ts:55:3 › Navigation › all slides load without OOM (15.2s)
  ✓   6 [chromium] › tests/smoke.spec.ts:64:3 › Navigation › presenter mode accessible (467ms)
  ✓   7 [chromium] › tests/smoke.spec.ts:69:3 › Navigation › overview mode accessible (443ms)
  ✓   8 [chromium] › tests/smoke.spec.ts:76:3 › Assets › images load without errors (2.0s)
  ✓   9 [chromium] › tests/smoke.spec.ts:92:3 › Keyboard Navigation › vim keys navigate slides (h/l) (2.8s)
  ✓  10 [chromium] › tests/smoke.spec.ts:110:3 › Keyboard Navigation › vim keys navigate slides (j/k) (2.9s)
  ✓  11 [chromium] › tests/visual-regression.spec.ts:13:3 › Layouts › cover (2.3s)
  ✓  12 [chromium] › tests/visual-regression.spec.ts:23:3 › Layouts › two-cols (2.2s)
  ✓  13 [chromium] › tests/visual-regression.spec.ts:33:3 › Layouts › two-cols-header (2.1s)
  ✓  14 [chromium] › tests/visual-regression.spec.ts:43:3 › Layouts › quote (2.1s)
  ✓  15 [chromium] › tests/visual-regression.spec.ts:55:3 › Components › figure with figcaption (2.1s)
  ✓  16 [chromium] › tests/visual-regression.spec.ts:67:3 › Components › Footnotes (2.2s)
  ✓  17 [chromium] › tests/visual-regression.spec.ts:78:3 › Components › table (2.1s)
  ✓  18 [chromium] › tests/visual-regression.spec.ts:91:3 › Footer › visible on content slides (1.5s)
  ✓  19 [chromium] › tests/visual-regression.spec.ts:99:3 › Footer › hidden on cover slides (1.5s)
  ✓  20 [chromium] › tests/visual-regression.spec.ts:107:3 › Presenter Mode › renders with notes panel (2.5s)
  ✓  21 [chromium] › tests/visual-regression.spec.ts:119:3 › Font Size Classes › code-10px and code-12px apply correctly (2.2s)

  21 passed (59.4s)
All tests passed!
Cleaning up...
slidev-test-server-1070693

pietrushnic added a commit that referenced this pull request Feb 24, 2026
Add Playwright test that modifies slide content on disk and verifies
the browser picks up the change without a manual page reload.

This addresses m-iwanicki's review on PR #23 where usePolling: false
broke HMR. The previous commit removes the explicit usePolling setting,
letting Vite auto-detect. This test ensures HMR keeps working.

Mount test-repo volume into Playwright container so the HMR test
can write to the slide file that the dev server watches.

Signed-off-by: Piotr Król <piotr.krol@3mdeb.com>
@pietrushnic pietrushnic force-pushed the feature/vite-memory-fixes branch from 2112c55 to 4a079d5 Compare February 24, 2026 11:30
@m-iwanicki
Copy link
Copy Markdown
Contributor

Hmmm, still doesn't work for me, even opened slide in new browser just to make sure it's not cache fault. How I tested it:

  1. Clone zarhus/presentations and it's submodules
  2. Checkout feature/vite-memory-fixes (in slidev-template)
  3. Render slide e.g.: ./slidev-template/scripts/render-slides.sh pages/zdm_3/dts.md
  4. Open slides in your browser: http://localhost:8000/
  5. Modify text in any slide in dts.md and check if it'll change in browser

Results:

No changes, not even when refreshing or opening slides in new browser.

Base automatically changed from fix/visual-regression-baselines to main March 2, 2026 19:38
@pietrushnic pietrushnic mentioned this pull request Mar 3, 2026
- Disable HMR error overlay to reduce memory consumption
- Add file watching optimizations (disable polling, 1s interval)
- Ignore slides/tools/** and slides/slidev-template/** patterns
  to prevent infinite symlink loop in file watcher (ELOOP errors)
- Configure vendor chunk splitting to reduce memory pressure
- Exclude @slidev/cli from pre-bundling optimization
- Add build-time rollup optimizations for chunking

scripts/render-slides: expose GC API for better memory management

- Add --expose-gc to NODE_OPTIONS to allow manual garbage collection
- Helps Vite/Slidev plugins manage memory more effectively

These changes address memory exhaustion issues when running Slidev
dev server with Vite 7, which has known HMR memory leaks.

Signed-off-by: Piotr Król <piotr.krol@3mdeb.com>
Add Playwright test that modifies slide content on disk and verifies
the browser picks up the change without a manual page reload.

This addresses m-iwanicki's review on PR #23 where usePolling: false
broke HMR. The previous commit removes the explicit usePolling setting,
letting Vite auto-detect. This test ensures HMR keeps working.

Mount test-repo volume into Playwright container so the HMR test
can write to the slide file that the dev server watches.

Signed-off-by: Piotr Król <piotr.krol@3mdeb.com>
Add vite-config-hmr-disabled.ts fixture that sets hmr: false in
vite.config.ts. When applied, the HMR test correctly fails, proving
it detects when file changes stop propagating to the browser.

Verified: ./scripts/run-tests.sh broken hmr → PROOF COMPLETE

Signed-off-by: Piotr Król <piotr.krol@3mdeb.com>
The `slides -> ..` symlink causes chokidar to report file changes
through recursive symlink-traversed paths instead of canonical paths.
Setting `followSymlinks: false` ensures Slidev's watchFiles map
matches the reported paths, fixing HMR for external files.

Also adds test-hmr-external.sh that reproduces the real developer
workflow (host file edit -> Docker dev server -> browser HMR) and
reduces broken fixture test verbosity (quiet on pass, verbose on fail).

Signed-off-by: Piotr Król <piotr.krol@3mdeb.com>
sed -i and git checkout replace file inodes, causing chokidar's
inotify watches to break on subsequent edits. Polling via fs.stat()
is immune to inode changes and is the standard Docker workaround.

Signed-off-by: Piotr Król <piotr.krol@3mdeb.com>
@pietrushnic
Copy link
Copy Markdown
Member Author

pietrushnic commented Mar 3, 2026

@m-iwanicki @macpijan I did it one more time, tested carefully:

  1. in zarhus/presentation: SLIDEV_PORT=8011 ./slidev-template/scripts/render-slides.sh pages/zdm_3/1-greetings-agenda.md
  2. Open localhost:8011/2 - check content
brave_screenshot_ollama local
  1. In other terminal: sed -i 's/Welcome/CHANGED Welcome/' ~/src/3mdeb/zarhus/presentations/pages/zdm_3/1-greetings-agenda.md
brave_screenshot_ollama local (1)
  1. git checkout -f .
brave_screenshot_ollama local (2)

Test results:

% SLIDEV_PORT=8082 ./scripts/run-tests.sh
Setting up test presentation repo...
HEAD is now at 4627c876183f fix: use polling for reliable HMR in Docker bind mounts
Test repo ready
Starting dev server on port 8082...
Waiting for dev server to be ready...
Dev server is ready
Running Playwright tests...

Running 21 tests using 1 worker

  ✓   1 [chromium] › tests/hmr.spec.ts:23:3 › Hot Module Replacement › slide content updates after file change without reload (6.2s)
  ✓   2 [chromium] › tests/smoke.spec.ts:17:3 › Dev Server › responds on configured port (535ms)
  ✓   3 [chromium] › tests/smoke.spec.ts:22:3 › Dev Server › theme loads without console errors (3.6s)
  ✓   4 [chromium] › tests/smoke.spec.ts:44:3 › Dev Server › src: directive renders content (1.5s)
  ✓   5 [chromium] › tests/smoke.spec.ts:55:3 › Navigation › all slides load without OOM (16.8s)
  ✓   6 [chromium] › tests/smoke.spec.ts:64:3 › Navigation › presenter mode accessible (531ms)
  ✓   7 [chromium] › tests/smoke.spec.ts:69:3 › Navigation › overview mode accessible (1.1s)
  ✓   8 [chromium] › tests/smoke.spec.ts:76:3 › Assets › images load without errors (2.1s)
  ✓   9 [chromium] › tests/smoke.spec.ts:92:3 › Keyboard Navigation › vim keys navigate slides (h/l) (2.9s)
  ✓  10 [chromium] › tests/smoke.spec.ts:110:3 › Keyboard Navigation › vim keys navigate slides (j/k) (2.9s)
  ✓  11 [chromium] › tests/visual-regression.spec.ts:13:3 › Layouts › cover (2.2s)
  ✓  12 [chromium] › tests/visual-regression.spec.ts:23:3 › Layouts › two-cols (3.4s)
  ✓  13 [chromium] › tests/visual-regression.spec.ts:33:3 › Layouts › two-cols-header (2.7s)
  ✓  14 [chromium] › tests/visual-regression.spec.ts:43:3 › Layouts › quote (2.2s)
  ✓  15 [chromium] › tests/visual-regression.spec.ts:55:3 › Components › figure with figcaption (2.2s)
  ✓  16 [chromium] › tests/visual-regression.spec.ts:67:3 › Components › Footnotes (2.2s)
  ✓  17 [chromium] › tests/visual-regression.spec.ts:78:3 › Components › table (2.2s)
  ✓  18 [chromium] › tests/visual-regression.spec.ts:91:3 › Footer › visible on content slides (1.4s)
  ✓  19 [chromium] › tests/visual-regression.spec.ts:99:3 › Footer › hidden on cover slides (1.6s)
  ✓  20 [chromium] › tests/visual-regression.spec.ts:107:3 › Presenter Mode › renders with notes panel (2.6s)
  ✓  21 [chromium] › tests/visual-regression.spec.ts:119:3 › Font Size Classes › code-10px and code-12px apply correctly (2.2s)

  21 passed (1.1m)
All tests passed!
Cleaning up...
slidev-test-server-3316854
[13:37:27 pietrushnic@ollama ~/src/3mdeb/zarhus/presentations/slidev-template(feature)]
% SLIDEV_PORT=8082 ./scripts/run-tests.sh broken
Running 12 broken fixture tests...

✓ src-directive
slidev-test-server-3318059
Cleaning up...
Cleanup complete
✓ images
slidev-test-server-3318059
Cleaning up...
Cleanup complete
✓ cover
slidev-test-server-3318059
Cleaning up...
Cleanup complete
✓ two-cols
slidev-test-server-3318059
Cleaning up...
Cleanup complete
✓ two-cols-header
slidev-test-server-3318059
Cleaning up...
Cleanup complete
✓ quote
slidev-test-server-3318059
Cleaning up...
Cleanup complete
✓ figure
slidev-test-server-3318059
Cleaning up...
Cleanup complete
✓ footnotes
slidev-test-server-3318059
Cleaning up...
Cleanup complete
✓ table
slidev-test-server-3318059
Cleaning up...
Cleanup complete
✓ footer-visible
slidev-test-server-3318059
Cleaning up...
Cleanup complete
✓ footer-hidden
slidev-test-server-3318059
Cleaning up...
Cleanup complete
✓ hmr
slidev-test-server-3318059
Cleaning up...
Cleanup complete

All 12 broken fixture tests passed ✓
Cleaning up...

@pietrushnic pietrushnic force-pushed the feature/vite-memory-fixes branch from 4a079d5 to a17cdee Compare March 3, 2026 12:51
Copy link
Copy Markdown
Member

@macpijan macpijan left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@pietrushnic It works the same for me. I get instant change in Firefox browser when changing sources as you do in your scenario.

@macpijan
Copy link
Copy Markdown
Member

macpijan commented Mar 3, 2026

Tets pass for me as well just fine.

@pietrushnic pietrushnic merged commit 9f92c1c into main Mar 3, 2026
@pietrushnic pietrushnic deleted the feature/vite-memory-fixes branch March 3, 2026 14:31
@m-iwanicki
Copy link
Copy Markdown
Contributor

@pietrushnic

I did it one more time, tested carefully

Yes, now it works 👍

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants