Since updating to version 7.x-1.3 we noted our website's response times doubled, and at times the server dragged to a halt. After examining code traces from the slowdowns, we were able to track the slowdown to theme_flickr_photo(). I have tracked it further to the getimagesize() request section, found in flickr.module at Line 320.
// If it is not a square.
if (!isset($width)) {
// Get the real width of the image.
list($width) = getimagesize($img_url);
}
In our case, we are using a single view block containing eight (8) photos. In every case the photo's size is 'm', and the width is 240 pixels. Since the old switch statement worked fine to determine that, it's difficult to understand why we need to make a size request to Flickr.com.
Yet, if I eliminate the size request so that $width is entirely missing, I get three "Undefined variable" notices, but the images renders perfectly and in the correct size.
Is there any way we can eliminate this little getimagesize() call once again? Based on our experience over the last two months, it makes a huge difference in the performance and stability of our website.
| Comment | File | Size | Author |
|---|---|---|---|
| #30 | faster_api_response-2227669-30.patch | 20.56 KB | lolandese |
| #29 | faster_api_response-2227669-29.patch | 19.54 KB | lolandese |
| #28 | faster_api_response-2227669-28.patch | 18.15 KB | lolandese |
| #23 | block_cache_api_implementation-2227669-23.patch | 36.48 KB | lolandese |
| #21 | block_cache_api_implementation-2227669-20.patch | 8.93 KB | lolandese |
Comments
Comment #1
tomogden commentedComment #2
lolandese commentedSee https://drupal.org/comment/8376255#comment-8376255 for possible improvement and the rest of that issue on the reasons behind the implementation.
Can you create a patch based on that info?
Thanks.
Comment #3
lolandese commentedLet me know if this improves the response times sufficiently.
Thanks.
Comment #4
lolandese commentedComment #5
lolandese commentedMoving the function to flickr.inc makes sense as it is a helper function.
Comment #6
tomogden commentedI tried #3 in three different sites, but there was no time improvement over what I was getting for version 1.4.
In the meantime, I'll keep working on a possible patch solution. I'll switch to working with 1.x-dev.
Comment #7
lolandese commentedPatches are always welcome. Usually I test them instantly and always commit with attribution.
Thanks.
Comment #8
tomogden commentedYes, @lolandese, I've noticed your diligent response to everything that gets posted. You are to be commended. :)
Getting familiar with the environment, I've noted that the slowdowns are not actually due to queries at Flickr, since everything is cached. But parsing the very large caches does seem to take a lot of time.
I've also found that Flickr images from tokens in the text (using Flickr Filter) seem to have no calls to flickr_request() at all (unless the cache expires or is cleared), and there is no latency – nice and snappy. I'm using all vertical test images, and width issues come up with "size=-", but all other sizes come out with the correct caption width.
Comment #9
lolandese commentedThat indeed explains why changing the method doesn't have any impact. Good info.
Do you notice a difference between blocks with 'random' images versus for example 'recent'? #2229253: Recent Photo Block - Slow to Access suggests we have the problem affecting also square images in blocks. I don't mark it as a duplicate of this issue yet. Do you experience that as well?
We might consider excluding the width request for images in a block, just like you suggested. That means that each caption would have the same width, independent from the image width. Some (not me) might even prefer a regular grid over the current kind of masonry behaviour. For the text filter we could leave the current behaviour to avoid the problem described in [#8376255].
Comment #10
tomogden commentedSurprisingly, no. Swapping the Recents block with the Random block does not affect load times. That would seem to support the supposition that this is a parsing issue and not a Flickr loading issue.
I increased my sample block to 20 photos and ran more tests, I found:
I would hope that would not be necessary. The code in Flickr Filter is so much simpler than everywhere else, and yet the caption width always correctly matches the photo. I wonder if we couldn't standardize a little more and provide the correct width in the other more complex rendering procedures?
Comment #11
lolandese commentedConclusions so far:
That means getimagesize() is not the culprit as square images don't make use of it. It also explains why the #3 patch (alternative to getimagesize) does not give improvement. Change the issue title to something more appropriate if you agree.
Oops! If block cache is turned on that means it doesn't depend on the dynamic (first time) rendering of a block. In other words, it doesn't dependent on the module code.
To test that create a block with the plain HTML from a module generated block and compare the load times. If the results are identical, it only depends on the remote image URL that loads slow. It still doesn't explain why this occurs particularly with blocks, so next step would be to paste it into a node body and run the same test again.
Both Flickr Filter and Flickr Block use the same code from the main module to render sets (the functions theme_flickr_photo and theme_flickr_photoset).
FYI:
I am working on an extension module that turns all image info from a user, group or set into nodes, except for the image file itself (only the URL). That means that blocks can then be created with Views:
So chances are that eventually Flickr Block as a submodule will become obsolete.
Comment #12
tomogden commentedYes, I wondered about that too. In my test block getimagesize() does NOT result in a flickr_request(), while in my production website's block it does. The two are very different implementations, I suppose. To the point, it seems we are looking to reduce calls to flickr_request().
I'll need to get back to you on that one. I can tell you that I commented out the caching code temporarily and found that load times more than doubled, so at least we know that caching is still valuable where it's at.
I've been comparing the code between the different modules, and I'm finding what look like quite a few differences, many of which are necessary, I'm sure, but there might be some places to standardize. Specifically, I am looking at:
Anyway, it's an interesting exercise for myself in trying to get to know the way things work.
That sounds brilliant and sounds like the logical next step. I think others have tried this before, have they not?
My one concern with this approach is that it mingles the Flickr entities with all of the other nodes. My personal inclination is to keep it as a separate sort of entity. But that's pure philosophy at this point.
Comment #13
tomogden commentedI copied the HTML from the same 20-photo random photo block and inserted it into a new test block. Predictably, the resulting page refreshed in less than a second. To be certain, I double-checked the
<img>tags for their src values. They all specified the Flickr farm, such as:<img class=" flickr-photo-img" height="67" width="100" typeof="foaf:Image" src="https://farm3.staticflickr.com/2323/5809676123_190980d436_t.jpg" alt="U.S. Secretary of State Hillary Rodham Clinton">Comment #14
lolandese commentedThen somehow the blocks are not sufficiently cached. At least this narrows down the probable cause of our issue. Can you try comparing the load times between being logged in and as an anonymous visitor?
Thanks for your help with this.
Comment #15
tomogden commentedI ran the tests again, and found load times are exactly the same.
Comment #16
lolandese commentedDoes this help?
Try on both random and not random blocks, clear cache after applying and reload the same page to be sure a block gets cached.
Comment #17
tomogden commentedNow that makes a difference. The random block times out the same, averaging about 20 seconds, but the recents block averages only 3.5 seconds for all 20 photos.
I also see that the calls to flickr_request() were reduced in that block photos only had a single "search" call for the whole block, instead of a call for each photos.
Comment #18
tomogden commentedWe are still seeing some slowdowns, though. To compare with 7.x-1.2, I cleared the caches and ran the same tests.
Random block of 20 => 5.9 seconds (20 seconds under 7.x-dev)
Recent block of 20 => about .5 seconds (3.5 under 7.x-dev)
I have found that although the number of calls to flickr_request() have remained the same for Flickr Filter and Flickr Field, Flickr Block photos have one more request than previously.
Comment #19
lolandese commentedWorking on a patch to extend a caching mechanism to random blocks and possibly also the others. Comparing load times with previous versions is useful, but after applying the upcoming patch as up to now it seems that effective Flickr block caching was practically absent.
Meanwhile I want to answer some points of #12 that I somehow missed.
Working on that in #2227019: Reduce code, break up big functions and move markup to theme functions/templates. I will look into the functions you mentioned.
The Flickr Rippr modules is a bit similar but does not offer integration with the Flickr module. Besides it didn't have any active development for more than three years. See https://drupal.org/node/130843/commits.
I looked into the "nodes vs entity" matter. Most found "rule of thumb" is that if it is content, using 'node' is appropriate. In any case to build the module based on nodes is a lot easier as a lot of Drupal mechanisms are already in place for them. For entities a lot of additional things need to be set up. Think about e.g. taxonomy that works out-of-the-box for nodes. If in a later stage it results that 'entities' give us advantages over 'nodes', we can always release a 2 version, although it might be hard to supply an upgrade path.
In any case, it will be a separate module as we even consider doing the same with the sub-modules that are now present inside the Flickr module. One might use 'Flickr Filter' but never have intentions to use 'Flickr Field'. It doesn't make sense to force them to download a whole package. Furthermore, splitting it up gives us a better insight on the usage. In any case, if this will happen it will be a 7.x-2.x version. On this point I will open a new issue soon.
Thanks for thinking with me on a broader scale. Your interest is appreciated.
Comment #20
tomogden commentedI look forward to generating nodes for Flickr photos with the new extension module! It sounds like a real winner of a module.
After that last patch, I did a bunch more testing and found the remaining time difference is made up when I switch to square thumbnails (as opposed to commenting out the
list($width) = getimagesize($img_url);intheme_flickr_photo()). That seems to be the last remaining time sync.For our own production website, we will consider switching to square thumbnails.
Comment #21
lolandese commentedAttached patch should improve load times for the random blocks. They will get refreshed once a day. We can make that configurable, but I think for most users that will be okay.
Once confirmed a subsequent patch will follow for the other blocks. Please register the current load time for one of those, so we can see how it improves after applying the upcoming patch.
Also we have to exclude cache for the 'User profile random photos' to avoid displaying the wrong (other user's) images.
Background info at http://www.lullabot.com/blog/article/beginners-guide-caching-data-drupal-7
Comment #22
tomogden commentedGot it. I got a 5% improvement on random photos, but we have a very large collection. Samples had very similar times, but it did seem to improve.
It seems we've done all we can on this issue.
Comment #23
lolandese commentedApplying the attached patch:
In any case it is recommended to use cache warming.
Comment #25
lolandese commentedhttp://drupalcode.org/project/flickr.git/commitdiff/a4f13f4
Thanks Tom, for reporting and testing.
Comment #26
lolandese commentedComment #27
mholve commented.
Comment #28
lolandese commentedGood point. :)
As most sites don't use a form of cache warming, it is important to also reduce load times after the cache has been cleared.
Attached patch reduces the number of photos returned on an API request (instead of 500), depending on the minimum number required to produce usable results for an album. The default limit for random and popularity sort can be set on the Flickr configuration page at admin/config/media/flickr.
Comment #29
lolandese commentedCorrection.
Comment #30
lolandese commentedCorrect counter numbers (totals).
Comment #31
lolandese commentedhttp://cgit.drupalcode.org/flickr/commit/?id=0c7c374
Comment #33
lolandese commentedComment #34
lolandese commentedSee #2367755: D6 maintenance.
Comment #35
lolandese commentedSetting this back to D7 and being 'fixed (closed)'.
Main reason is the fact that links to this issue show the status on hover without revealing the version (6 or 7). This might give the impression that the mentioned issue will not be solved, while in fact it is already fixed for the D7 version. 'Fixed (closed)' reflects the current status correctly for D7. 'Closed (won't fix)' is only valid for the minimally maintained D6 version of the module.