Есть сайт, при загрузке одной страницы идут несколько десятков одинаковых запросов к апи(/api/products, /api/objects), нужно сделать оптимизацию запросов к апи, т.е. уменьшить количество одинаковых запросов.
Чтобы это сделать, думаю, нужно сохранить где-то несколько массивов JSON, которые вовзращает АПИ (весом примерно 1мб.), чтобы не ломиться к апи за одними и теми же данными.
Важно, что данные нужно обрабатывать на стороне сервера (php).
Пробовал сохранить в localstorage, но мне нужно еще и обработать эти данные, и получить их обратно на сервер при загрузке текущей страницы не получается.
Сохранять в сессиях думаю, что не очень хорошо будет.
Вам поможет кеширование. Их бывает два вида.
Давайте кешировать запросы на 1 час прямо в браузере? Тогда добавьте такой заголовок:
$maxAge = 3600;
header(sprintf('Cache-Control: max-age=%d, must-revalidate', $maxAge));
Проверить можно в Хроме через консоль разработчика - вкладка сеть, фильтр XHR. Закешированные запросы будут показываться как (from disk cache)
.
Этот заголовок также можно добавить на уровне веб-сервера. В Nginx: add_header Cache-Control "max-age=3600";
.
В принципе, клиентское кеширование спасет от кучи однотипных запросов. Однако если запросы идут от разных клиентов (разные люди в разных браузерах), включите кеширование на сервере.
В примере ниже игнорируется заголовок Set-Cookie
. Это заставляет кешировать ответы для всех запросов, игнорируя авторизацию (не учитывается пользователь) и прочее. Если не уверены в том, что делаете, не используйте :) Удачное решение, если информация по продуктам / ценам одинакова для всех.
Чтобы лучше разбираться в отдельных тонкостях, отсылаю к официальной документации
Так как я люблю nginx, пример будет для него:
# Настройки кеша
proxy_cache_path /tmp/nginx # путь
levels=1:2 # количество уровней
keys_zone=my_cache:10m # название:размер зоны, 1Мб ~ 8000 ключей (1 ключ - 1 запрос)
max_size=10g # размер данных кеша, при превышении удаляются наиболее старые
inactive=60m # время хранения запроса на диске с момента последнего обращения, независимо от Cache-Control
use_temp_path=off; # off - используем proxy_cache_path; on - используем proxy_temp_path, указанный в location
server {
# тут настройки вашего веб-сервера
# укажите тут свой location, который следует кешировать
location /api/ {
# Какой кеш использовать? Эта инструкция работает также на уровне server
proxy_cache my_cache;
# Так можно будет в браузере понять, взят ли запрос диска, или пришлось запустисть веб-сервер
# HIT - из кеша, MISS - с сервера, EXPIRED - время кеширования истекло, взято с сервера
add_header X-Cache-Status $upstream_cache_status;
# Начинаем игнорировать заголовки:
# Expires - точно нужно игнорировать, иначе не будет кешироваться, на счет остальных - не уверен
proxy_ignore_headers Expires Cache-Control Set-Cookie;
# Добавляем свой Cache-Control
add_header Cache-Control "max-age=3600";
# форсируем кеширование, хотя эта опция нужна не для всех случаев !!!
proxy_cache_valid any 60m;
# Если источник "отвалился", будем отдавать с диска
proxy_cache_use_stale error timeout http_500 http_502 http_503 http_504;
# но будем обновляться в фоне, (c версии Nginx 1.11.10), если ваш Nginx старый, закомментируйте
proxy_cache_background_update on;
# Веб-сервер - источник данных
proxy_pass http://$http_host$uri$is_args$args;
}
}
UPD
Кеширование - палка о двух концах. Данные устаревают. Важно понять причины устаревания данных, типичную продолжительность их жизни и выработать стратегию инвалидации кеша.
Если указать срока жизни кеша в 1 час, это значит, что мы осознано идем на то, что данные могут быть просрочены на 1 час. Для описательной части товара это я считаю приемлемым. Отзывы о товаре - нет (человек только что оставил отзыв, и его не видит).
Добавление параметра GET позволяет полностью инвалидировать кеш.
Допустим, вы обновляете каталог раз в сутки. Тогда новый URI будет содержать дату /api/products?d=15012018
.
Если вы обновляете свой API с возможной "поломкой" обратной совместимости, добавьте версию API: /api/products?v=0.101
.
Если кеш совершенно не приемлем, а запрос обрабатывается долго, смотрите в сторону ускорения производительности (в том числе оптимизации и кеширование отдельных SQL запросов, etc) и балансировки потока запросов на несколько веб-серверов.
Есть сайт, при загрузке одной страницы идут несколько десятков одинаковых запросов
Вместо десятков одинаковых запросов к /api/products надо сделать один запрос, который возвращает десятки значений.
Повторить то же самое для /api/objects. Проблема решена.
Айфон мало держит заряд, разбираемся с проблемой вместе с AppLab
Перевод документов на английский язык: Важность и ключевые аспекты
Какие существуют виды рекламных бордов и как выбрать подходящий?
Храню в MySQL словарь: 1 таблица, 2 столбца (id и ru_word)Параметры второго столбца: тип Varchar(100), сравнение urf8_general_ci
Разбираюсь с структурой assimp Разработал класс на основе примера для рисования модели ни никак не могу понять как получить адрес файла с текстурой