GoogleChrome / GoogleChrome/lighthouse

Audit: Costly image decodes

Open
#2,515 2 comments 1 reaction 0 assignees View on GitHub
feature new_audit P2
Dominant language
JavaScript
Stars
30.8k
Forks
9.8k
Avg merge
1d 20h
Merged PRs (30d)
19

Description

https://stats.yarnpkg.com/ loads quick but has surprisingly high "Composite Layers" cost. But as it turns out, it's just stalled in Composite Layers as it waits for an "Image Decode" in the raster threads to finish:
![image](https://user-images.githubusercontent.com/39191/27235581-1e33aff2-5276-11e7-96c6-b28084ba2191.png)

The root issue here is that the image is shipped as 5000px wide, but only shown as 400px wide. Whoops. :) We already flag oversize images and calculate the download overhead cost:
![image](https://user-images.githubusercontent.com/39191/27236252-18af4674-5279-11e7-90d8-e4eaa3bd0afe.png)

However, we are ignoring the runtime costs (decode and resize). And in this case, we can see it's significant.

### Implementation

Processing the raw trace for this is surprisingly hard as the image URL isn't in the `DecodeImage` trace event, but linked via two other references (`LazyPixelRef` lol). Caseq points out this particular area is one of the most complicated to put together... So given that, it makes more sense to let `devtools-timeline-model` do our heavy lifting..

The basic flow:

```js
for (const thread of someTimelineModel._virtualThreads) {
for (const event of thread.events) {
if (event.name === 'Decode Image') {
data = TimelineModel.TimelineData.forEvent(event);
if (event.duration > 10)
console.log({url: data.url, duration: event.duration, event, data});

}
}
}
```

TBD on how we surface this cost to the user, since we'd now have calculated both network and runtime cost of this issue.

Contributor guide

Open the contributing guide

Assessment

This issue has not been assessed yet.

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.