cdek-it / widget

Базовое решение по интеграции карты выбора ПВЗ от СДЭК
https://widget.cdek.ru
GNU Lesser General Public License v3.0
5 stars 1 forks source link

Виджет зависает при инициализации #34

Open EngineMaster opened 7 months ago

EngineMaster commented 7 months ago

Пробовали различные эксперименты, но виджет все время застрявает на инициализации и кладет фронт на время.

Пример https://fizzymarket.com в корзине.

Да в целом и у вас на виджете тоже можно это заметить, только чуть поменьше провисание

https://widget.cdek.ru/

vermorag commented 7 months ago

Добрый день. Можете проверить с последней версией?

ubzor commented 7 months ago

Добрый день!

Проверил на последней версии - проблема всё ещё актуальна.

Связано это, скорее всего, с тем, что при инициализации виджет подгружает все доступные точки СДЕК - на данный момент это 8250 штук. Это 165 запросов к скрипту, заданному в переменной servicePath, и в общей сложности ~15MB трафика. Причём, поскольку запросы идут через скрипт, а не напрямую к api СДЕКа, это дополнительно замедляет загрузку, т.к. плюсует туда время ответа от api скрипту и производительность сервера, на котором лежит скрипт.

Как один из вариантов решения могу предложить изначально грузить только те точки, которые попадают в стартовый bounding box карты, а остальные догружать по мере надобности.

edit: Ещё один вариант (лучший на мой взгляд) - отказаться от скрипта на бэке и обращаться напрямую к api СДЕКа из браузера. Но раз так до сих по не сделали, видимо на это есть какие-то причины, поэтому:

Как ещё один из вариантов - кэшировать данные о точках на бэке (выигрываем время, затрачиваемое каждый раз на обращение к апи), периодически обновляя их по крону.

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

edit3: Ещё один вариант оптимизации - не блокировать карту индикатором загрузки в ожидании пока все 165 запросов придут обратно с данными, а добавлять маркеры на карту порциями, после каждого запроса.

vermorag commented 7 months ago

Добрый день.

отказаться от скрипта на бэке и обращаться напрямую к api СДЕКа из браузера

В настоящий момент это не является возможным, поскольку для получения офисов необходим токен, при утечке которого можно получить заказы и персональные данные клиентов, соответственно работать с ним из браузера не безопасно

кэшировать данные о точках на бэке (выигрываем время, затрачиваемое каждый раз на обращение к апи), периодически обновляя их по крону.

service.php предназначен для запуска в универсальной среде, ему не нужна база, он не работает с файлами, из-за этого приходится мириться с такими ограничениями как невозможность кэширования. Однако никто не мешает разработчику его самостоятельно модифицировать под коркретную среду.

Да, и ещё - каждая точка содержит полный набор данных - телефоны, часы работы, и так далее

Это особенность работы общих протоколов - они предоставляют сразу все данные об офисах

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

Тогда как мы можем гарантировать, что, открыв карту, мы увидим точки сразу на открытой области, а не через какое-то время?

Наша команда сейчас работает над альтернативной API учитывающей особенностей виджета, но конкретный срок назвать я не могу, тк дата выпуска будет зависеть и от загруженности смежных отделов. В настоящий момент реализация стоит на 1 квартал 2024.

ubzor commented 7 months ago

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

vMamr commented 5 months ago

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

Подскажите а как сделали кэширование?

vermorag commented 5 months ago

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

Номер задачи на доработку CMS-806. Если требуется, можете подключиться к рассылке по релизу всех новых версий наших плагинов. Письма в рассылке о новых версиях содержат номера задач команды разработки, входящих в патч, а также краткое описание обновлений. Для подписки на рассылку напишите, пожалуйста, в телеграм: https://t.me/cdek_it_bot, раздел Интеграция для интернет-магазинов.

ubzor commented 5 months ago

Подскажите а как сделали кэширование?

Вместо того, чтобы, как это сделано в файле service.php из этого репозитория, фетчить каждый раз пункты выдачи из апи СДЕК'а при обращении к методу getOffices(), я сохраняю их в бд и обновляю по крону, и их и использую для выдачи виджету, обернув в Laravel'евский Cache::rememberForever. После каждого обновления пунктов выдачи в базе их кэш сбрасывается.

vermorag commented 4 months ago

@ubzor Если у вас есть возможность/желание поучаствовать в закрытом тестировании 4 версии виджета, напишите мне на почту cms-integrator@cdek.ru, расскажу подробнее про особенности и процедуре.

m6t9 commented 4 months ago

Есть ли примерный дедлайн для 4 версии виджета? Фронтэнд на MODx при тестовом подключении жутко тормозит, а при "боевом" подключении (больше ПВЗ) браузер не справляется. На Бэкенде конечно кэширую, но Фронтэнду уже это не помогает.

vermorag commented 4 months ago

Есть ли примерный дедлайн для 4 версии виджета?

В настоящий момент - 30.06.2024.

piton-zel commented 2 months ago

Что там с дедлайнами? Надежда еще есть?

ceobit commented 1 month ago

Поддержу, есть сроки?

piton-zel commented 1 month ago

Похоже все, потуги местных разработчиков закончились, не успев начаться. Дали бы денег нормальной конторе, давно бы уже сделали хороший продукт, а не эту поделку пионеров. Ладно, с мобилы текущая версия это просто жесть на открытие, поэтому помимо кеширования (это супер обязательная тема, т.к. сервера сдека так же быстры, как и разработчики этого кода :) уменьшаем трафик, решение следующее

protected function getOffices()
{
        $res = $this->httpRequest('deliverypoints', $this->requestData);
        if ($json = json_decode($res['result'], true)) {
            $json = self::updateOffice($json);
            $res['result'] = json_encode($json, JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES| JSON_PRESERVE_ZERO_FRACTION);
        }
        return $res;
}

protected function updateOffice(array $data): array
{
        $ret = array();
        foreach ($data as $item) {
            $ret[] = array(
                'code' => $item['code'],
                'name' => $item['name'],
                'work_time' => $item['work_time'],
                'type' => $item['type'],
                'is_dressing_room' => $item['is_dressing_room'],
                'have_cashless' => $item['have_cashless'],
                'have_cash' => $item['have_cash'],
                'allowed_cod' => $item['allowed_cod'],
                'weight_min' => (float)$item['weight_min'],
                'weight_max' => (float)$item['weight_max'],
                //'dimensions' => $item['dimensions'],
                'location' => array(
                    'country_code' => $item['location']['country_code'],
                    'region' => $item['location']['region'],
                    'city_code' => $item['location']['city_code'],
                    'city' => $item['location']['city'],
                    'postal_code' => $item['location']['postal_code'],
                    'longitude' => $item['location']['longitude'],
                    'latitude' => $item['location']['latitude'],
                    'address' => $item['location']['address'],
                )
            );
        }
        return $ret;
}

Что имеем на выходе, был трафик сервер-клиент 14метров, стал 4, т.е. более чем в 3 раза уменьшился

Что можно еще сделать, чтобы было по красоте, в плане загрузки. Это уменьшить то безумное количество потоков на скачивание, да еще и не статического контента до одного, но тут сожалению только через правку кода js. Файл который правим: cdek-widget.umd.js

Ищем вот это

e.headers["x-total-elements"])/500

и меняем на вот это

e.headers["x-total-elements"])/10000

Далее ищем вот это

this.fetchOfficePage(n,t,500)

и меняем на вот это

this.fetchOfficePage(n,t,10000)

Все, наслаждаемся уже более менее быстрой загрузкой, у меня в среднем данные сейчас в один запрос, после сжатия web сервером, прилетают за 72мс, это трафик ~386кБ.

Vlad-i-Slav commented 1 month ago

И всё же, в соседней ветке был набор на бета-тест. Написал на почту, ответа нет. Здесь тоже тишина. Не будет нового релиза? Просто можно написать об этом же.

vermorag commented 1 month ago

Добрый день. Релиз 4 версии виджета действительно был запланирован на конец июня. 26 мая произошел массовый сбой, отчего все силы были брошены на восстановление работы всей системы.

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

На текущий момент работа над виджетом возобновлена. К сожалению, предоставить новый точный срок релиза сейчас не смогу. Если у вас возникнут другие вопросы по текущим проектам - мы готовы подключиться к решению вопроса в рамках новых задач.