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

    В рамках разработки раздела "О нас" появилась задача автоматически отображать картинки-сниппеты (аналогично предпросмотру в 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-задачу.

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