0

In order to improve the pagespeed of my website, Pagespeed Insight suggest to use deferred images instead of lazy jQuery images. I did an attempt according to the recommendations from another topic

Reference Topic on stackoverflow

I use opencart 2 and I tried to change the code in the following way:

  1. I created a small 1x1 pixel gif picture and uploaded this as image/imgdefer.gif.

  2. I placed a javascript file in the head of my header.tpl template which is used for all pages. The script is completely conform to the instructions I found on stackoverflow (sse link above) and varvy.com. The javascript used is:

    <script>
    function init() {
    var imgDefer = document.getElementsByTagName('img');
    for (var i=0; i<imgDefer.length; i++) {
    if(imgDefer[i].getAttribute('data-src')) {
       imgDefer[i].setAttribute('src',imgDefer[i].getAttribute('data-src'));
    } } }
    window.onload = init;
    </script>
    
  3. I replaced the lazy images code in the main.tpl template by the script proposed script in the article, so

Existing Lazy Image script:

<a href="<?php echo $submenu_item['href']; ?>">
   <img width="<?php echo $submenu_item['image_width']; ?>" height="<?php  echo $submenu_item['image_height']; ?>" class="lazy" src="<?php echo $submenu_item['dummy']; ?>" data-src="<?php echo $submenu_item['image']; ?>" alt="<?php echo $submenu_item['name']; ?>"/>
</a>

was replaced by

<a href="<?php echo $submenu_item['href']; ?>">
   <img width="<?php echo $submenu_item['image_width']; ?>" height="<?php echo $submenu_item['image_height']; ?>" src="image/imgdefer.gif" data-src="<?php echo $submenu_item['image']; ?>" alt="<?php echo $submenu_item['name']; ?>"/>
</a>
  1. After applying the code changes in points 1 to 3 above, I receive a notice about a missing offset in vq2_system_modification_system_library_response.php in line 115. The concerned piece of code is listed below. It is the first if instruction (if (count($info) == 3 && $info1[0] == 'src') {) which generates the error.

    preg_match_all('/<img[^>]+>/i', $this->output, $result);
    
    $img = array();
    foreach($result[0] as $img_tag) {
        preg_match_all('/(width|height|src)=("[^"]*")/i',$img_tag, $img[$img_tag]);
    }
    foreach ($img as $k => $info) {
        if (count($info) == 3 && $info[1][0] == 'src') {
        //if (curl_init(str_replace('"', '', $info[2][0]))) {
           $imgfile = str_replace('"', '', $info[2][0]);
           $imgfile = str_replace(HTTP_SERVER, DIR_IMAGE . '../', $imgfile);
           $imgfile = str_replace(HTTPS_SERVER, DIR_IMAGE . '../', $imgfile);
           if (file_exists($imgfile)) {
               $image_info = getImageSize(str_replace('"', '', $imgfile));
               $k = trim($k, '/>');
               $k = trim($k, '>');
               $this->output = str_replace($k, ($k . ' ' . $image_info[3]), $this->output);
           }
        }
    }
    
  2. I did some simulations and I have the impression that $info[1][0] sometimes give 0 as value (empty array?).

Are there suggestions that could help me out and point me in the correct direction? Is this the correct way to implement deferred images?

UPDATE:

I applied the proposal of Novice below which seemed very logical, but the same error "Notice: Undefined offset: 0 in vqmod\vqcache\vq2-system_modification_system_library_response.php on line 115" persists. Only when I delete the script file from point 2 out of my header.tpl, the error is gone.

Could it be that my deferred images only will start loading later (too late) and that the code in point 4 can not be properly executed at the moment it is requested? The code in point 4 is used to provide image and height attributes for all images on the page according to recommendations from google pagespeed?

How to solve? I'm breaking my head for a few days already on this problem, so any suggestions would be very appreciated.

I have to add that there are also other <img> tags - not lazy loading - on this page, but I have deleted all these tags one by one and no matter which img tag I delete, the notice warning persists...

Regards,

SabKo

marc_s
  • 732,580
  • 175
  • 1,330
  • 1,459
SabKo
  • 57
  • 10

1 Answers1

0

It's not empty actually it's failing due to the fact that$info[1][0] is equal to "width" it's so because the regexp. scans in sequential manner whatever comes first get put first since you put width attribute first it goes to gets first position([0]).Note that sequence of qualifies inside an regexp. doesn't matter ie. in most of the cases '/(width|height|src)=("[^"]*")/i gives exactly same output as '/(src|height|width)=("[^"]*")/i.What really matter is order of attributes in your tags what comes first in your subject string and passes the test will get put first.

So if you change tag related code like this

<img src="image/imgdefer.gif" width="<?php echo $submenu_item['image_width']; ?>" height="<?php echo $submenu_item['image_height']; ?>"  data-src="<?php echo $submenu_item['image']; ?>" alt="<?php echo $submenu_item['name']; ?>"/>

Then it would work fine I guess.In case you don't want to change that order you can also edit the condition like if (count($info) == 3 && $info[1][2] == 'src')

Vinay
  • 7,442
  • 6
  • 25
  • 48