• Resolved labm0nkey

    (@labm0nkey)


    I wanted to make this plugin compatible with my custom image sizes. After reading https://github.com/kylereicks/picturefill.js.wp#respond-to-custom-image-sizes my first thought was “Omg why is this so complicated”. Anyway I have edited a bit the code from that article and ended up with following code. It can be improoved but it suits my needs.

    function getImages()
    {
        $images = array(
            'img-320' => 320,
            'img-768' => 768,
            'img-1024' => 1024,
            'img-1450' => 1450,
            'img-1900' => 1900
        );
        return $images;
    }
    
    responsiveImages();
    
    function responsiveImages()
    {
        foreach (getImages() as $key => $val) {
            add_image_size($key, $val, false);
            add_image_size($key . '@2x', $val * 2, false);
        }
        add_filter('picturefill_wp_image_sizes', 'theme_remove_thumbnail_from_responsive_image_list', 11, 2);
    
        function theme_remove_thumbnail_from_responsive_image_list($image_sizes, $image_attributes)
        {
            return array_diff($image_sizes, array('thumbnail', 'thumbnail@2x', 'medium', 'medium@2x', 'large', 'large@2x', 'full'));
        }
    
        add_filter('picturefill_wp_image_attachment_data', 'theme_picturefill_new_size_attachment_data', 10, 2);
    
        function theme_picturefill_new_size_attachment_data($attachment_data, $attachment_id)
        {
            $data = array();
            foreach (getImages() as $key => $val) {
                $data[$key] = wp_get_attachment_image_src($attachment_id, $key);
                $data[$key . '@2x'] = wp_get_attachment_image_src($attachment_id, $key . '@2x');
            }
            return array_merge($attachment_data, $data);
        }
    
        // Add the new image size(s) to the responsive queue
        add_filter('picturefill_wp_image_sizes', 'theme_add_new_small_size_to_responsive_image_list', 11, 2);
    
        function theme_add_new_small_size_to_responsive_image_list($image_sizes, $image_attributes)
        {
            $data = array(); //'thumbnail', 'medium', 'large', 'full');
            foreach (getImages() as $key => $val) {
                array_push($data, $key);
                array_push($data, $key . '@2x');
            }
            if (!in_array($image_attributes['min_size'], $data)) {
                return $data;
            } else {
                return $image_sizes;
            }
        }
    
        // Set the breakpoint for the new image as a new size
        add_filter('picturefill_wp_media_query_breakpoint', 'theme_picturefill_new_small_size_breakpoint', 10, 3);
    
        function theme_picturefill_new_small_size_breakpoint($breakpoint, $image_size, $width)
        {
            foreach (getImages() as $key => $val) {
                if (in_array($image_size, array($key, $key . '@2x')))
                    return $val;
            }
            return $breakpoint;
        }
    
    }

    I think that everything is properly done here but still there is one critical bug. When I open any website with picturefill code the above code is executed and the filter “picturefill_wp_image_attachment_data” is applied in file picturefillwp\inc\class-model-picturefill-wp.php on line 100. After that there is this loop

    foreach($image_attachment_data as $attachment_size => $attachment_data){
              if($this->image_needs_to_be_created($image_attachment_data, $attachment_size, $attachment_data)){
                $new_meta_data = wp_generate_attachment_metadata($attachment_id, get_attached_file($attachment_id));
                wp_update_attachment_metadata($attachment_id, $new_meta_data);
                $image_attachment_data[$attachment_size] = wp_get_attachment_image_src($attachment_id, $attachment_size);
              }
            }

    Which increases load time about 10 times longer. When there is more that one image (in my case about 15) page loads in 20 minutes… When I comment out this loop. Everything works fine and page loads instantly. Whats the point of this loop? Can this be fixed?

    http://wordpress.org/plugins/picturefillwp/

Viewing 4 replies - 1 through 4 (of 4 total)
  • Plugin Author kylereicks

    (@kylereicks)

    I apologize for the complexity of customizing the plugin. I knew that I wouldn’t be able to imagine every use-case, so I prioritized diligent hooking to allow theme authors to use the plugin as a jumping off point. The upcoming feature release, version 1.3.0, adds an abstraction layer to facilitate the most common customizations. I hope it will make things a little less confusing.

    The code you have highlighted is indeed the most resource intensive part of the plugin. It checks to see if an image size exists and if it does not, if it can be created. It then creates those images, if required. It is creating the images that really eats up resources, especially when there are several images on the page, as you noted. This should, however, only need to occur when an image was uploaded before the Picturefill.WP plugin was active (add_image_size() should ensure that image sizes are created at upload), and then only once. On subsequent page loads, the plugin should recognize that the image exists on the sever, and move on.

    In addition, transient caching is applied early in the plugin’s function. In class-picturefill-wp.php you will notice the cache_picturefill_output method checks to see if the post has been updated since the last time the plugin was run, if not the plugin simply returns the same content as before and skips further computation.

    If the plugin is working as it is supposed to, the first load of a page will take some extra time. On image heavy posts created before Picturefill.WP was activated, this may even take minutes. After the page successfully loads, things should be significantly faster.

    The first thing I would like you to do, if you are willing, is take another look at your use of add_image_size(). You are setting the height of the images to false, which evaluates to 0 with PHP’s intval(). If this is preventing WordPress from creating new images, that may be the source of the issue. You may want to try something like add_image_size($key, $val, 9999, false); if the image height is not important to the design.

    Next, try loading the page a few more times with the full plugin code. If it is still taking several minutes after 2 or 3 loads, check the http://yoursite.com/wp-admin/options.php page for the transient fields. They should look something like _transient_picturefill_wp_the_content_output_{post_id}_p1. After the first successful load of the page, these should contain the full content of your post with Picturefill.WP’s alterations.

    Also, take a quick look in the uploads directory and see if the image files exist as you would expect them to.

    I will take some time this weekend to try to duplicate the issue, to see if there is anything else that might be causing trouble.

    Thanks very much for bringing up the issue.

    Thread Starter labm0nkey

    (@labm0nkey)

    That first fix worked. After setting height to 9999 page loads just fine. So the real problem is that if I don’t set height in my custom image size It is recreated on every page load. I understand that on first load some images that are missing should be recreated but in my case I used another plugin to recreate every image in every size so they already existed and still your plugin thought that it needs to be done. Additionally I’ve let it recreate images on first load which took 26 minutes on my local server and still they were recreated again on next page load. To sum this up something, somewhere thinks that when height is not mentioned the image has to be always recreated.

    Getting back to the complexity of adding custom sizes in this plugin. I think that the aim of this plugin to work out of the box is perfectly achieved. Look on this from another side – after all the stuff done in this plugin the output is simple “picturefill” html output. The syntax of it is in most cases the same and the only thing that can be different is the list of image sizes and their breakpoints. Image sizes with all needed attributes are already passed with add_image_size, also as you can see in my example in first post adding custom sizes can be easyly automated. A perfect and not so complicated solution for me would be adding a filter which has an array of all image sizes that should be included where by default only wordpress standard sizes are flagged “true” to be in the output (At this point plugin would work exactly same as now) and all other could be also included just by switching their flags to true.

    Thank you for help and for this plugin.

    Hi Kyle,

    Sorry to bump a thread, and for being such a huge pain in your ass but I’m STILL having page load problems. I’ve tried to disable several plugins to see if I’m getting a conflict and met with the same problems.

    I realized I wasn’t setting my height (using 0) so I tried the value 9999 as suggested here, and my pages still seem to be re-generating the thumbs every time! (It’s the only solution that makes sense to me, disabling PicturefillWP leads to fast page loads.

    Could you take a peek at

    http://zachatkinson.com/web-services/

    And see if it doesn’t appear to hang for you too? So confused as to what could be going wrong.

    All fixed now!

Viewing 4 replies - 1 through 4 (of 4 total)
  • The topic ‘Poor performance with custom image sizes’ is closed to new replies.