Как устроена локальная обработка файлов в браузере
Если ничего никуда не загружается, то что и где вообще выполняет работу?
Что здесь значит «локально»
Обычный онлайн-конвертер — это сайт с точкой приёма загрузок. Ваш файл передаётся на машину, которую вы не контролируете, обрабатывается там, какое-то время хранится и предлагается обратно для скачивания. Локальная обработка вычёркивает середину этого предложения: код, читающий ваш файл, выполняется во вкладке браузера, которая у вас уже открыта, на вашем собственном процессоре, а результат записывается обратно на ваш собственный диск.
Сам сайт по-прежнему загружается по сети: HTML, таблицы стилей, скрипты и модули WebAssembly приходят с сервера, как у любой веб-страницы. Разница в направлении. Код программы идёт вниз; ваш файл наверх не идёт.
Все нужные детали в браузере уже есть
| Возможность | Что она даёт |
|---|---|
| API File и Blob | Читают байты файла, который пользователь выбрал или перетащил, без отправки формы |
| Web Workers | Выполняют тяжёлую работу в фоновом потоке, чтобы интерфейс продолжал отвечать |
| WebAssembly | Выполняет скомпилированные библиотеки кодеков на C, C++ или Rust почти на скорости нативного кода |
| Canvas и OffscreenCanvas | Декодируют, рисуют, масштабируют и заново кодируют изображения |
| WebCodecs | Открывает доступ к собственным аппаратно ускоренным видеокодировщикам и декодерам браузера |
| WebGPU | Выполняет вывод моделей и параллельную работу с пикселями на графическом процессоре |
| File System Access | Записывает результат сразу в выбранное пользователем место, там где это поддерживается |
Ничего экзотического здесь нет. Это та же платформа, на которой во вкладке работают электронные таблицы, дизайнерские редакторы и игры. Необычно тут только одно решение — не добавлять к ней сервер.
Какой путь проходит файл
- Вы выбираете файл. Браузер передаёт странице дескриптор — не копию, а ссылку.
- Страница читает первые байты, чтобы определить настоящий тип файла по его сигнатуре, а не доверять расширению.
- Она оценивает, сколько памяти потребует задача, и отказывается от работы или ставит её в очередь, если оценка превышает то, что устройство способно безопасно выделить.
- Байты передаются в Web Worker. Передача ArrayBuffer перемещает владение, а не копирует его, поэтому большой файл не существует в памяти дважды.
- Внутри воркера декодированием и кодированием занимается кодек на WebAssembly или платформенный API.
- Результат возвращается в виде байтов, оборачивается в Blob и предлагается вам для скачивания либо записывается в выбранное вами место.
- Временный URL этого Blob отзывается, а буферы освобождаются.
Почему всё изменил именно WebAssembly
Кодеки изображений и видео — это десятилетия тщательно оптимизированного кода на C. Переписать их на JavaScript было нереально с самого начала. WebAssembly — переносимый двоичный формат инструкций, который браузеры выполняют в песочнице со скоростью, близкой к нативному коду, а значит, эти существующие библиотеки можно скомпилировать и доставить в браузер как есть.
Песочница важна не меньше скорости. У модуля WebAssembly нет доступа по умолчанию ни к вашей файловой системе, ни к сети, ни к другим вашим вкладкам. Он видит ту память, которую ему передала страница, и больше ничего. Вредоносный или просто содержащий ошибку кодек не сможет уйти в сторону и прочитать то, чего ему не давали.
Что всё-таки обращается к сети и почему это не ваш файл
По сети приходят три вещи: сама страница, движок того инструмента, который вы открыли, и — для удаления фона — веса модели. Все три представляют собой собственные статические файлы FileSlimmer, запрашиваемые с собственного источника FileSlimmer до того, как будет прочитан хоть один ваш байт. Это загрузки, они кэшируются, и после первого использования их можно отдавать из собственного кэша браузера вообще без обращения к сети.
Всё, что происходит после этого, локально. Движки получают байты файла только через postMessage от страницы; им никогда не передают URL, куда что-либо отправлять, а политика безопасности контента ограничивает, куда страница вообще могла бы подключиться, даже если бы какой-то код попытался.
Компромиссы, названные прямо
| Критерий | В вашем браузере | На сервере |
|---|---|---|
| Куда попадает ваш файл | Никуда | На машину, которую вы не контролируете |
| Скорость | Какую способно дать ваше устройство | Какую оплатил оператор сервиса |
| Очень большие файлы | Ограничены памятью браузера | Ограничены лимитами оператора |
| Работа офлайн | Да, как только движок закэширован | Нет |
| Экзотические форматы | Только то, что компилируется в WebAssembly | Всё, что установит оператор |
| Пакет из тысячи файлов | Ограничен возможностями устройства | Обычно подходит лучше |
Локальная обработка не лучше во всём. Она лучше, когда файл приватный, устройство достаточно мощное, а работа умещается в память. Сервер лучше, когда обработать нужно гораздо больше, чем помещается на одной машине. Ясно понимать, в какой из этих ситуаций вы находитесь, полезнее, чем настаивать, что один из подходов побеждает везде.
О чём здесь ничего не утверждается
Всё сказанное относится к тому, что делает это приложение. Это не утверждение ни о ваших расширениях браузера, которые могут читать содержимое любой открытой вами страницы, ни о вашей операционной системе, которая может изучить любой файл, к которому вы прикоснулись, ни о вашем операторе связи, который видит, что вы заходили на сайт. Всё это вне досягаемости любого сайта, и инструмент, который утверждает иное, преувеличивает.
Утверждение узкое и проверяемое: выбранные вами файлы обрабатываются локально в этом браузере, и FileSlimmer их никуда не загружает. Следующее руководство объясняет, как проверить это самому, а не принимать на веру.
Инструменты для этого
Источники
- W3C — File API
- W3C — WebAssembly Core Specification
- WHATWG — HTML Standard, Web Workers
- W3C — WebCodecs