Follow-up to #2260061: Responsive image module does not support sizes/picture polyfill 2.2
- Adjusts theme('responsive_image') to require the caller to provide a 'width' and 'height', like theme('image_style') does. The 95% use case caller (the image field formatter) passes the dimensions anyway (the Imageitem has them).
This improves consistency bewteen responsive and non-responsive styles.
- Improves perf by removing the code that repeatedly reads the dimensions from the file. We stopped doing that in D7 (IIRC) for image styles for performance (reading dimensions on each output can be nastly if the file is not local ?)
Also, removes the need to create an ImageInterface object for the file altogether.
- As a side effect, strramlines a bit the logic between template_preprocess_responsive_image_formatter() responsive_image_build_source_attributes() and how they work together.
- Adjusts the phpdoc for responsive_image_build_source_attributes() accordingly, and fixes a couple nits while we're in there :-)
Beta phase evaluation
Issue category | Task: Improve performance and consistency of the theme function responsive images |
---|---|
Issue priority | Not critical (but the perf impact for repeatedly reading dimensions from non-local files might be noticeable ?) |
Prioritized changes | The main goal of this issue is performance (and streamlining some code) |
Disruption | Disruptive for contributed modules that call theme('responsive_image') directly, they now need to pass the explicit 'width' and 'height' of the image - should be pretty limited, the main entry point for this is Core's ResponsiveImageFormatter |
Original report by [username]
I think we can still streamline responsive_image_build_source_attributes() a bit, but this can totally happen in a followup.
This needs a bit more information ;-)
Comment | File | Size | Author |
---|---|---|---|
#85 | 2423743-85.patch | 10.54 KB | Nitin shrivastava |
#83 | 2423743-83.patch | 10.51 KB | mrinalini9 |
#81 | reroll_diff_79-81.txt | 7.37 KB | Medha Kumari |
#81 | 2423743-81.patch | 10.36 KB | Medha Kumari |
#79 | interdiff_78_79.txt | 3.84 KB | ameymudras |
Issue fork drupal-2423743
Show commands
Start within a Git clone of the project using the version control instructions.
Or, if you do not have SSH keys set up on git.drupalcode.org:
Comments
Comment #1
yched CreditAttribution: yched commentedPatch mostly moves the "image dimensions" logic, currently split between template_preprocess_responsive_image() and responsive_image_build_source_attributes() (which then just redoes the same logic for all source tags), all the way into the former.
This makes it clearer that responsive_image_build_source_attributes() only needs a $dimensions array with 'width' and 'height', not the full $variables array from template_preprocess_responsive_image() with lots of other stuff it doesn't use.
Then, this clarifies that I don't understand that logic to begin with :-) :
- We allow calling #theme 'responsive_image' passing forced, pre-defined width and height.
- the beginning of template_preprocess_responsive_image() has a comment saying "if present, we'll output them", but that seems misleading: unlike what theme_image() does with "flat" imgs, we don't output those as 'width' / 'heigth' attributes in the HTML
- Those dimensions are forced as "the dimensions of the original image" to compute the resulting pixel width of the various image derivatives used in the srcset.
So I'm confused why would you would want to pass arbitrary dimensions there, other than the ones of the actual original image ? That sounds like it would totally mess the resulting widths in the srcset ?
Patch then does a couple other cleanups I found along the way:
- Adds a couple comments for balance, and adjust those about the "fallback image"
- Visually aligns the two mappings added in the code sample in the phpdoc for responsive_image_build_source_attributes()
- in that same code sample, changes the 'sizes_image_styles' to a simple numeric array without the duplicate key/values (the config schema says it's a sequence, so it's the only thing that's ever going to get saved anyway ?)
- Fixes the @return doc (a single Attribute object rather than an array now)
Comment #3
yched CreditAttribution: yched commentedOh, of course, patch is rolled on top of #2260061: Responsive image module does not support sizes/picture polyfill 2.2, so it's out of reach for the tesbot for now.
Comment #4
Wim Leers#2260061: Responsive image module does not support sizes/picture polyfill 2.2 got committed (YAY!), hence this is now unblocked :)
Comment #5
Wim LeersLet's see if the patch applies.
Comment #7
attiks CreditAttribution: attiks commentedComment #8
yched CreditAttribution: yched commentedSeems to apply OK after all :-)
Comment #9
yched CreditAttribution: yched commentedSide note: #2424697: ResponsiveImageFormatter throws an exception on node preview
This predates #2260061: Responsive image module does not support sizes/picture polyfill 2.2, but the right people are likely subscribed here, so, shameless plug :-)
Comment #10
Wim LeersAssigning to @attiks (I can't assign to @Jelle_S — do you want to officially become a maintainer of the
responsive_image
module, Jelle_S? :)) to gather a reply to @yched's questions in #1.Comment #11
Jelle_S@Wim I'd be honoured!
You're absolutely right! It's a leftover from old code. When I first wrote
theme_picture()
(back when it was stillpicture.module
) I started off withtheme_image()
as the base code. That in combination with some old outdated specs of the<picture>
and<source>
tags resulted in the code using the passed dimensions. It should be removed now. I missed it in the big "Responsive Image Cleanup Patch" (#2260061: Responsive image module does not support sizes/picture polyfill 2.2), sorry about that...So I guess that makes this NW.
Comment #12
yched CreditAttribution: yched commented@Jelle_S thanks for the pointer.
Something like this then ?
[edit; interdiff is in #14]
Comment #13
yched CreditAttribution: yched commentedAlthough, looking at how things work for "flat" image styles, it looks like theme 'image_style' *requires* passing the image dimensions.
template_preprocess_image_style() just takes those and directly passes them to $style->transformDimensions() without trying to figure them out from the original image.
Maybe we should just do the same for consistency ?
Comment #14
yched CreditAttribution: yched commentedOops, forgot the interdiff for #12
Comment #15
attiks CreditAttribution: attiks commentedI think all of this should go, width and height should be removed from variables as well.
We need the exact dimensions of the original image to calculate the sizes of the derivatives.
Comment #16
yched CreditAttribution: yched commented@attiks : Actually, theme 'image_style' / template_preprocess_image_style() work the way they do (require the caller to pass the source image dimensions, don't bother trying to read them from the file) because the dimensions are stored in ImageItem field values (see ImageItem::preSave()), and are thus already available.
Displaying a derivative image in an Image field formatter is the 95% use case for image styles output, other use cases need to fetch the image dimensions themselves before calling theme 'image_style'.
So if we did #15 for responsive image styles, that would be a perf regression, because template_preprocess_responsive_image() would perform i/o operations to read the image dimensions from the file while we already have them available in the ImageItem.
That would also be the opposite of how theme 'image_style' works. Keeping image_style and responsive_image_style consistent is IMO a cognitive and maintenance win.
Attached patch:
- Requires image dimensions to be passed, like theme 'image_style' does,
- Then, no need to go through the Image object to grab the extension, we can call pathinfo() on $variables['uri']. This way, no need to go through the 'image.factory' service to create an Image object, the information passed by the caller are enough.
- Additional doc fix : AFAICT the 'image_style' param for theme_responsive_image_formatter() is not optional, template_preprocess_responsive_image() assumes there is one.
Comment #17
yched CreditAttribution: yched commentedSide note: looking at the code at this point, it might make sense to turn responsive_image_build_source_attributes() back into "handle all mappings" - thus reverting one of the last refactors I suggested in #2260061: Responsive image module does not support sizes/picture polyfill 2.2 ;-). The logic around "dimensions" was a bit more confusing back then...
Comment #18
yched CreditAttribution: yched commentedAlso : opened #2426757: responsive_image_build_source_attributes() calls mime type guesser over and over
Comment #20
yched CreditAttribution: yched commentedDoh.
- arguments order mismatch
- there was still code that used the $image object to get the uri.
The # of parameters for responsive_image_build_source_attributes() make more arguments for #17. Let's get back to green first.
Comment #23
RainbowArrayWe need a reroll on this. It looks like this was mostly ready and just needed some reviews? Would be good to get this cleaned up.
Comment #24
JeroenTCreated reroll.
Comment #25
JeroenTComment #26
star-szrComment #27
RainbowArrayNow that #2123251: Improve DX of responsive images; convert theme functions to new #type element has been committed, this will need a reroll. Some of this may no longer be necessary since the DX was changed around a fair amount in that patch.
Comment #28
Jelle_SRerolled the patch.
Comment #30
Jelle_SAs said in #16: Passing the width and height is now required for theming responsive images.
Comment #31
Jelle_SComment #32
yched CreditAttribution: yched commentedComment #33
yched CreditAttribution: yched commentedComment #34
yched CreditAttribution: yched commentedUpdated the IS, added a beta evaluation.
Also, additional cleanup of a couple stale "use" statements, no need for ImageInterface anymore :-)
Comment #35
attiks CreditAttribution: attiks commented#34 Thanks, looks good to me and is indeed a performance improvement.
Comment #36
alexpottChanging to the short array syntax is out of scope and makes the patch harder to review.
Why change the $image to $uri - seems unnecessary.
Out of scope
I'm not sure I see the point of this issue - since nothing that uses the responsive_image template is changing I assume that everything already provides dimensions - and therefore will this actually have any performance impact. There does not seem to be any proof of this impact on the issue.
Comment #37
yched CreditAttribution: yched commented1. reverted the array() / [] changes (but kept the re-alignment of the two calls to addImageStyleMapping() in the code sample)
2. $image doesn't exist anymore, the point of this patch is that there is no need to create an ImageInterface object :-)
3. sure - but unlike the array() / [] changes mentioned in 1., it hardly complicates patch review ? Temptatively leaving that in.
Yes, only the ResponsiveImageFormatter currently calls 'responsive_image' in core, and it does already pass the dimensions, and thus does not need any change.
But even in that case, template_preprocess_responsive_image-) currently needlessly creates an Image object,
and responsive_image_build_source_attributes() repeatedly calls getDimensions() on it[edit: sorry, that was a little hasty. Current code doesn't read $image dimensions if they are already passed in. But the $image is not needed to begin with]Comment #40
Jelle_SReroll.
Comment #43
Jelle_SMinor fix (forgot to pass the
$uri
argument toresponsive_image_get_image_dimensions
). Let's see what the bot thinks (assuming the bot is fixed by now...)Comment #44
RainbowArrayI think you mixed in some work from another issue. There are changes to the template here that I don't think belong.
Comment #45
Jelle_SOops! You're right, my bad. That patch is for an entirely different issue. Good to know it's green though ;-) . New patch without the code from the other issue.
Comment #46
RainbowArrayMight be worth looking to see if any of these improvements could go in under the hood in 8.1.
Comment #48
Wim LeersWould be great if we could get this going again. No longer applies to 8.1.x
Comment #49
vprocessor CreditAttribution: vprocessor at Skilld commentedComment #50
vprocessor CreditAttribution: vprocessor at Skilld commentedHi guys,
reroll is ready
Comment #51
vprocessor CreditAttribution: vprocessor at Skilld commentedComment #52
Wim LeersThanks! :)
Comment #54
vprocessor CreditAttribution: vprocessor at Skilld commentedChecking for errors
Comment #55
vprocessor CreditAttribution: vprocessor at Skilld commented>>fail: [PHP Fatal error] Line 402 of core/modules/responsive_image/responsive_image.module:
>> Class 'Attribute' not found
fixed
interdiff and patch added
Comment #56
vprocessor CreditAttribution: vprocessor at Skilld commentedComment #57
andypostCode looks great, +1 rtbc here
But there's API change and #36 points about scope...
this requires change record with example code for contrib maintainers
Comment #59
catchSo on the one hand responsive_image_build_source_attributes() looks like just a helper for the preprocess that should have an an underscore on it.
On the other hand it's got very extensive documentation that makes it look like an API function, and it doesn't have an underscore.
So probably we should add a new method, and if possible have responsive_image_build_source_attributes() call that method? Shame to duplicate the code unless we really have to, since this probably should never have been an API function in the first place.
Comment #60
xjm#59 sounds good to me. I'd also explicitly deprecate
responsive_image_build_source_attributes()
with that approach.Comment #61
vprocessor CreditAttribution: vprocessor at Skilld commentedComment #71
quietone CreditAttribution: quietone as a volunteer commentedUnassigning because it has been 5 years since vprocessor was able to work on this issue.
Comment #75
catchThis already had release manager review - we should do this in bc-friendly way.
Comment #76
andypostComment #78
sahil.goyal CreditAttribution: sahil.goyal as a volunteer and at Srijan | A Material+ Company for Drupal India Association commentedRerolled the patch for current version and attaching the reroll diff.
Comment #79
ameymudras CreditAttribution: ameymudras at Salsa Digital commentedFixed issues with the above patch
Comment #81
Medha KumariReroll the patch #79 with Drupal 10.1.x.
Comment #82
JeroenTComment #83
mrinalini9 CreditAttribution: mrinalini9 at Srijan | A Material+ Company for Drupal India Association commentedRerolled patch #81, please review it.
Comment #84
mrinalini9 CreditAttribution: mrinalini9 at Srijan | A Material+ Company for Drupal India Association commentedComment #85
Nitin shrivastava CreditAttribution: Nitin shrivastava at OpenSense Labs commentedFix Custom command failure for #83