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

WIP: Element screenshots #8797

Closed

Conversation

mattzeunert
Copy link
Contributor

@mattzeunert mattzeunert commented May 2, 2019

Summary

Very WIP 🏗

  • take full-page screenshot (created a separate PR for this)
  • capture element bounding boxes
  • render element screenshot in report

Todo:

  • figure out final UX
  • we should scroll down the page once before capturing element positions or the screenshot
  • sort out how chrome devtools instantiates detailsrenderer
  • don't use clippath (see Patrick's note on browser support, also there's no reason we need it)
  • do we need to check if the element is not visible and then not capture the bounding box so that we don't show a screenshot that doesn't show the element (e.g. because it's overflowing a scroll container or there's an overlay on top of it)
  • handle elements that are outside the captured screenshot area (e.g. for pages > 16000px)

Known issues:

  • if resizing the window changes the layout then the element marker positions will be off (e.g. this happens for position fixed elements, or if the page uses vh)
  • elements in overflow: scroll containers may be hidden
  • elements can be obscured by full-screen overlays

Related Issues/PRs

fixes #6683
fixes #7327

snippetEl.innerText = item.snippet;
element.appendChild(snippetEl);

const fullpageScreenshotUrl = __LIGHTHOUSE_JSON__.audits['full-page-screenshot'].details.data;
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What's a good way to access this in the renderer?

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I would say it should probably be passed into a DetailsRenderer as the context of the report, almost like setTemplateContext

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Passing it into the DetailsRenderer constructor now.

Copy link
Collaborator

@patrickhulce patrickhulce left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nice @mattzeunert do you think you could update the artifacts so we can play around with it in the now.sh deployment report on the PR? (right now report renderer just throws and page is empty)

lighthouse-core/audits/accessibility/axe-audit.js Outdated Show resolved Hide resolved
height = Math.min(maxScreenshotHeight, height);

await driver.sendCommand('Emulation.setDeviceMetricsOverride', {
// todo: figure out what this means and set appropriately
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

😆 I wonder how many devtools protocol settings we should add this comment to 🤔

snippetEl.innerText = item.snippet;
element.appendChild(snippetEl);

const fullpageScreenshotUrl = __LIGHTHOUSE_JSON__.audits['full-page-screenshot'].details.data;
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I would say it should probably be passed into a DetailsRenderer as the context of the report, almost like setTemplateContext

types/artifacts.d.ts Outdated Show resolved Hide resolved
.lh-element-screenshot__content {
position: absolute;
right: 0px;
top: -190px;
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

this is based on the dynamic height we set it js? anyway to fix it or not have the hanging magic value? :)

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It's so that the screenshot doesn't cover the table item you're hovering over and instead appears above it. Not really based on anything though.

Do you think showing the screenshot above the table item on hover is the way to go? And then on mobile we could expand the table item to include the screenshot when the user taps on it.

if (item.boundingRect) {
/** @type {Element} */
let elementScreenshot;
element.addEventListener('mouseenter', () => {
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

not sure what our stance is on JS in report now

@paulirish 🤓 🔫 , CSS-only impl? ;)

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I can't find the comment, but I think we decided that's ok on the snippet renderer PR.

Not sure how feasible this would be to do without JS, browsers might not like having a hundred 500kb base64 images on one page.

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Oh that sounds right. I was remembering some I/O convo about going back and forth to make things easier on PSI, but we did already break that barrier.

const clipId = 'clip-' + Math.floor(Math.random() * 100000000);
mask.style.width = previewWidth + 'px';
mask.style.height = previewHeight + 'px';
mask.style.clipPath = 'url(#' + clipId + ')';
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

clever! I think the chart is scarier than reality given this narrow usecase but still might be troublesome for us? https://caniuse.com/#search=clipPath

would you mind explaining in words what the approach is here? I think I'm getting it but not sure why the mask is necessary

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

There isn't anything that can't be done with divs positioned over the image, will change it.

@mattzeunert
Copy link
Contributor Author

do you think you could update the artifacts so we can play around with it in the now.sh deployment report on the PR

Done now 👍

@patrickhulce
Copy link
Collaborator

patrickhulce commented May 15, 2019

Nice thanks for deploying it! The experience is A-MAZ-ING 😍

I think the only major question I have is around the usefulness of it being full-size. I think context is frequently enough here and probably what we actually want in many cases. Perhaps that makes the size issue a little more swallowable too and/or the compression issues less noticeable?

Few findings:

  • Small screen sizes it gets a little weird that it goes full screen and completely covers the node, maybe we scale it down a bit so we can shift it to the side?
    image

  • This is the sort of thing I was worried about with textContent, maybe we actually want innerText or perhaps the 80 character limit is enough?
    image

  • Sometimes the full-size preview isn't really what we want I think, we might actually prefer context for where it is on the page? Example where we have a ton of duplicate lighthouse images on the page so I still don't know which one this is talking about.
    image

  • It wasn't able to get the screenshot for these two links here, not sure whats going on with that
    image

  • Another small screen size failure case where the important part of the screenshot is outside the window.

image

@mattzeunert
Copy link
Contributor Author

This is the sort of thing I was worried about with textContent, maybe we actually want innerText or perhaps the 80 character limit is enough?

Addressed in this PR.

It wasn't able to get the screenshot for these two links here, not sure whats going on with that

They have a visible size of 0x0px – do you think we should leave some kind of indication if there's no screenshot?

Sometimes the full-size preview isn't really what we want I think, we might actually prefer context for where it is on the page? Example where we have a ton of duplicate lighthouse images on the page so I still don't know which one this is talking about.

Maybe if the element is taller than 60px we try to show where on the page it is and zoom out by 2x or 4x, and for smaller ones we do something similar to what we have now?

Small screen sizes it gets a little weird that it goes full screen and completely covers the node, maybe we scale it down a bit so we can shift it to the side?

I changed the CSS so that the hover always appears above the table item. Let's see how the zoomed out stuff from above works and see if it can help with this too.

What do you mean by "shift it to the side"?

Another small screen size failure case where the important part of the screenshot is outside the window.

Will do this:

  • if there's a hover contain it within the window
  • if the page is narrower than say 800px users have to tap the line with the element

@connorjclark
Copy link
Collaborator

hey @mattzeunert we're wanting to land this (mostly for #10517) and willing to invest eng time to get it the rest of the way. mind if we take it from here, or would you be able to pick this back up?

I'll go through the PR tomorrow and leave my thoughts.

@mattzeunert
Copy link
Contributor Author

Hey @connorjclark! Having someone on the team pick it up sounds good 👍

@connorjclark
Copy link
Collaborator

I forked and started work here: https://github.com/GoogleChrome/lighthouse/compare/elscreens

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Visual audit reporting Improve how HTML elements are displayed in the results table
6 participants