Slow page loading

Hello,

I am developing this site, and I am experiencing slow page loads. Some times loading speed is normal, other times too slow.

I was using barba.js for transitions, and this slowness broke it’s effect. I now disabled it to rule out this dependency being the problem.

Could the problem be in my php code and Kirby rendering? Server response time? I see in the browser’s network tab that when a slowdown is happening, the requested page has a ‘pending’ status for some seconds. What is happening during that time?

Any ideas about how to test, what to check etc would be appreciated.

Site speed seems fine to me. Are you still having issues?

Yes, still. It doesn’t happen on every page load, but it happens very often.

You have a lot of high resulution photos being displayed much smaller. Make use of the resize function. I can see many of the images are in excess of 2,000px but you are only displaying them at around 600px on the page.

Check your PHP memory settings also - with all this heavy image work, setting it to atleast 2048mb. When i looked now, the home page was very slow but was fine earlier. Do you have something that might touching the files? The media generation uses file hashing to tell if an image has changed. It is as if the media folder keeps getting deleted or the files them selves are changing enough to cause regeneration.

I am using responsive images and lazy loading. The media files don’t seem to be regenerating, as I can infer from the date/time the files are created.

For the home page, this loop seems to be responsible for the slowness:

<?php if ($items->isNotEmpty()): ?>
  <?php foreach ($items as $item):
    $photo = $item->featured_photo()->toFile();
  ?>
    <article class="item"
              data-element="item"
              data-category="<?= str_replace(' ', '-', $item->category()->lower()) ?>"
              data-orientation="<?= !is_null($photo) ? $photo->orientation() : '' ?>">

      <a href="<?= $item->url() ?>">
        <?php if (!is_null($photo)): ?>
            <img srcset="<?= $photo->srcset([800, 1200, 1600]) ?>"
                  sizes="(max-width: 760px) 100vw, (max-width: 1360px) 50vw, 35vw"
                  src="<?= $photo->url() ?>"
                  width="<?= $photo->width() ?>"
                  height="<?= $photo->height() ?>"
                  alt="<?= $photo->alt() ?>"
                  loading="<?= e($item->indexOf() > 3, 'lazy', 'auto') ?>">
        <?php endif ?>

        <span class="heading t1 bold"><?= $item->title() ?></span>
        <span class="subheading t-1"><?= $item->category() ?></span>
      </a>
    </article>
  <?php endforeach ?>
<?php endif ?>

On a project page, the slowness comes from Blocks. An image block:

<?php
  /** @var \Kirby\Cms\Block $block */
  $image   = $block->image()->toFile();
  $alt     = $block->alt();
  $caption = $block->caption();
  $src     = $image->url();
  $width   = $block->width();
  $sizes_l = null;
  $sizes_p = "(min-width: 500px) 50vw, (min-width: 1360px) 35vw, 100vw";

  switch ($width) {
    case "full":
      $sizes_l = "100vw";
      break;
    case "normal":
      $sizes_l = "(min-width: 1360px) 60vw, 100vw";
      break;
    case "small":
      $sizes_l = "(min-width: 1360px) 40vw, 100vw";
      break;
  }
?>

<?php if ($src): ?>
  <figure
    class="<?= $width ?>"
    data-orientation="<?= $image->orientation() ?>">
    <img srcset="<?= $image->srcset([800, 1200, 1600, 2000, 2800]) ?>"
         sizes="<?= e($image->orientation() == 'landscape', $sizes_l, $sizes_p) ?>"
         src="<?= $src ?>"
         width="<?= $image->width() ?>"
         height="<?= $image->height() ?>"
         alt="<?= $alt ?>"
         loading="lazy">

    <?php if ($caption->isNotEmpty()): ?>
      <figcaption><?= $caption ?></figcaption>
    <?php endif ?>
  </figure>
<?php endif ?>

Are the above too expensive to calculate fast for many items on a page?

It is my understanding (but I could be wrong) that calling ->width() and ->height() is quite resource intensive because the server doesn’t have those info stored somewhere and it has to load the resources first in order to calculate those values and return you the correct information.

Maybe that is why your server is taking a long time to return the content of your page.

As I said, I could be 100% wrong though.

Both width and height are properties of the image object though just like url, alt etc., so these calls shouldn’t have any additional effect on performance.

I followed @manuelmoreale’s advice (removed width/height and orientation) and curiously, the problem is gone. I would still need these dimensions and orientation though. I also noticed that as @jimbobrjames said, some images are huge, I missed that they were 300dpi. But even with those, I was expecting the page to load normally, and only the images to download late.

What you could do is store this information in the file metadata.

Can this be done automatically on file upload or replacement?

Yes, via a file.upload:after/file.replace:after hook.

Can this be done automatically on file upload or replacement?

This is exactly what I ended up doing in all my sites.
I have a hook that stores width, height and a few other things.
looks like this

'file.create:after' => function ($file) {

    # Exit if we're not working with a web image
    if (!in_array($file->extension() , ['gif' , 'jpg' , 'jpeg' , 'png']))
        return true;

    // Add the relevant meta info
    return $file->update([
        'w' => $file->width(),
        'h' => $file->height(),
    ]);

},

'file.replace:after' => function ($newFile, $oldFile) {
    kirby()->trigger('file.create:after', ['file' => $newFile]);
}
4 Likes

As I said, I could be totally wrong but the last time I looked into this I remember finding out that since those info are not stored anywhere, at some point the server has to load those images into memory in order to calculate those dimensions.

I don’t think you can avoid it because php has no idea how big an image is until it has loaded it and “measure” it.

Again, I could be completely wrong but I remember that being the case at least for me the last time I looked into this and it’s why I ended up storing those values into the file txt

Usually it’s not an issue but it becomes one if you’re dealing with a lot of big images.