Как ускорить загрузку слотов
Свободное время на месяц вперёд Планёрка отдаёт за секунды — это не баг, а честный расчёт по календарям. Грузите горизонт волнами, и посетитель увидит первые слоты через секунду.
Почему это долго
Свободное время не лежит готовым списком. На каждый день Планёрка складывает расписание сотрудника, его встречи из подключённых календарей, буферы до и после, минимальный срок записи, длину самой встречи и часовой пояс посетителя. Получается сетка возможных начал, из которой вычитается всё занятое. Это работа на каждый день отдельно, и чем больше дней вы просите, тем больше её приходится делать.
Главное здесь не сами секунды, а форма кривой: каждый следующий день обходится дороже предыдущего. Четыре дня стоят немногим больше одного, а двадцать — уже в шестнадцать раз больше. Поэтому «запросить сразу месяц и не думать» — самая дорогая из стратегий.
На пустом типе встречи проблема не видна
Кривая зависит от того, что именно приходится считать. Тот же запрос к типу встречи без подключённых календарей и без единой записи отдаёт все двадцать дней меньше чем за секунду — роста просто нет. Он появляется, когда у сотрудника есть реальные календари, буферы и уже занятое время. Поэтому замеряйте на боевом типе встречи: на свежесозданном тестовом всё будет выглядеть прекрасно ровно до первого живого клиента.
Что делать: волны
Посетителю не нужен весь месяц в первую секунду. Ему нужен ближайший свободный слот, а дальние даты он смотрит редко и не сразу. Поэтому горизонт берётся не одним запросом и не двадцатью, а четырьмя.
- 01сегодня
- 02ещё три дня
- 03неделя
- 04остаток месяца
Все четыре запроса уходят разом — ждать друг друга им незачем. А вот рисовать нужно строго по очереди: сначала первая волна, потом вторая и так далее. Тогда календарь заполняется слева направо и не скачет, даже если дальняя волна доехала раньше ближней.
Первые слоты видно в одиннадцать раз раньше, и весь горизонт при этом успевает загрузиться быстрее, чем одним куском. Пока посетитель читает список форматов и выбирает дату, остальные волны уже доехали — переключение между датами получается мгновенным.
Код
Границы волн — в днях от сегодня. Дни, которых нет в ответе, помечаются пустыми: 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, к каждому запросу добавляется её собственный запуск. Волн это касается вдвойне: их всего четыре, но каждая платит за старт скрипта. Здесь помогает кэш на стороне прослойки — соседние посетители просят одни и те же ближайшие дни, и второму уже не нужно ничего считать.
Кэш и свежесть — компромисс
Чем дольше живёт кэш, тем быстрее форма и тем выше риск показать время, которое уже заняли. Ближние дни имеет смысл держать в кэше недолго, дальние — дольше: их разбирают реже. Запись всё равно проверяется на стороне Планёрки, поэтому худшее, что случится, — посетитель вернётся на шаг назад и выберет другое время.