viewfit 0.0.1 → 0.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.
package/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 Andrea Bonacci
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
package/README.md CHANGED
@@ -1,8 +1,146 @@
1
1
  # ViewFit
2
2
 
3
- A JavaScript library currently under active development. Coming soon with initial features!
3
+ Fit and compress every image to the size it is actually rendered at, using a real headless browser.
4
4
 
5
- ## Installation
5
+ ViewFit opens your site in Chromium, measures each `<img>` and CSS `background-image` with `getBoundingClientRect()`, applies the device pixel ratio, and recommends a per-image target size. Sharp then resizes and compresses each file individually instead of applying one generic setting to everything.
6
+
7
+ ## Requirements
8
+
9
+ - Node.js >= 18
10
+ - A Chromium browser for Playwright:
11
+ - `npx playwright install chromium`, or
12
+ - use an installed Google Chrome with `--browser chrome`
13
+
14
+ ## Install
15
+
16
+ ```bash
17
+ npm install -g viewfit # then run: viewfit
18
+ # or run without installing:
19
+ npx viewfit
20
+ ```
21
+
22
+ ## Quick start
23
+
24
+ ```bash
25
+ # Report only. Nothing is written to disk.
26
+ viewfit ./dist
27
+
28
+ # Write an optimized copy of the site with one preset.
29
+ viewfit optimize ./dist --preset web --site --yes
30
+ ```
31
+
32
+ `./dist` is the folder to analyze: whatever your build outputs (`dist`, `build`, `out`, `public`, or `.` for the current directory). When it is a folder, ViewFit recursively analyzes every `.html`/`.htm` page inside it (skipping `node_modules`, `.git` and the output folder). You can also pass a single HTML file or an already running URL.
33
+
34
+ ## Two commands
35
+
36
+ | Command | What it does |
37
+ | --- | --- |
38
+ | `viewfit [target]` | Analyze and print a report. Never writes files. |
39
+ | `viewfit inspect [target]` | Explicit name for the same report-only command. |
40
+ | `viewfit optimize [target]` | Analyze, then write the optimized images. Asks for confirmation. |
41
+
42
+ A directory target means **all HTML pages recursively**; each unique image is reported and compressed once, using the largest rendered size found across pages.
43
+
44
+ ## Presets
45
+
46
+ `--preset` sets device, tier, format and quality with one flag. Any option passed explicitly overrides the preset.
47
+
48
+ | Preset | Device | Format | Tier | Quality |
49
+ | --- | --- | --- | --- | --- |
50
+ | `web` | Mobile | WebP | 90% | 80 |
51
+ | `hq` | Desktop | AVIF | 100% | 85 |
52
+ | `fast` | Mobile | WebP | 75% | 70 |
53
+
54
+ ## Common examples
6
55
 
7
56
  ```bash
8
- npm install viewfit
57
+ # Analyze a build output on desktop
58
+ viewfit ./dist
59
+
60
+ # Analyze as mobile
61
+ viewfit ./dist --device mobile
62
+
63
+ # Custom tier: 80% of the exact rendered size
64
+ viewfit ./dist --tier 80
65
+
66
+ # Write to a custom folder, converting to WebP
67
+ viewfit optimize ./dist --format webp --out optimized
68
+
69
+ # Also copy HTML/CSS/JS and rewrite image references
70
+ viewfit optimize ./dist --preset web --site --yes
71
+
72
+ # Overwrite originals (same format only)
73
+ viewfit optimize ./dist --in-place --yes
74
+
75
+ # Interactive choices for tier, format and quality
76
+ viewfit optimize ./dist --interactive
77
+ ```
78
+
79
+ ## Options
80
+
81
+ | Option | Description | Default |
82
+ | --- | --- | --- |
83
+ | `[target]` | Local directory, HTML file or URL | `.` |
84
+ | `-p, --preset <name>` | `web`, `hq` or `fast` | none |
85
+ | `-d, --device <mode>` | `desktop` or `mobile` | preset or `desktop` |
86
+ | `--viewport <w>x<h>` | Viewport override, e.g. `1440x900` | device preset |
87
+ | `-t, --tier <tier>` | `exact`, `safe`, `aggressive`, `extreme` or a number (1-100) | preset or `exact` |
88
+ | `-q, --quality <number>` | Encoder quality (1-100) | preset or `80` |
89
+ | `-f, --format <format>` | `original`, `webp` or `avif` | preset or `original` |
90
+ | `--out <dir>` | Output directory (only `optimize`) | `viewfit-output` |
91
+ | `-w, --in-place` | Overwrite originals (requires `--format original`) | `false` |
92
+ | `--site` | Copy HTML/CSS/JS into the output folder and rewrite image references | `false` |
93
+ | `--root <dir>` | Root used to map URLs to local files when using a URL | none |
94
+ | `--browser <channel>` | Playwright channel: `chromium` or `chrome` | `chromium` |
95
+ | `--timeout <ms>` | Navigation timeout | `30000` |
96
+ | `-i, --interactive` | Choose tier, format and quality interactively | `false` |
97
+ | `-y, --yes` | Skip confirmation prompts | `false` |
98
+ | `--json` | Print the analysis as JSON | `false` |
99
+
100
+ ### Tiers
101
+
102
+ | Tier | Scale |
103
+ | --- | --- |
104
+ | `exact` | 100% of the exact rendered size |
105
+ | `safe` | 90% |
106
+ | `aggressive` | 75% |
107
+ | `extreme` | 50% |
108
+ | number | Custom percentage, e.g. `--tier 85` |
109
+
110
+ ## Demo
111
+
112
+ A ready-to-run example lives in [`examples/demo-site`](examples/demo-site). It has two pages, six high-resolution Unsplash photos and a heavy PNG icon (about 24 MB total). From the repository root:
113
+
114
+ ```bash
115
+ npm run build
116
+ node dist/cli.js ./examples/demo-site --browser chrome
117
+ node dist/cli.js ./examples/demo-site --browser chrome --device mobile --tier 80
118
+ ```
119
+
120
+ ## How it works
121
+
122
+ 1. Discovers every HTML page in the target directory (or uses the single file/URL).
123
+ 2. Serves the target directory and opens each page in Chromium with the selected viewport, device pixel ratio and mobile emulation.
124
+ 3. Scrolls each page to trigger lazy loading and waits for images to decode.
125
+ 4. Collects every rendered `<img>` and CSS background image with its CSS box and fit mode, merging duplicates across pages.
126
+ 5. Reads real dimensions and file size with Sharp.
127
+ 6. Computes the target size from the rendered box, DPR and compression tier.
128
+ 7. Prints a report with original size, rendered size, target size and estimated savings.
129
+ 8. With `optimize`, resizes and re-encodes each image with Sharp.
130
+ 9. With `--site`, copies HTML/CSS/JS into the output folder and rewrites image references to the new files.
131
+
132
+ Images that cannot be mapped to a local file (remote/CDN assets) are reported but not modified.
133
+
134
+ ## Development
135
+
136
+ ```bash
137
+ npm install
138
+ npm run dev -- ./dist --browser chrome
139
+ npm run typecheck
140
+ npm test
141
+ npm run build
142
+ ```
143
+
144
+ ## License
145
+
146
+ MIT