I will spend a bit of time looking into the best way. Events has been suggested and I am having a look at doing it that way also.
Yes, it is definitely worth it because I already lazyload images but on pagespeed tests the space where the image would show up remained empty for a few seconds and that contributed to the LCP. After preloading images, the browser already knows the image that should show up in that space and it is no longer empty and it lowered the LCP and even other metrics of pagespeed.
If that could be done on category pages too, for the first x number of products, from the first one being rendered to the bottom, that would really improve the scores.
Thank you again from the bottom of my soul mike for creating the ocmod, it worked like a charm, right out of the box. I don't know anything about events, but I am sure you know what is all about. Thank you, thank you, thank you!!!
Have a nice weekend!
Now that the issue has been solved, please add: [SOLVED] at the beginning of the subject line on your first post.ovidiusss wrote: ↑Sat Mar 12, 2022 2:42 pmHi,
Yes, it is definitely worth it because I already lazyload images but on pagespeed tests the space where the image would show up remained empty for a few seconds and that contributed to the LCP. After preloading images, the browser already knows the image that should show up in that space and it is no longer empty and it lowered the LCP and even other metrics of pagespeed.
If that could be done on category pages too, for the first x number of products, from the first one being rendered to the bottom, that would really improve the scores.
Thank you again from the bottom of my soul mike for creating the ocmod, it worked like a charm, right out of the box. I don't know anything about events, but I am sure you know what is all about. Thank you, thank you, thank you!!!
Have a nice weekend!
Dedication and passion goes to those who are able to push and merge a project.
Regards,
Straightlight
Programmer / Opencart Tester
in you product controller you can use:
after:
Code: Select all
$data['popup'] = $this->model_tool_image->resize($product_info['image'], $this->config->get('theme_' . $this->config->get('config_theme') . '_image_popup_width'), $this->config->get('theme_' . $this->config->get('config_theme') . '_image_popup_height'));
Code: Select all
// add main image header as preload
$headersImage[] = '<'.$data['popup'].'>; rel=preload; as=image';
Code: Select all
foreach ($results as $result) {
$data['images'][] = array(
'popup' => $this->model_tool_image->resize($result['image'], $this->config->get('theme_' . $this->config->get('config_theme') . '_image_popup_width'), $this->config->get('theme_' . $this->config->get('config_theme') . '_image_popup_height')),
'thumb' => $this->model_tool_image->resize($result['image'], $this->config->get('theme_' . $this->config->get('config_theme') . '_image_additional_width'), $this->config->get('theme_' . $this->config->get('config_theme') . '_image_additional_height'))
);
}
Code: Select all
// add additional images as prefetch
foreach ($data['images'] as $image) {
$headersImage[] = '<'.$image['popup'].'>; rel=prefetch; as=image';
}
// no duplicates
$headersImage = array_unique($headersImage);
// consolidate headers
$headersImageAll = implode(',',$headersImage);
// send headers
$this->response->addHeader('Link: '.$headersImageAll);
DISCLAIMER:
You should not modify core files .. if you would like to donate a cup of coffee I will write it in a modification for you.
https://www.youtube.com/watch?v=zXIxDoCRc84
Thank you very much for your help. I will give it a try.
Can you please tell me the code I need to use for the category? I don't know how to do it, as I am not a developer and in a category I only need to get the preload of images from the first 10 products from the first one that appears at the top and going down....is this even possible?
Thank you very much!
in catalog/controller/product/category.php they are created/retrieved in a loop:
Code: Select all
foreach ($results as $result) {
if ($result['image']) {
$image = $this->model_tool_image->resize($result['image'], $this->config->get('theme_' . $this->config->get('config_theme') . '_image_product_width'), $this->config->get('theme_' . $this->config->get('config_theme') . '_image_product_height'));
} else {
$image = $this->model_tool_image->resize('placeholder.png', $this->config->get('theme_' . $this->config->get('config_theme') . '_image_product_width'), $this->config->get('theme_' . $this->config->get('config_theme') . '_image_product_height'));
}
[...more code here...]
}
so you would just change that to:
Code: Select all
foreach ($results as $result) {
if ($result['image']) {
$image = $this->model_tool_image->resize($result['image'], $this->config->get('theme_' . $this->config->get('config_theme') . '_image_product_width'), $this->config->get('theme_' . $this->config->get('config_theme') . '_image_product_height'));
// add image push header
$headersImage[] = '<'.$image.'>; rel=preload; as=image';
} else {
$image = $this->model_tool_image->resize('placeholder.png', $this->config->get('theme_' . $this->config->get('config_theme') . '_image_product_width'), $this->config->get('theme_' . $this->config->get('config_theme') . '_image_product_height'));
}
[...more code here...]
}
// no duplicates
$headersImage = array_unique($headersImage);
// consolidate headers
$headersImageAll = implode(',',$headersImage);
// send headers
$this->response->addHeader('Link: '.$headersImageAll);
so any controller which has a statement like:
Code: Select all
$xxxx = $this->model_tool_image->resize(.........);
This because preload tells the browser "you must load this now because you need it" whereas prefetch tells it "consider loading this already as you might need it soon" and you do not want the browser to start loading images unnecessarily.
You could do that by using an additional counter instead:
Code: Select all
$inview = 4; // the number of images presumed to be in view on page load of a category page
foreach ($results as $result) {
if ($result['image']) {
$image = $this->model_tool_image->resize($result['image'], $this->config->get('theme_' . $this->config->get('config_theme') . '_image_product_width'), $this->config->get('theme_' . $this->config->get('config_theme') . '_image_product_height'));
// add image push header
if ($inview > 0) {
// push image with preload
$headersImage[] = '<'.$image.'>; rel=preload; as=image';
} else {
// push image with prefetch
$headersImage[] = '<'.$image.'>; rel=prefetch; as=image';
}
$inview--;
} else {
$image = $this->model_tool_image->resize('placeholder.png', $this->config->get('theme_' . $this->config->get('config_theme') . '_image_product_width'), $this->config->get('theme_' . $this->config->get('config_theme') . '_image_product_height'));
}
......
}
// no duplicates
$headersImage = array_unique($headersImage);
// consolidate headers
$headersImageAll = implode(',',$headersImage);
// send headers
$this->response->addHeader('Link: '.$headersImageAll);
DISCLAIMER:
You should not modify core files .. if you would like to donate a cup of coffee I will write it in a modification for you.
https://www.youtube.com/watch?v=zXIxDoCRc84
Thank you very much for the help. I tried the way you mentioned but unfortunately the Largest Contentful Paint, for instance, goes from 6 seconds to 12 seconds after I preload or prefetch the images (I tried both) on a category page and the overall PageSpeed Score goes down, I don't know why...
Thank you again for your help!
I am sure you read somewhere ways to improve your speed and this was a suggestion.This because preload tells the browser "you must load this now because you need it" whereas prefetch tells it "consider loading this already as you might need it soon" and you do not want the browser to start loading images unnecessarily.
If you read above you will understand what prefetch and preload mean. What lazy load does - only start to load when it is in view. You can not follow advice blindly you must consider what it is you are doing. In addition following page speed insights also is an algorithm - and you can get a better score but actually be slower in the real world.
Have you considered reducing your image sizes? This has a greater impact on not only your scores but the real world
Have you considered webp?
https://www.opencart.com/index.php?rout ... earch=webp
If you have images other than just product images, I have one that does all the images in your store.
https://www.opencart.com/index.php?rout ... n_id=43173
DISCLAIMER:
You should not modify core files .. if you would like to donate a cup of coffee I will write it in a modification for you.
https://www.youtube.com/watch?v=zXIxDoCRc84
Now that the issue has been solved, please add: [SOLVED] at the beginning of the subject line on your first post.
Dedication and passion goes to those who are able to push and merge a project.
Regards,
Straightlight
Programmer / Opencart Tester
What - so now you don't even read the heading title :-)straightlight wrote: ↑Mon Mar 14, 2022 10:54 pmNow that the issue has been solved, please add: [SOLVED] at the beginning of the subject line on your first post.
Your worse than a bot.
It must of been for another post, sorry.

Dedication and passion goes to those who are able to push and merge a project.
Regards,
Straightlight
Programmer / Opencart Tester
This Mod works on ALL opencart pages.
It finds the first x number of images and puts the URL in a preload link in the header.
You will have to revert your header files back to original. header.twig and header.php.
Once you have the original files in place then you can install the mod.
Then you can test it for your pagespeed etc etc.
I have now deleted this file and the updated version, fixing duplicates and adding data-src urls for lazy load is here viewtopic.php?f=202&t=227618&p=839452#p839452
.
Dedication and passion goes to those who are able to push and merge a project.
Regards,
Straightlight
Programmer / Opencart Tester
Why ?straightlight wrote: ↑Wed Mar 16, 2022 1:33 amjQuery 2.1.1 may not be reliable on all stores. Adding a JS from the controller would be more ideal, in this case.
Simple. Because custom themes might use another jQuery version while your extension is specifically looking for that filename with the indicated path of: *.mikeinterserv wrote: ↑Wed Mar 16, 2022 1:37 amWhy ?straightlight wrote: ↑Wed Mar 16, 2022 1:33 amjQuery 2.1.1 may not be reliable on all stores. Adding a JS from the controller would be more ideal, in this case.
Dedication and passion goes to those who are able to push and merge a project.
Regards,
Straightlight
Programmer / Opencart Tester
I wrote some non sense here - sorry straightlight :-)straightlight wrote: ↑Wed Mar 16, 2022 2:49 amSimple. Because custom themes might use another jQuery version while your extension is specifically looking for that filename with the indicated path of: *.mikeinterserv wrote: ↑Wed Mar 16, 2022 1:37 amWhy ?straightlight wrote: ↑Wed Mar 16, 2022 1:33 amjQuery 2.1.1 may not be reliable on all stores. Adding a JS from the controller would be more ideal, in this case.
Yes you are correct
also
If a CUSTOM THEME needs ADAPTATION then SO BE IT.
Also in case you haven't noticed it is NOT a GENERAL RELEASE - it is specially made for the OP - If anyone else can make use of it they are welcome.
Point made for the adaptation from my previous reply. However, since this OCMod has been specifically made for the OP, that's fine but it should of been mentioned in the first place in case other users may want to use it in the future. Therefore, you may consider from what I am saying as pointless and wrong, as you say. In the end, I don't see any information regarding the terms of use for other users who may depend on your specific custom-made extensions.mikeinterserv wrote: ↑Wed Mar 16, 2022 3:04 amMy function works with ALL jquery >2.1.1 ^straightlight wrote: ↑Wed Mar 16, 2022 2:49 amSimple. Because custom themes might use another jQuery version while your extension is specifically looking for that filename with the indicated path of: *.
The file is called imgpreload.js - is in the catalog/view/javascript folder so again what you say is completely pointless and WRONG.
Whether JQuery() or $() its going to work 99% of the time. If actually, that is what your referring to.
If a CUSTOM THEME needs ADAPTATION then SO BE IT.
Also in case you haven't noticed it is NOT a GENERAL RELEASE - it is specially made for the OP - If anyone else can make use of it they are welcome.
Dedication and passion goes to those who are able to push and merge a project.
Regards,
Straightlight
Programmer / Opencart Tester
Well I owe you an apology at least about the path targeted in my extension ( I misunderstood ) Yes I will choose another line to replace.straightlight wrote: ↑Wed Mar 16, 2022 3:35 amTherefore, you may consider from what I am saying as pointless and wrong, as you say. In the end, I don't see any information regarding the terms of use for other users who may depend on your specific custom-made extensions.
Other than that yes an adaptation for custom themes may be required but that is quite common to many mods
I am interested to see if it gives the OP the results he is hoping for.
One more thing - something that Mona had put in her code.
Duplicates - I initially didn't even think about that till I saw Monas code and then just noticed it occuring myself so I will have to fix that.
Users browsing this forum: No registered users and 61 guests