Как ускорить загрузку слотов

Свободное время на месяц вперёд Планёрка отдаёт за секунды — это не баг, а честный расчёт по календарям. Грузите горизонт волнами, и посетитель увидит первые слоты через секунду.

10 минутДля тех, у кого форма думает

Почему это долго

Свободное время не лежит готовым списком. На каждый день Планёрка складывает расписание сотрудника, его встречи из подключённых календарей, буферы до и после, минимальный срок записи, длину самой встречи и часовой пояс посетителя. Получается сетка возможных начал, из которой вычитается всё занятое. Это работа на каждый день отдельно, и чем больше дней вы просите, тем больше её приходится делать.

1 день1,0 с
4 дня1,4 с
11 дней5,0 с
20 дней16 с
Замер 22 августа 2026: боевой тип встречи с подключёнными календарями, один сотрудник.

Главное здесь не сами секунды, а форма кривой: каждый следующий день обходится дороже предыдущего. Четыре дня стоят немногим больше одного, а двадцать — уже в шестнадцать раз больше. Поэтому «запросить сразу месяц и не думать» — самая дорогая из стратегий.

На пустом типе встречи проблема не видна

Кривая зависит от того, что именно приходится считать. Тот же запрос к типу встречи без подключённых календарей и без единой записи отдаёт все двадцать дней меньше чем за секунду — роста просто нет. Он появляется, когда у сотрудника есть реальные календари, буферы и уже занятое время. Поэтому замеряйте на боевом типе встречи: на свежесозданном тестовом всё будет выглядеть прекрасно ровно до первого живого клиента.

Что делать: волны

Посетителю не нужен весь месяц в первую секунду. Ему нужен ближайший свободный слот, а дальние даты он смотрит редко и не сразу. Поэтому горизонт берётся не одним запросом и не двадцатью, а четырьмя.

  1. 01сегодня
  2. 02ещё три дня
  3. 03неделя
  4. 04остаток месяца
Волна 1сегодня — один день
Волна 2следующие три дня
Волна 3следующая неделя
Волна 4остаток горизонта — в примере ниже это 20 дней

Все четыре запроса уходят разом — ждать друг друга им незачем. А вот рисовать нужно строго по очереди: сначала первая волна, потом вторая и так далее. Тогда календарь заполняется слева направо и не скачет, даже если дальняя волна доехала раньше ближней.

Одним кускомпусто 16 секунд, потом появляется весь месяц
Волнамипервый день через 1,4 секунды, весь горизонт — через 6,8
Тот же горизонт в 20 дней, тот же тип встречи.

Первые слоты видно в одиннадцать раз раньше, и весь горизонт при этом успевает загрузиться быстрее, чем одним куском. Пока посетитель читает список форматов и выбирает дату, остальные волны уже доехали — переключение между датами получается мгновенным.

Код

Границы волн — в днях от сегодня. Дни, которых нет в ответе, помечаются пустыми: API не присылает даты, где нет ни одного свободного начала, а календарю нужно знать, что там занято, — иначе такие дни останутся кликабельными.

// Горизонт в 20 дней, четыре волны
var WAVES = [[0, 0], [1, 3], [4, 10], [11, 19]];

function fetchSpan(a, b) {
  return api("/rest/v2/slots?eventTypeId=" + typeId +
             "&start=" + ymd(a) + "&end=" + ymd(b) +
             "&timeZone=" + encodeURIComponent(TZ), "2024-09-04")
    .then(function (body) {
      var data = body.data || {};
      Object.keys(data).forEach(function (d) { byDate[d] = data[d] || []; });
      // дни, которых в ответе нет, — занятые: помечаем пустыми
      for (var i = a; i <= b; i++) {
        var dd = ymd(i);
        if (!byDate[dd]) byDate[dd] = [];
      }
    });
}

// запросы уходят разом, а рисуем строго по очереди —
// календарь заполняется слева направо, без скачков
var jobs = WAVES.map(function (w) { return fetchSpan(w[0], w[1]); });

var chain = Promise.resolve();
jobs.forEach(function (job) {
  chain = chain.then(function () {
    return job.then(function () { renderDates(); });
  });
});
Готовый вариант этого кода — в блоке из рецепта «Своя форма записи на Тильде».

Один день — это отрезок из одного дня

В параметрах start и end границы включаются обе. Чтобы перечитать одну дату — например, когда время заняли, пока посетитель заполнял поля, — отправьте её и как начало, и как конец.

Чего не делать

Запрашивать месяц одним кускомСамый частый вариант и самый медленный на старте: посетитель смотрит на пустой календарь всё время, пока считается последний день месяца. До первого слота он может не досидеть.
Запрашивать каждый день отдельноОбратная крайность. Один день считается быстро, но за каждый запрос платятся накладные: дорога до сервера и обратно, проверка ключа, разбор ответа. А запросы, отправленные разом, ещё и мешают друг другу — сервер считает их параллельно, и каждый становится медленнее, чем был бы в одиночку. Четыре волны это выдерживают, двадцать запросов — уже нет.
Ждать все волны и рисовать разомТогда весь смысл теряется: экран остаётся пустым до самой медленной волны. Рисуйте каждую волну сразу, как она доехала.

Если ходите через прослойку

Когда запросы идут не напрямую, а через прослойку на Google Apps Script, к каждому запросу добавляется её собственный запуск. Волн это касается вдвойне: их всего четыре, но каждая платит за старт скрипта. Здесь помогает кэш на стороне прослойки — соседние посетители просят одни и те же ближайшие дни, и второму уже не нужно ничего считать.

Кэш и свежесть — компромисс

Чем дольше живёт кэш, тем быстрее форма и тем выше риск показать время, которое уже заняли. Ближние дни имеет смысл держать в кэше недолго, дальние — дольше: их разбирают реже. Запись всё равно проверяется на стороне Планёрки, поэтому худшее, что случится, — посетитель вернётся на шаг назад и выберет другое время.

Следующий рецептСвоя форма записи на ТильдеГотовый блок, где волны уже собраны: пять экранов и запись, не уходя со страницы.