Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Lazy loaded images and iframes should be forced to eager when printing #6581

Closed
grakz opened this issue Apr 13, 2021 · 17 comments
Closed

Lazy loaded images and iframes should be forced to eager when printing #6581

grakz opened this issue Apr 13, 2021 · 17 comments

Comments

@grakz
Copy link

grakz commented Apr 13, 2021

Issue summary

When printing a page that contains lazy loaded images or iframes that have not been shown on screen yet these are not loaded but shown as empty elements.

Currently the lazy loading attributes spec and the actual user agent implementations do not consider printing, however for many website owners who's users depend on printing (either on paper or to PDF), this issue is a hurdle that prevents them from moving to native lazy loading.

Expected behavior

Since lazy loading should be transparent to the user, the user agent should load all images and iframes immediately prior to showing a print preview.

Possible solutions

There are two potential solutions, the first seems most natural to me, though the second will also benefit other uses of the Intersection Observer.

  1. The user agent should treat each img and iframe element as having the lazy loading attribute set to eager when the media type is equal to print.
  2. For each target, of each observing IntersectionObserver, set isIntersecting to true when the media type is equal to print.

Potential issues

  1. Confusing to user why print preview/dialog is not being shown to users on slow connections or on pages with a large number of lazy loaded elements.

Implementation bugs

Related Links

@annevk
Copy link
Member

annevk commented Apr 14, 2021

@domfarolino @emilio it seems like this is a blocker for Wikipedia and perhaps also others.

@grakz
Copy link
Author

grakz commented Apr 14, 2021

I added a test page, that should show the numbers 1 through 6 when printing.

Printing this page fails in Chrome and Safari and succeeds in Firefox and Safari.

EDIT: It turns out I forgot to enable lazy loading in Safari, with lazy loading enabled Safari also fails.

Firefox 74, Windows 10

image

Chrome 92, Windows 10 / Chrome 89 Android 10

image
image

Safari, macOS 11.2.3 / iOS 14.4.2

image
image

@emilio
Copy link
Contributor

emilio commented Apr 14, 2021

I fixed this ages ago in https://bugzilla.mozilla.org/show_bug.cgi?id=1648064.

@emilio
Copy link
Contributor

emilio commented Apr 14, 2021

It's not clear to me that the spec needs special-casing this? You could argue that the print document always gets displayed "fully" and thus all images should be loaded.

@annevk
Copy link
Member

annevk commented Apr 14, 2021

Yeah, I think in terms of normative requirements we are okay, but it might be worth calling out in a note as a thing to pay attention to. (Also great that we already do this and it seems to be mostly a Chrome bug.)

@grakz
Copy link
Author

grakz commented Apr 14, 2021

I am an idiot. I forgot to turn on lazy loading in Safari (it's not enabled by default yet). When you enable it, Safari also fails to
print the page correctly.

It seems only Firefox is handling this case correctly. Though I noticed that on a slow connection the Firefox print dialog continues to update in the background without notifying the user that the content is still being loaded (Firefox 89.0a1).

@Krinkle
Copy link
Member

Krinkle commented Apr 14, 2021

This may be obvious, but I wonder how browsers should (or do) behave when a user initiates the print workflow before the load event was reached (or some other significant event, like document readyState complete). That is perhaps less common, but it might be useful to think about. This feels like logically the same kind of scenario from the user's perspective, where (below-the-fold) HTML chunks and style/image subresources can also still be pending, and this situation can arise even without lazy-loading.

If vendors agree that users expect printing to render the full document (vs only the HTML and images so far in their viewport or buffer), then that would (or perhaps already does) get subjected to the same treatment. Whether we go for real-time updates, or telling the user we're waiting, or asking them after a certain threshold, etc. The "wait" would track the load event, plus another such wait-for sequeunce for any new subresources initiated around the time we switched to eager loading.

(Feel free to ignore if this is obvious or not helpful. I didn't see this mentioned and figured it might help to look at it from this prespective as well.)

@grakz
Copy link
Author

grakz commented Apr 15, 2021

@Krinkle I agree with your thinking. For the user it should be the same. Currently Chrome, Firefox and Safari all show different behaviors when users try to print a document before it finishes loading:

  • Chrome, printing before page load finishes: freezes loading and shows incomplete page. Printing Lazy loaded images: behaves the same.
  • Firefox, printing before page load finishes: print preview continues to be updated without notice. Printing lazy loaded images: behaves the same.
  • Safari, printing before page load finishes: asks user if they want to wait for load to finish or print now, if you select print now, the preview is no longer updated. Printing lazy loaded images: behaves different, it does not ask user if they want to wait, and just does not load the images.

So there is no agreement on between the vendors, but how should browsers behave when a user initiates the print workflow before the load event was reached?

@emilio
Copy link
Contributor

emilio commented Apr 15, 2021

In Firefox this depends on whether it's window.print() or user print what gets called. For window.print(), we do wait until the load event and other browsers do the same, but otherwise we do print a potentially incomplete page.

@grakz
Copy link
Author

grakz commented Apr 15, 2021

@emilio I loaded an html page with a single 30mb image in Firefox 89 in an artificially squeezed internet connection (setting my ethernet to 10mbit half-duplex). I selected print in the print menu. The print preview opens and it then silently updates after the image finishes loading. See the attached video for what happens.

Firefox.Nightly.2021-04-15.11-42-35.mp4

@emilio
Copy link
Contributor

emilio commented Apr 18, 2021 via email

@zcorpan
Copy link
Member

zcorpan commented Jan 20, 2022

https://bugs.chromium.org/p/chromium/issues/detail?id=875403 is now fixed by @chrishtr, with the following caveats:

This works for user-initiated print, but not scripted print.

I'm currently thinking it isn't worth it to implement for iframes, because they are much more complicated and/or slow to load than images, and I'm not so sure there is enough value. Please comment if you think there is, and if so why.

@domfarolino
Copy link
Member

I meant that if you Ctrl+P before the load event fires we'll just take the dom as it is

This seems to be at odds with:

However even with the print menu / Ctrl+P, we do wait for resources to load

I just want to be clear in my understanding that Firefox does allow you to print a document with incomplete resources. That is, the print dialog won't explicitly "wait" for pending resources to load before allowing a print (via CTRL+P). Though if the resources do happen to load while the print preview is displayed, it gets updated to show this. But if I'm misunderstanding please correct me.


Regarding:

Yeah, I think in terms of normative requirements we are okay, but it might be worth calling out in a note as a thing to pay attention to. (Also great that we already do this and it seems to be mostly a Chrome bug.)

Do we think there is any remaining action to be taken here in the spec? It looks like Chrome now, for user-initiated prints, makes all lazyload resources load immediately and block the load event. We set a 2 second timer to wait for these resources, and which ever comes first (load event, or 2 seconds is up) we then show the print dialog. Perhaps we require such logic in the spec?

@chrishtr
Copy link
Contributor

Update: Chromium now forces eager when printing via user-initiated and script print, as well as with iframes.

@emilio
Copy link
Contributor

emilio commented May 23, 2022

I meant that if you Ctrl+P before the load event fires we'll just take the dom as it is

This seems to be at odds with:

However even with the print menu / Ctrl+P, we do wait for resources to load

I just want to be clear in my understanding that Firefox does allow you to print a document with incomplete resources. That is, the print dialog won't explicitly "wait" for pending resources to load before allowing a print (via CTRL+P). Though if the resources do happen to load while the print preview is displayed, it gets updated to show this. But if I'm misunderstanding please correct me.

This is not right. Sorry, I should've realized that my previous comment wasn't super-clear if you don't know about how Firefox does printing.

Let me try to clarify and let me know if there's something still unclear.

In order to print in Firefox, there are actually two documents involved, not one:

  • The original document (the document displayed in the content area).
  • A clone of the original document (which is the thing that will actually be printed).

This is for a variety of reasons (main one being that you can keep displaying the website while you're printing, though there are other historical ones).

The details are a bit fuzzy in my mind (I could page this back completely if required), but there are some things that are cloned as-is from the original document into the clone document (like style sheets), and others (mostly the ones that can be triggered via media queries or so, like images) where the clone document does trigger its own resource load.

The two sentences you quoted are about different documents:

  • We don't wait for the load of the main document for the user to be able to Ctrl+P, though we delay until the load event for window.print(). Last I looked at this, this last bit was interoperable across browsers.

  • However we do wait for the load event of the clone document to print, and we rebuild the preview when that happens. This is usually pretty fast (if all the CSS and images come from the cache), but could be slow if you load a lot of background-images from e.g. and @media print { } block, or <source media>, or such.

Does that explain the Firefox setup a bit better?

@tgrushka
Copy link

This lazy-loading decision also negatively impacts accessibility and accessibility testing. Who makes these decisions, and why are they made without consultation with accessibility SMEs?

@annevk
Copy link
Member

annevk commented Nov 8, 2024

I'm not sure what decision you are referring to. This issue documents issues with implementations, but the specification is correct.

As such, closing this.

@annevk annevk closed this as not planned Won't fix, can't repro, duplicate, stale Nov 8, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Development

No branches or pull requests

8 participants