Skip to main content
PhotoEditor

( First-party data )

Reproducible batch editor benchmark

How long the workflow took on one reference machine, using the same image and three repetitions per batch. These numbers document a test; they are not a speed guarantee.

Observed results

Measured on . Each main value is the median of three runs.

Download JSON data
Medians by batch size
ImagesTotal megapixelsUploadAutomatic adjustmentPNG export
11.0 MP836 ms137 ms393 ms
109.6 MP824 ms864 ms1.46 s
2524.0 MP836 ms10.55 s2.51 s

Upload timing ends when every thumbnail and the central preview are visible. Adjustment timing ends when the batch summary appears. Export timing ends when the download page publishes its completed/failed summary.

Reproducible method

Reference environment

System
Windows x64
CPU
12 logical processors
RAM
32 GiB
Chromium
151.0.7922.34
Viewport
1440x900

Input and sequence

Each sample opens an isolated context, loads copies of the project-owned 1200×800 px fixture (0.96 MP), selects the batch, runs Automatic Adjustment, and exports PNG.

npm run dev -- --port 3218
npm run benchmark:batch

Technical analysis: memory and browser execution

When editing photos in batch locally inside the browser, the primary constraint is not network bandwidth or storage speed, but uncompressed bitmap memory in RAM. When a compressed JPEG or PNG file of 500 KB is opened, the browser decodes it into raw 32-bit RGBA pixel arrays (ImageData). Each pixel consumes exactly 4 bytes (Red, Green, Blue, Alpha). A single 1200×800 image requires approximately 3.84 MB of uncompressed memory, meaning a batch of 25 photos holds nearly 96 MB of raw image buffers in the browser tab simultaneously.

During automatic adjustment, processing runs through an isolated background Web Worker. This worker computes tonal statistics, luminance histograms, and color balance without freezing the browser user interface. Notice how adjustment time scales sub-linearly between 10 and 25 images: modern JavaScript JIT engines (such as V8 in Chromium) optimize loops and hot code paths after initial warmup, allowing consecutive images to be adjusted efficiently.

PNG export is consistently the most demanding phase because encoding uncompressed RGBA pixel buffers into filtered, deflate-compressed PNG chunks requires intensive CPU cycles and checksum calculations. When multiple files finish exporting, JSZip bundles the output files into a single archive in memory before triggering the browser's native file download prompt.

Questions about this benchmark

Do these exact times apply to my computer or phone?
Not as absolute values. Hardware speed, CPU core count, operating system throttling, and browser version all shift these numbers up or down. What remains representative is the relative curve between 1, 10, and 25 images: export is consistently more demanding than adjustments, and upload decoding scales with overall pixel volume.
Why report three repetitions instead of hundreds?
Because the goal is practical transparency and order of magnitude with documented variance, not academic statistical modeling. All nine raw samples are preserved in the downloadable JSON dataset, including the slower initial run before engine caching.
Why is there no universal maximum photo count?
Because browser tab memory limits vary dynamically based on other running applications, available physical RAM, 32-bit vs 64-bit architecture, and mobile OS constraints. Publishing an arbitrary fixed file count would promise what browser environments cannot universally guarantee.
Why does PNG export take significantly longer than automatic adjustment?
Automatic adjustment evaluates pixel statistical samples in memory and modifies color arrays in place using Web Workers. PNG export, however, must perform line-by-line filtering (Sub, Up, Average, Paeth) and zlib/deflate compression on every single pixel before assembling the binary file, which is computationally heavier.
How can I reproduce these exact benchmark runs locally?
Clone the project repository, install dependencies, and run the automated benchmark script shown in the command box above (npm run benchmark:batch). It will launch an automated Playwright Chromium browser instance, execute the 9 sample cycles, and output the timing JSON file with medians.