Как я ускорил выгрузку чата Telegram в 11 раз и долго чинил не то

Как я ускорил выгрузку чата Telegram в 11 раз и долго чинил не то

У меня есть проект, который считает статистику переписки прямо в браузере. Кто пишет первым, кто дольше отвечает, какие слова повторяются. Для Telegram обычно нужен файл экспорта из Telegram Desktop, а с телефона его не сделать никак. Поэтому я сделал второй путь. Человек входит в свой Telegram прямо на странице, выбирает чат, и браузер сам скачивает историю через официальный API, как обычный клиент.

Работало это три недели, и работало медленно. Я открыл свою аналитику. Чат на 100–250 тысяч сообщений выгружался в среднем 33 минуты, самый долгий сто. И всё это время человек держит вкладку открытой с горящим экраном, потому что в фоне телефон останавливает загрузку. Дожидались не все.

Потом я выгрузил с телефона свою переписку на 52 тысячи сообщений. Страница честно написала, что осталось около 29 минут. Вы бы стали ждать полчаса, глядя на полоску загрузки? Я бы, наверное, нет.

Сейчас тот же чат с того же телефона грузится за две с половиной.

Но путь к этому вышел кривой.

Куда уходило время

Telegram отдаёт историю страницами по сто сообщений. Если спрашивать слишком часто, он отвечает «подождите N секунд». В первой версии я сделал паузу между страницами и удваивал её после каждого такого ответа. А уменьшать забыл. Одна неудачная минута в начале, и дальше весь чат ползёт на минимальной скорости. Ошибка глупая, исправил сразу.

Дальше интереснее. Библиотека, через которую я хожу в Telegram, короткие просьбы подождать молча пережидает сама. Мой код их просто не видел, и в аналитике выходило, что Telegram почти не жалуется. Я выключил это поведение и посмотрел на реальную картину со своего телефона.

Telegram не попросил подождать ни разу. А страница всё равно шла три с половиной секунды. Почему?

Как я ускорил выгрузку чата Telegram в 11 раз и долго чинил не то

У других людей, судя по той же аналитике, ответ занимает около 0,2 секунды на страницу, у меня в пятнадцать раз дольше. На телефоне у меня включён VPN. Видимо, дело в нём, хотя без VPN я так и не проверил. Но тогда я об этом не подумал и пошёл чинить ограничения, которых не было.

Режим экспорта, который ничего не дал

У Telegram есть официальный режим для экспорта, им пользуется сам Telegram Desktop. В нём, если верить документации, лимиты мягче. Сразу его не включить. На свежем входе Telegram присылает в служебный чат запрос на экспорт, и человек должен нажать «Разрешить». Я сделал плашку с этой просьбой и тихий повтор, пока кнопку не нажмут.

Ускорения не случилось. Я полез в исходники Telegram Desktop, нашёл, что он делает ещё (запрашивает историю по диапазонам и совсем без пауз), повторил. Те же три с половиной секунды на страницу.

Если подумать, всё логично.

Режим экспорта снимает ограничения на число запросов, а я в них не упирался, время съедала дорога туда и обратно. Это я понял, кажется, далеко не сразу, когда уже переписал половину кода выгрузки, добавил плашку, повтор запроса и диапазоны, и всё равно смотрел на те же три с половиной секунды в строке скорости.

Двенадцать страниц сразу

Раз один запрос идёт три секунды, а Telegram не жалуется, напрашивается простое. Просить несколько страниц одновременно, каждую по своему соединению.

Сколько именно, снаружи никто не знает, и я сделал так, чтобы ширина подбиралась сама. Начинаем с четырёх страниц, после трёх спокойных пачек добавляем ещё две, до двенадцати. На первое же «подождите» ширина падает вдвое. Без режима экспорта потолок три, там Telegram, по моим ощущениям, строже.

Как я ускорил выгрузку чата Telegram в 11 раз и долго чинил не то

Вышло 52 тысячи сообщений за две с половиной минуты. Telegram за всю выгрузку один раз попросил подождать 19 секунд. Тут надо сказать честно. В последнем замере ответ сервера вдруг стал быстрее, похоже, VPN в тот вечер работал лучше. Часть прироста подарила сеть, и сколько именно, я не знаю. С компьютера по QR получилось так же быстро.

И кстати, режим экспорта в итоге пригодился. Без него больше трёх страниц сразу просить не стоит, а с ним двенадцать проходят почти без пауз. Так что плашка с «Разрешить» осталась главным советом на экране.

Не качать то, что уже есть

Вторая половина работы про повторную выгрузку. Человек посчитал чат в октябре, а в декабре хочет итоги года. Зачем снова тянуть сто пятьдесят тысяч сообщений, если новых там тысяч пять?

Теперь переписка сохраняется на самом устройстве, в браузере, сжатой. Чат на 52 тысячи занимает 1,9 МБ. При обновлении страница скачивает только новое и ещё два дня до последнего сохранённого сообщения. Эти два дня заменяются свежей версией целиком, так в итог попадает то, что за это время удалили или исправили, и не бывает дублей.

Как я ускорил выгрузку чата Telegram в 11 раз и долго чинил не то

Обновление чата, где за пару часов ничего не написали, заняло меньше половины секунды.

Неделя переписки, наверное, займёт несколько секунд.

Самое обидное случилось в конце. На компьютере всё работало, а на iPhone копия молча не сохранялась. Полдня ушло, чтобы понять, что Safari не даёт второй раз прочитать файл, который я уже убрал из кэша. В Chrome можно, в Safari нет. Пришлось сохранять копию раньше, пока данные ещё в памяти.

Чего я до сих пор не знаю, так это сколько запросов сразу выдерживает Telegram на хорошей сети, без VPN. У меня один аккаунт и один вечер замеров. Если кто-то выгружал большие чаты через API и мерил, расскажите, мне правда интересно сравнить.

11