Перейти до вмісту
Пошук в
  • Детальніше...
Шукати результати, які ...
Шукати результати в ...

kJlukOo

Користувачі
  • Публікації

    1 707
  • З нами

  • Відвідування

Записи блогу, опубліковані користувачем kJlukOo

  1. kJlukOo
    Причин может быть масса от конфига сервера, до тяжелых запросов к бд, проблемы с dns, cdn и тд
    Возьмем то случай, когда ваш VPS имеет много ресурсов и настроен серьезным специалистом, а  значит проблема на стороне опенкарта и плагинов, которые были установлены
     
    Обычно первым делом включают лог тяжелых запросов. Опенкарт в момент создания таблицы выбирает тип таблиц ENGINE=MyISAM. Этот тип может блокировать таблицы, именно поэтому в логе можно встретить простейшие запросы выполняющиеся по 2+ секунды. Лучше перейти на innodb. На просторах гитхаба есть скрипт, который поможет сменить движок хранилища, а так же добавить индексы к таблицам. Кстати, индексы он добавляет всем столбцам, которые содержат подстроку "_id" 
    https://github.com/lilalaunesau/opencart-turbo
     
    Но одним логом сыт не будешь и поэтому я написал решение, которое покажет время работы каждого контроллера на странице.
    Предварительно желательно отключить кеширование mysql. За это отвечают такие параметры конфигурации как 
    query_cache_size        = 0 query_cache_type        = 0  
    С скрина, который прикреплен к этому посту можно сделать вывод, что менюшка не кешируется и грузится около 640мс
    Один из моих модулей отрабатывает за 100мс, что тоже не есть хорошо, но с учетом того что на этой странице таблица из 10+ товаров, то норм
    Футер тоже можно закешировать сэкономив около 300мс
     
    Если этот пост набирает 5 комментов, то выложу это решение. Напоследок хочу сказать, что продакшн это святое и любые тесты и замеры нужно делать на дев, тест или локальном окружении под присмотром профессионалов. Если я где-то некорректно выразился, то пишите поправим
     

  2. kJlukOo
    Надоело во время разработки дергать обновление модификаторов перед каждым обновлением страницы ?
    Я нашел в себе силы и написал решение. работает по хоткею CTRL + B на витрине сайта
    Единственное условие для работы модификатора - нужно быть авторизованным в админке
     
    https://github.com/kjpower/Refresh-opencart-page-with-modif/blob/main/upload/system/refresh_page_with_modif.ocmod.xml
    работает на 2.3.х и 3.х
     
    если полезно то ставь лайк и беги покупать мои дополнения 
  3. kJlukOo

    обсуждение
    почему все разработчики тем оставляют выбор кол-ва в карточке товара?
    оптовики это нная часть от всех инет магазинов, почему бы по умолчанию не скрыть это поле
    господа, ваши мысли по этому поводу?
    кстати алло, розетка, элмир, мойо - не имеет кол-ва в карточке товара. только в корзине
  4. kJlukOo

    cache
    привет форумчане. статья может быть полезна для начинающих разрабов и тех, кто недавно столкнулся с опенкартом
    штатный кэш опенкарта
    1. ocmod
    обновляется в админке. меню слева - расширения - модификаторы.
    обновить можно следующим образом

     
    рекомендации:
    когда сайту плохо и вы получаете 404 можно сделать очистку всех модификаторов - нажав на желтую кнопку с ластиком, чтобы убедиться, что дело не в них в бд в таблице oc_modification колонка xml легко поддается поиску через интерфейс phpMyAdmin перед работой с сайтом желательно сохранить все модифицированный файлы - storage/modification  
    2. twig and sass cache (3.x)
    opencart и ocstore 3 ветки обзавелся twig шаблонизатором, который умеет кэшироваться
    настраивается это в админке. в левом меню пункт панель состояния


     
    рекомендации: отключить перед работой с сайтом. после завершения не забыть включить
     
    3. opencart file/mem cache
     
    библиотека для разработчиков. которая используется так
    $this->cache->set('test','value'); $val = $this->cache->get('test'); содержимое кэша по умолчанию находится в system/storage/cache
    для файлового кэша очищается посредством удаления содержимого папки
    для мемкэша очищается вызовом пары команд в консоле. это легко гуглится
    в этот хранилище обычно кэшируется языки, валюты и меню сайта
     
    рекомендации: можно кэшировать любой статический контент сайта, например футер или блок преимуществ
    по возможности используйте мемкэш или редис, если вы используете файловый кэш - ssd и m.2 в помощь
     
    4. image cache
    опенкарт создает кэш изображений под размеры указанные в настройках темы
    этот кэш находится в image/cache. чтобы очистить - удалите содержимое этой папки
     
    рекомендации: не избыточное разрешение, webp и отложенная загрузка изображений. ну и верный Cache-control для изображений от сервера
     
    5. design/theme (3.x)
    этот инструмент кэширует представления(view) в бд
    находится в левом меню. дизайн - редактор шаблона
    на скрине ниже можно увидеть, что файл account/account закэширован
    изменение этого файла на сервере не даст ожидаемого результата

     
    рекомендации: желательно не использовать вовсе
     
    6. внештатные дополнения для кэширования
    тут наши полномочия все. следуйте рекомендациям автора и читайте руководства к модулям
     
    рекомендации: чтобы сделать ваш сайт быстрым нужен индивидуальный подход. общие решения не дадут нужного эффекта. тут зеленыЙ прав
     
    клиентский кэш
    это кэш вашего браузера. заголовок ответа сервера Cache-control является инструкцией для браузера
    пример блока из конфига для nginx, который отдаст инструкцию браузеру к кэшированию js, css, jpeg на 72 часа
    location ~* \.(css|js|gif|jpeg|jpg|png)$ { expires 3d; access_log off; add_header Pragma public; add_header Cache-Control "public, max-age=259200"; add_header X-Asset "yes"; }  
    этот кэш отключается следующим образом для google chrome:
    1. нажатие хоткея CTRL + F5 приведет к перезагрузке страницы со сбросом кэша
    2. отключаем кэширование браузера в инструментах разработчика. под спойлером
     
    поправляйте если где-то ошибаюсь

  5. kJlukOo
    при работе с опенкартом всегда возникает необходимость обновлять модифы, после ряда совершенных правок.
    делается это для того, чтобы получить актуальный контент
    давным давно я решил этот вопрос программно, что избавило меня от кучи головной боли в виде открытия вкладки и нажатия кнопки обновления модифов раз за разом
    я решил этот вопрос программно следующим образом. пришло время делиться
     
    1. авторизация по ссылке
     быстрая авторизация в админке по ссылке.
     
    перед использованием модификатора обязательно изменить эти значения на свои
     
    $secret_key = 'secret_key64587967'; $secret_val = 'eret345dfgc342';  
     
    ссылку в админку для обновления модификаторов выглядит следующим образом
    https://site.com/admin/index.php?route=extension/modification/refresh
    добавим к этой ссылке нашу секретную пару
    https://site.com/admin/index.php?route=extension/modification/refresh&secret_key64587967=eret345dfgc342
    в вашем случае ссылка должна отличаться
     
     
     
    <?xml version="1.0" encoding="utf-8"?> <modification> <name>fast admin auth fix</name> <code>fast admin auth fix</code> <version>1.3</version> <author>kJluk</author> <link>cleanphp.ru</link> <file path="admin/controller/common/login.php"> <operation> <search><![CDATA[public function index() {]]></search> <add position="after"><![CDATA[ //обязательно измените эти значения! $secret_key = 'secret_key64587967'; $secret_val = 'eret345dfgc342'; if(isset($this->request->get[$secret_key]) && $this->request->get[$secret_key]==$secret_val) { $this->session->data['user_id'] = 1; $token = token(32); $this->session->data['token'] = $token; $url=HTTPS_SERVER.'index.php?'; $params = array('token' => $token); if(!empty($this->request->get['route'])) $params['route']=$this->request->get['route']; $this->response->redirect($url.http_build_query($params)); } ]]></add> </operation> </file> </modification>  
     
    2. Запрос к обновлению модифов используя авторизацию по ссылке
    эта функция, которые прекрасно скушает 302 редирект, после успешной авторизации
    путь к куки должен быть ваш. куки должен лежать в какой-то закрытой папке
    ее необходимо разместить в system/library/helper.php. возможно это правильно сделать модификатором, но мне лень
     
     
    function curlWihteRedir($url) { //путь к куки должен быть ваш $path_to_cookie = '/path_to_cookie/cookies.rip'; $ch = curl_init(); curl_setopt($ch, CURLOPT_URL, $url ); curl_setopt($ch, CURLOPT_RETURNTRANSFER, TRUE); curl_setopt($ch, CURLOPT_HEADER, 0); curl_setopt($ch, CURLOPT_FOLLOWLOCATION, 1); curl_setopt($ch, CURLOPT_COOKIEJAR, $path_to_cookie); curl_setopt($ch, CURLOPT_COOKIEFILE, $path_to_cookie); curl_setopt($ch, CURLOPT_TIMEOUT, 30); curl_setopt($ch, CURLOPT_USERAGENT, "Mozilla/4.0 (compatible; MSIE 5.01; Windows NT 5.0)"); curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false); curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, false); $response = curl_exec($ch ); curl_close($ch); return $response; }  
    3. Использование
    вызываем функцию с ссылкой, которую получили в 1п для быстрой авторизации.
    обычно вызывать функцию нужно в начале метода контроллера
    curlWihteRedir(HTTPS_SERVER."index.php?route=extension/modification/refresh&secret_key64587967=eret345dfgc342");  
  6. kJlukOo
    catalog/model/catalog/product.php
    метод getProducts имеет следующий цикл
    foreach ($query->rows as $result) { $product_data[$result['product_id']] = $this->getProduct($result['product_id']); } те на каждый товар категории у нас создается отдельный запрос с кучей условий. как избавится от порождения кучи новых запросов?
    получить все в одном запросе. без цикличного вызова метода getProduct
    foreach ($query->rows as $result) { $product_data[$result['product_id']] = $result; } в родном запросе мы получим: id, рейтинг, акцию и дискаунт
    в моем случае для категории мне нужно:  количество, изображение, название товара, id , цена
    //исходный $sql = "SELECT p.product_id, (SELECT AVG(rating) AS total FROM " . DB_PREFIX . "review r1 WHERE r1.product_id = p.product_id AND r1.status = '1' GROUP BY r1.product_id) AS rating, (SELECT price FROM " . DB_PREFIX . "product_discount pd2 WHERE pd2.product_id = p.product_id AND pd2.customer_group_id = '" . (int)$this->config->get('config_customer_group_id') . "' AND pd2.quantity = '1' AND ((pd2.date_start = '0000-00-00' OR pd2.date_start < NOW()) AND (pd2.date_end = '0000-00-00' OR pd2.date_end > NOW())) ORDER BY pd2.priority ASC, pd2.price ASC LIMIT 1) AS discount, (SELECT price FROM " . DB_PREFIX . "product_special ps WHERE ps.product_id = p.product_id AND ps.customer_group_id = '" . (int)$this->config->get('config_customer_group_id') . "' AND ((ps.date_start = '0000-00-00' OR ps.date_start < NOW()) AND (ps.date_end = '0000-00-00' OR ps.date_end > NOW())) ORDER BY ps.priority ASC, ps.price ASC LIMIT 1) AS special";  
    заменим
    SELECT p.product_id
    на
    SELECT p.product_id, p.image, p.price, p.quantity, pd.name
     
    $sql = "SELECT p.product_id, p.image, p.price, p.quantity, pd.name, (SELECT AVG(rating) AS total FROM " . DB_PREFIX . "review r1 WHERE r1.product_id = p.product_id AND r1.status = '1' GROUP BY r1.product_id) AS rating, (SELECT price FROM " . DB_PREFIX . "product_discount pd2 WHERE pd2.product_id = p.product_id AND pd2.customer_group_id = '" . (int)$this->config->get('config_customer_group_id') . "' AND pd2.quantity = '1' AND ((pd2.date_start = '0000-00-00' OR pd2.date_start < NOW()) AND (pd2.date_end = '0000-00-00' OR pd2.date_end > NOW())) ORDER BY pd2.priority ASC, pd2.price ASC LIMIT 1) AS discount, (SELECT price FROM " . DB_PREFIX . "product_special ps WHERE ps.product_id = p.product_id AND ps.customer_group_id = '" . (int)$this->config->get('config_customer_group_id') . "' AND ((ps.date_start = '0000-00-00' OR ps.date_start < NOW()) AND (ps.date_end = '0000-00-00' OR ps.date_end > NOW())) ORDER BY ps.priority ASC, ps.price ASC LIMIT 1) AS special";  
    //тесты
     
    10 срезов по ttfb показали
    категория 50 товаров. 62.8 => 23.5 ms
    категория 30 товаров: 45.8 => 22.7 ms
     
     
    $startTime = microtime(true); $query = $this->db->query($sql); foreach ($query->rows as $result) { $product_data[$result['product_id']] = $result; //$product_data[$result['product_id']] = $this->getProduct($result['product_id']); } $msec = (microtime(true) - $startTime)*1000; if($_SERVER['REMOTE_ADDR']=='ваш айпи') { echo round($msec,2); exit(); }  
     
     
  7. kJlukOo
    недавно увидел что на официальном сайте продается драйвер под редис. ссылку прикладывать не буду
    а вот тот самый редис, который уже давно есть на гитхабе (с 6 июля 2017 года)
    https://github.com/opencart/opencart/blob/master/upload/system/library/cache/redis.php
     
    как кеш опенкарта делегировать редису?
    чтобы заставить работать редис на своем сервере необходимо 
     
    1. установить редис и добавить его в список автозагрузки, установить php модуль для редиса . для разных осей комманды могут отличаться. гугл в помощь!
    2. актуально для всей ветки 2х ocstore/opencart. в 3х версии окстор и опенкарт драйвер  уже есть
    создаем файл system/library/cache/redis.php содержимое вот https://github.com/opencart/opencart/blob/master/upload/system/library/cache/redis.php
    3. создаем файл redis_test.php в корневой директории сайта, вызывать его будем следующим образом https://site.com/redis_test.php
    это мы делаем, для того, чтобы протестировать редис перед включением, чтобы избежать краша магазина
    <?php ini_set('display_errors', '1'); ini_set('display_startup_errors', '1'); error_reporting(E_ALL); include __DIR__.'/system/library/cache/redis.php'; $expire = 5000; //namespace opencart 4 O_O $obj_redis = new Opencart\System\Library\Cache\Redis($expire); //namespace opencart 3x //$obj_redis = new Cache\Redis($expire); $obj_redis->set('key', 'REDIS WORK FINE'); $res = $obj_redis->get('key'); echo $res; сохраняем файл. открываем браузер и вызываем https://site.com/redis_test.php
    если видим REDIS WORK FINE то сразу к следующему пункту
    ошибки, которые могут говорить о
    криво установленном редисе => пункт 1 отсутствии файла => пункт 2 не забывайте. что редис должен быть включен и установлен пхп модуль редис  
     
    4. этот пункт выполняем только в случае, если в п3 видим REDIS WORK FINE
    в конфиге по пути ocs23/system/config/default.php 
    находим строку
    $_['cache_type']           = 'file'; // apc, file or mem и меняем на 
    $_['cache_type']           = 'redis'; // apc, file or mem  
     
     
  8. kJlukOo
    использовать родной кеш можно следующим образом
    $this->cache->get($key); $this->cache->set($key); $this->cache->delete($key); настройки родного кеша хранятся тут system/config/default.php
    по умолчанию в ocstore 2.3 кеш файловый, который живет один час
    $_['cache_type'] = 'file'; // apc, file or mem $_['cache_expire'] = 3600;  
    file       - файловый кеш (значения хранятся в файлах). ссдшник кстати поди ускоряет работу этого кеша
    mem    - кеш хранящийся в оперативной памяти, етесно он быстрее чем файловый
    apc      - честно не знаю, что это за тип, но гугл говорит - APC (Alternative PHP Cache) - бесплатный и открытый opcode кэшер для PHP.
     
    инициализируется родной кеш в файле system/framework.php для того, чтобы он был доступен для использования в любом контроллере
    $registry->set('cache', new Cache($config->get('cache_type'), $config->get('cache_expire'))); чтобы использовать своей кеш, который будет жить сутки, можно сделать так
     
    $mycache = new Cache('file', 60*60*24); $mycache->set('test',1); кстати, для использования мемкеша нужно проводить дополнительные манипуляции с определением констант, которые в нем используются. это легко гуглится
     
  9. kJlukOo
    var delay_sec = 10 * 60; // 10 min function init_delayed_modal() { var first_visit_time = get_cookie('first_visit_time'); var current_time = new Date().getTime() / 1000; var time_passed; if(first_visit_time == undefined) { // first time visit create_cookie('first_visit_time', current_time); setTimeout(show_modal,delay_sec * 1000); } else { // two and more time visit time_passed = current_time - first_visit_time; //if time left if(time_passed>delay_sec) show_modal(); else setTimeout(show_modal,(delay_sec - time_passed) * 1000); } } function show_modal() { // set cookie and show modal create_cookie('modal_alredy_show', true); alert('modal'); } //https://stackoverflow.com/questions/1458724/how-do-i-set-unset-a-cookie-with-jquery function get_cookie(name) { var matches = document.cookie.match(new RegExp( "(?:^|; )" + name.replace(/([\.$?*|{}\(\)\[\]\\/\+^])/g, '\$1') + "=([^;]*)" )); return matches ? decodeURIComponent(matches[1]) : undefined; } //https://stackoverflow.com/questions/1458724/how-do-i-set-unset-a-cookie-with-jquery function create_cookie(name, value, days) { var expires; if (days) { var date = new Date(); date.setTime(date.getTime() + (days * 24 * 60 * 60 * 1000)); expires = "; expires=" + date.toGMTString(); } else expires = ""; document.cookie = encodeURIComponent(name) + "=" + encodeURIComponent(value) + expires + "; path=/"; } if(get_cookie('modal_alredy_show') == undefined) init_delayed_modal();  
    допустим нам необходимо однократно показать юзеру сообщение спустя 10 минут нахождения на сайте. чистый джс

×
×
  • Створити...

Important Information

На нашому сайті використовуються файли cookie і відбувається обробка деяких персональних даних користувачів, щоб поліпшити користувальницький інтерфейс. Щоб дізнатися для чого і які персональні дані ми обробляємо перейдіть за посиланням . Якщо Ви натиснете «Я даю згоду», це означає, що Ви розумієте і приймаєте всі умови, зазначені в цьому Повідомленні про конфіденційність.