Оптимизация загрузки изображений-сниппетов для новостного раздела

В рамках разработки раздела "О нас" появилась задача автоматически отображать картинки-сниппеты (аналогично предпросмотру в Telegram, ВКонтакте и других соцсетях) для каждой новостной статьи, где упоминается компания.

В настоящий момент используется функция getOgImage, которая парсит HTML-код внешней страницы для извлечения изображения из мета-тега og:image. Однако этот подход создаёт избыточную нагрузку при формировании списка статей: для каждого элемента инфоблока требуется отдельный HTTP-запрос к внешнему ресурсу, что негативно сказывается на скорости работы.

Текущее решение и его недостатки

Используемая функция:

function getOgImage($url)
{
    $image = '';
    libxml_use_internal_errors(true);
    $c = file_get_contents($url);
    if (!$c) {
        return $image;
    }
    $d = new DomDocument();
    $d->loadHTML($c);
    $xp = new domxpath($d);
    foreach ($xp->query("//meta[@property='og:image']") as $el) {
        $image = $el->getAttribute("content");
    }
    return $image;
}

Основные проблемы метода:

  • Производительность: Каждый запрос к списку статей инициирует множество обращений к внешним сайтам.
  • Зависимость от доступности: Если исходный новостной ресурс недоступен, сниппет не будет получен.
  • Время отклика: Общее время формирования страницы увеличивается пропорционально количеству статей.

Предлагаемые пути оптимизации

Для решения проблемы рассматриваются следующие варианты:

  1. Сохранение изображения при создании элемента (кэширование). Наиболее эффективный способ. В момент добавления новости в раздел "О нас" выполняется однократный запрос для получения URL картинки. Этот URL (или сама загруженная картинка) сохраняется в свойствах элемента инфоблока. При последующих показах данные берутся из локальной базы, что исключает внешние запросы.
  2. Фоновая (отложенная) загрузка. Основной контент страницы отдаётся мгновенно, а запросы на получение сниппетов выполняются асинхронно, после загрузки страницы, с помощью JavaScript. Это улучшает воспринимаемую скорость работы, но не снижает общую нагрузку на сервер.
  3. Периодическое обновление кэша. В дополнение к первому пункту можно реализовать механизм, который раз в сутки или неделю проверяет и обновляет устаревшие снипппеты, например, через CRON-задачу.

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