-
Постов
687 -
Зарегистрирован
-
Посещение
-
Победитель дней
165
AndreyJ стал победителем дня 8 июля
AndreyJ имел наиболее популярный контент!
Посетители профиля
Блок последних пользователей отключён и не показывается другим пользователям.
Достижения AndreyJ
-
А вот это вообще хорошая штука. Да это кешируется, но только когда кто-то первый раз зашел в ту категорию. А когда в магазине обновляются цены, товары, то этот кеш постоянно сбрасывается. Добавте плиз в коробку тоже. --- Ещё одно место с лишними запросами в SEO-фильтрах — генерация SEO-имён фильтров. В дополнение к тому, что я писал выше про кэш field_type — при построении SEO-ссылок фильтров на странице категории функция получения SEO-имени (внутри fn_ab__seo_filters_url_post → get_name) делает отдельный запрос к БД на КАЖДЫЙ вариант фильтра. На «холодной» категории с большим числом фильтров это выливается в сотни запросов — у нас доходило до ~1200 на одну категорию, и все они читают из одной и той же таблицы SEO-имён. Предложение: один раз за запрос выбрать ВСЕ одно-фичевые SEO-имена категории одним bulk-запросом и держать их в памяти (одна запись в Registry / static-массив вида feature_value → {sf_id, name, features_hash}). Тогда: одно-фичевые имена берутся из карты в памяти; отсутствие в карте = имени нет — без дополнительных запросов; мульти-фичевые хэши остаются на штатной ветке get_name. Эффект у нас: холодная категория — с ~1200 запросов до единиц, время генерации SEO-ссылок заметно падает. Вместе с фиксом кэша field_type (сообщение выше) это две независимые точки, где на одной странице категории набегают сотни повторных запросов. На холодной категории (но прогретом сайте) суммарно ~1674 → ~584 SQL-запроса (≈в 3 раза меньше). Отдельно: field_type-кэш 660→475, bulk-прекэш SEO-имён — с ~1200 запросов до единиц. Основной эффект — кратное снижение нагрузки на БД на генерации SEO-страниц фильтров. По времени генерации на 20-25% примерно.
- 2 ответа
-
- 1
-
-
Приветствую. Сергей, тут еще вот такое вот нашли. Не уверен, что ві и планировали тот кеш, но Клавдия настаивает. ---- Модуль «Стикеры» 3.0.2, CS-Cart 4.20.1. Похоже, Registry-кэш готового HTML стикеров в get_stickers никогда не сохраняется между запросами — HTML всех стикеров пересобирается при каждом AJAX-запросе. Причина. В controllers/frontend/ab__stickers.php кэш регистрируется под именем ab__stickers_html, но во все три вызова fn_ab__stickers_get_sticker_frontend_information() (строки ~33, ~50, ~65) имя кэша не передаётся, а у параметра в func.php дефолт — пустая строка: // контроллер (3 места): list($sticker_id, $product_id, $template_id, $cache_key) = fn_ab__stickers_get_sticker_frontend_information($sticker_html_id); // без $cache_name // func.php: function fn_ab__stickers_get_sticker_frontend_information($sticker_html_id, $cache_name = '') { ... $cache_key = "{$cache_name}.{$sticker_html_id}"; // получается ".126-28891" } Ключи с пустым префиксом до точки попадают в Registry под незарегистрированное имя и на диск не пишутся (персистятся только поддеревья зарегистрированных имён). Registry::isExist($cache_key) на новом запросе всегда false, и fn_ab__stickers_prepare_sticker_to_frontend() отрабатывает заново для каждого стикера на каждом запросе. Как проверить. После любого прогона витрины со стикерами в var/cache/registry/<store_prefix>/ нет папки ab__stickers с файлами *ab__stickers_html — кэш ни разу не записался. Фикс. Передать имя во все три вызова: fn_ab__stickers_get_sticker_frontend_information($sticker_html_id, $cache_name); Нюанс. После фикса кэш начнёт реально накапливаться — по записи на каждую комбинацию «стикер × товар × шаблон», одним блобом на dispatch/группу/язык, без TTL и лимита размера. На каталоге в тысячи товаров блоб вырастет до мегабайт, которые целиком читаются и перезаписываются на каждом запросе. Лучше сразу добавить TTL либо кэшировать в static-массиве в рамках запроса — межзапросный кэш даёт мало, ключ всё равно включает product_id.
-
Небольшое уточнение к моему посту выше — про флаг lazy_load_disabled. Я назвал его «мёртвым кодом», но, разобравшись глубже, это неточно: правильнее — незавершённая заготовка ровно под эту задачу. Само имя выдаёт замысел: пометить картинку как «ленивую загрузку отключили». Уточняю, почему в текущем виде оно не работает — это подсказывает, где механизм не был доведён. Единственное присваивание — в хуке ab__preload hooks/common/image.pre.tpl: {if $restore} {$image_additional_attrs['lazy_load_disabled'] = true scope="parent"} {$restore = false} {/if} Ставится только в JS-режиме ($restore = true лишь когда на входе $lazy_load == true). В нативном режиме, где и возникает проблема с loading="lazy", флаг не выставляется вовсе. Потребитель не реализован. Значение нигде не читается: шифрованных файлов в ab__preload/ab__lazy_load нет, lazysizes 5.3.2 такого атрибута не знает, func.js ab__lazy_load его не проверяет, PHP тоже. И не может быть прочитан ab__lazy_load из-за порядка хуков — он выполняется раньше ab__preload (priority 190000 против 200000), поэтому на момент его работы флага ещё нет. Побочный эффект: render_tag_attrs булев true выводит как голый атрибут, поэтому в JS-режиме флаг протекает в разметку — <img … lazy_load_disabled> (невалидный атрибут, браузер игнорирует). Вывод: проще всего закрыть задачу форсированием loading="eager" в ab__preload (как в предложении выше) — это покрывает оба режима и не зависит от порядка хуков, а присваивание lazy_load_disabled тогда можно убрать (заодно уйдёт мусорный атрибут в JS-режиме). Если же сигнальную модель хочется сохранить, её придётся переносить: сигнал должен выставляться до работы ab__lazy_load, и на его стороне нужен читатель.
-
Снова приветствую. Тут еще в борьбе с гуглпейджспидом и дерганьем при загрузке нашли момент важный. --- Тема: в нативном режиме ab__lazy_load предзагружаемая картинка получает loading="lazy" — прелоад и ленивая загрузка противоречат друг другу, страдает LCP Оба модуля — ваши, и в связке они не примиряются, когда ab__lazy_load работает в нативном режиме (mode = native). Итог: главное фото товара (а также баннеры и плитки категорий) одновременно: предзагружается: <link rel="preload" as="image" fetchpriority="high" href="…"> (ставит ab__preload); и помечено loading="lazy" (ставит ab__lazy_load). Это прямой антипаттерн: прелоад говорит браузеру «грузи сразу с высоким приоритетом», а loading="lazy" — «отложи». Lighthouse/PageSpeed это ловит («LCP image was lazily loaded»), и предзагрузка фактически обесценивается. Причина (разобрана по коду): Оба модуля вешают хук на common/image.pre.tpl. Шаблонные хуки выполняются в порядке приоритета аддонов (fn.init.php: SELECT … FROM ?:addons … ORDER BY priority; SmartyEngine/Blocks/Hook.php: foreach по аддонам без пересортировки). Приоритеты: ab__lazy_load = 190000, ab__preload = 200000 → ab__lazy_load выполняется ПЕРВЫМ. В нативном режиме хук ab__lazy_load вешает атрибут loading="lazy": {if !$lazy_load} {$image_additional_attrs.loading="lazy" scope=parent} {/if} и при этом НЕ меняет переменную $lazy_load (в true её ставит только JS-режим). Хук ab__preload (выполняется вторым) свою защиту от lazy включает только веткой {if $lazy_load} — истинной лишь в JS-режиме. В нативном режиме $lazy_load = false, поэтому защита не срабатывает: предзагружаемая картинка так и остаётся с loading="lazy". Флаг lazy_load_disabled, который ab__preload при этом присваивает, нигде не читается (мёртвый код) — то есть текущая защита в нативном режиме не делает ничего. Подтверждено на реальных страницах и замерами. На пристинной установке (нативный режим) главное фото товара приходит с loading="lazy" при наличии preload fetchpriority="high" на ту же картинку. Сравнительный A/B (PageSpeed mobile, одна страница, по 2 прогона на режим): нативный режим устойчиво лучше JS-режима (score ~73–78 против 62–72; TBT ~250–380 мс против 510–590 мс — JS-режим грузит основной поток ленивой обработкой ~100 картинок). То есть переключение в JS-режим как обходной путь не подходит — чинить надо в нативном. Предложение (владелец фикса — ab__preload, т.к. он выполняется вторым и уже знает, что картинка приоритетная). В хуке ab__preload/hooks/common/image.pre.tpl, внутри блока принятия решения о предзагрузке, форсировать eager: {if ($ab__ll.mode|default:'') !== 'js'} {$image_additional_attrs.loading = 'eager' scope="parent"} {$image_additional_attrs.fetchpriority = 'high' scope="parent"} {/if} Поскольку ab__preload выполняется после ab__lazy_load, его loading="eager" перекрывает выставленный ранее loading="lazy". Guard !== 'js' оставляет JS-режим без изменений (там ab__preload уже разлочивает картинку через $lazy_load = false, и вмешательство в атрибуты может задеть lazysizes/srcset). Правка покрывает разом главное фото, баннеры и плитки категорий. Мотивация: предзагрузка картинок — ключевая функция ab__preload ради быстрого LCP — в нативном режиме ab__lazy_load сейчас не работает: браузер всё равно откладывает предзагруженную картинку. После правки прелоад начинает выполнять своё назначение, и у пользователей снимается замечание PageSpeed «LCP image was lazily loaded». Минусов нет: правка применяется только к тем картинкам, что ab__preload и так помечает на предзагрузку (приоритетные, первый экран); обычные картинки сохраняют нативный loading="lazy". JS-режим не затрагивается (guard). Проверено: в нативном режиме предзагружаемое главное фото становится eager, прочие картинки остаются lazy; в JS-режиме рендер идентичен прежнему.
-
Добрый день. Делаем аналитику ГА4 полноценную и она не цепляет вкладки в которых выводятся блоки этого модуля. А они важные. На виду. Добавте плиз хук или может тот экзит лишний и случайно там оказался. Все как обычно проверено кучей изысканий и поиском иных вариантов. но этот самый надежный и феншуйный. Дальше письмо со смыслом. --- Мы используем ваш модуль ab__intelligent_accessories (блоки «Сумісні / Схожі / Похожие товары» на карточке товара) вместе с модулем GA4-аналитики. Зачем пишем. Нам нужно снимать по этим блокам стандартную e-commerce-аналитику Google Analytics 4: view_item_list — показы товаров в блоке (какие сопутствующие товары реально увидел покупатель), select_item — клики по товару из блока. Это наполняет встроенные отчёты GA4 «Список товаров» (Item list), и мы видим, какой из блоков подбора приносит просмотры, клики и в итоге продажи — то есть насколько эффективен ваш модуль в деньгах. Сейчас эти блоки в аналитику не попадают, и мы буквально «слепы» по ним, хотя по категориям/поиску/каруселям всё уже трекается. Техническая причина. Товары вкладки наливаются AJAX-контроллером ab__ia_joins.get_join_products (app/addons/ab__intelligent_accessories/controllers/frontend/ab__ia_joins.php), который завершается через exit; (строка ~89). Из-за exit; обходится штатный механизм пост-контроллеров CS-Cart, и никакой сторонний аддон не может пост-обработать отрендеренный products_scroller (добавить в него разметку для аналитики). Просьба. Добавьте, пожалуйста, точку расширения — хук перед exit;: /** * Fires after the join products scroller is rendered, before the AJAX response is sent. * * @param array $block Block data * @param array $products Products shown in the join tab */ fn_set_hook('ab__ia_joins_get_join_products', $block, $products); exit; (при желании — с guard if (isset($block, $products)) { ... }). Изменение минимальное, логику модуля не меняет — просто даёт штатную точку расширения. Это позволит нам (и другим клиентам) корректно интегрировать аналитику без правок вашего кода. Спасибо!
-
Приветсвую. Изучите плиз на сколько Клавдия Антроповна говорит по дело. Я со своей стороны тесты погонял, замеры поделал. Вроде не вреть. Это и баг т.к. не работает и предложение как решить. Оно конечно только в связки с ядром сработает. Надеюсь вы со своей стороны простимулируете команду Карта к фиксу. Ну а если нет, то предлагаю добавить этот фикс к вам и информацию в справку модуля, как у вас сделано с модулем Мтеатегов например. Я им тоже написаль. Тема: прелоад шрифтов промахивается мимо query в CSS — шрифт грузится дважды fn_ab__p_get_css_timestamp() формирует query для <link rel="preload"> из собственной метки. Она никогда не совпадает с query того же шрифта внутри скомпилированного файла стилей standalone.*.css, потому что ядро (Tygh\Less::parseUrls) пишет туда компайл-тайм TIME, различный у каждого такого файла. Итог: предзагруженный шрифт браузер скачивает повторно при разборе CSS — прелоад не срабатывает, и вместо ускорения получается лишняя загрузка, то есть противоположное назначению модуля. Предложение: привязать query прелоада к cache_id: $cache_id = fn_get_storage_data('cache_id'); if ($cache_id) { return $cache_id; } return Registry::ifGet('ab__preload.timestamp', 0); и по возможности эскалировать правку в ядро (см. выше) — тогда query прелоада совпадёт и со скомпилированными файлами стилей, а с критическим CSS (если он на cache_id) совпадает уже сейчас. Мотивация: сейчас ключевая ценность модуля — предзагрузка ради быстрого первого рендера — для шрифтов не работает вовсе; после правки модуль начинает делать ровно то, что обещает, и снимает у пользователей замечание PageSpeed по шрифтам. Минусов нет: cache_id стабилен в пределах одной генерации ассетов и бампается при очистке кэша — busting сохраняется, а идентичные шрифты получают единый URL во всех скомпилированных файлах стилей.
-
Приветствую. В func.php, fn_ab__dotd_get_plural_rule(): if (__('ab__dotd.countdown.seconds',[],'en') === __('ab__dotd.countdown.seconds',[],$lang_code)) { Если язык en в магазине не установлен, этой строки нет в cscart_language_values, а ядро не кэширует отсутствующие langvars — в итоге на каждой странице с блоком «Товара дня» выполняется лишний SQL-запрос, вечно. Воспроизводится на CS-Cart 4.20.1 ULTIMATE (языки uk/ru): дважды открыть страницу с блоком — запрос виден в дебагере оба раза. Обошли так: INSERT IGNORE INTO cscart_language_values (lang_code, name, value) VALUES ('en', 'ab__dotd.countdown.seconds', '[n] second|[n] seconds|[n] seconds'); Предложение: кэшировать результат функции в static по $lang_code или не запрашивать перевод неустановленного языка. Спасибо!
-
И пожалуйста допилити, чтобы ваш фотосвайпер и видео из вашей же видеогалереи показывал. И научился фотки по кругу бесконечно мотать. Первый пункт так и вовсе очень странно, что не реализован за столько лет. А второй просто удержит людей дольше на сайте. Спасибо!
- 3 ответа
-
- 1
-
-
ага. может даже и писал им когда то про это.. попробуйте еще вы ))
-
/app/functions/fn.products.php вот тут сделать вот так. Уже правда и не помню где это взял и есть ли другой способ.
-
В карте колво товаров по идиотски считается, там количество колонок кажется на 4 умножается. Посмотрите на его форуме про это. При каждой обнове этот кусочек кода правлю. Про баннеры есть настройка учитывать их в количестве товаров или нет. Что то такое.
-
я так не считаю, но удержаться невозможно АБ Лучшие!
-
@ab.support.serhii понял. Думал что может я что то упускаю. Удивлен, что за столько лет это никому не понадобилось. Спасибо. Скажите хоть а зачем город отправления зафиксировали жестко? В чем тут логика?
-
Приветствую. Начали атки вникать в автоматизацию вместо работы в кабинете НП. Сергей, помогите разобраться. Лучше под спойлер уберу)
-
Приветствую. Мы тут ще чуток с Клавдией нарыли. перепроверьте плиз и если она не врет, то добавте. --- Здравствуйте! При генерации карты сайта (CS-Cart 4.20.1, PHP 8.x) в лог пишется предупреждение: Deprecated: strpos(): Passing null to parameter #1 ($haystack) of type string in .../ab__advanced_sitemap/Tygh/Addons/Ab_AdvancedSitemap/XmlBuilder.php on line 250 Причина. В методе generateLinks() переменная $link объявляется только внутри веток switch. Для типов объектов, попадающих в ветку default и не реализующих хук sitemap_link_object (например, объекты от ab__geo_pages, которые формируют ссылку через пост-хук sitemap_link), $link остаётся неинициализированной (null), и строка strpos($link, '?') получает null. На состав карты это не влияет (ссылки добавляются корректно через sitemap_link), но засоряет логи. Предлагаемое исправление — инициализировать переменную перед switch: protected function generateLinks($object_type, $value, $lang_code = '') { $link = ''; // <-- добавить switch ($object_type) { ... } $sep = strpos($link, '?') === false ? '?' : '&'; ... Просьба учесть в следующем обновлении модуля. Спасибо!
