Поиск дубликатов фотографий в браузере без загрузки в облако

#frontend#web-apis#privacy#performance

TL;DR

Разбираем клиентский подход к поиску дубликатов фотографий с использованием Web Crypto API, File System Access API и Web Workers. Полный контроль над данными, нулевые загрузки в облако и работа с большими библиотеками до 20k файлов.

Введение: зачем client-side deduplication?

Типичный сценарий: после экспорта из Google Photos, синхронизации через WhatsApp и резервного копирования получаем 3 копии одного фото с разными именами. Традиционные решения требуют загрузки всего контента на сервер, что неприемлемо для приватных данных.

Современные браузеры предоставляют все необходимые API для локальной обработки:

Основная часть: архитектура решения

1. File System Access API

const dirHandle = await window.showDirectoryPicker();
const imageFiles = await scanDirectory(dirHandle);

async function scanDirectory(dirHandle) {
  const files = [];
  for await (const entry of dirHandle.values()) {
    if (entry.kind === 'file' && isImageFile(entry.name)) {
      files.push(entry);
    } else if (entry.kind === 'directory') {
      files.push(...await scanDirectory(entry));
    }
  }
  return files;
}

Важные нюансы:

2. Хеширование через Web Crypto

async function getFileHash(fileHandle) {
  const file = await fileHandle.getFile();
  const buffer = await file.arrayBuffer();
  const hashBuffer = await crypto.subtle.digest('SHA-256', buffer);
  return bufferToHex(hashBuffer);
}

function bufferToHex(buffer) {
  return [...new Uint8Array(buffer)]
    .map(b => b.toString(16).padStart(2, '0'))
    .join('');
}

Производительность:

3. Оптимизации для больших коллекций

// Воркер для хеширования
self.onmessage = async (e) => {
  const { fileHandle } = e.data;
  const hash = await getFileHash(fileHandle);
  self.postMessage({ hash, fileHandle });
};

// Главный поток
const workerPool = Array(4).fill(null).map(() => new Worker('hasher.js'));

files.forEach((file, i) => {
  workerPool[i % 4].postMessage({ fileHandle: file });
});

Критические улучшения:

Практическое применение

Сценарии использования

  1. Pre-backup cleanup: уменьшение размера бэкапов на 10-30%
  2. Messenger exports: удаление дубликатов из WhatsApp/Telegram
  3. Фотоархивы: проверка перед передачей клиенту

Безопасность и приватность

Проверочный чеклист:

- [ ] Network tab показывает только метрики, не файлы
- [ ] Работает в offline-режиме после загрузки
- [ ] Явные запросы на запись в FS
- [ ] Четкое описание операций в privacy policy

Заключение

Client-side deduplication — жизнеспособная альтернатива облачным сервисам. Современные браузеры предоставляют все необходимые API, а производительность Web Crypto делает решение практичным даже для больших коллекций.

Главные преимущества:

Ограничения:

Для проектов, работающих с приватными медиа, этот подход становится must-have, а не опциональной фичей.


Источник: https://dev.to/helloashish99/finding-duplicate-photos-in-the-browser-without-uploading-your-library-1if5