mlisook / plastic-image

A Polymer 3.0 element which adds extra plasticity to <iron-image> with support for srcset and lazy loading
MIT License
30 stars 6 forks source link

Major performance issues on Firefox #19

Closed paales closed 7 years ago

paales commented 7 years ago

There seems to be an issue with the IntersectionObserver which is using getClientBoundingBox which forces a repaint and thus causing mayor jank on the page.. The odd thing is that safari runs absolutely fine, but doesn't have support for IntersectionObserver as well..

Maybe it is in our environment specifically, but I'll update this issue when we have properly profiled the page.

mlisook commented 7 years ago

Thank you, I'd definitely appreciate any additional information.

My top todo on the element right now could be related - stop observing intersections after triggering loading.

paales commented 7 years ago

The first step probably is that I'll create a demo page with 100 images on them and try to debug the performance there.

mlisook commented 7 years ago

Potentially related issue WICG/IntersectionObserver - Polyfill: callback is called synchronously #225

josephliccini commented 7 years ago

I am getting an issue where both in IE and FireFox, when the polyfill is added, it quickly freezes up the page and the browser goes into "not responding". Is this the same behavior you are seeing?

EDIT: sorry I will move this into the polyfill issue, this is not related to plastic-image, but to the intersection-observer polyfill

mlisook commented 7 years ago

@josephliccini - plastic-image does load the polyfill dynamically - only if the browser doesn't support it (or the polyfill was not previously loaded) and if lazy-load is specified. This is done by adding a script tag to the header.

I think it's possible that could cause the issue you're describing, but I'm not seeing it myself and my internet connection is always over celular (I travel full time).

On the plus side, both Firefox and Edge will have native support for IntersectionObserver in the next release, both do very soon.

mlisook commented 7 years ago

BTW, I have a page on a demo site with 202 plastic-images on a page (it's a PWA I'm dabbling in an hour here and there that will potentially replace my personal travel blog, roamwardbound.com). The site is served by Wordpress and the PWA uses the Wordpress REST API for all it's data.

You can try the page in Firefox at https://demo.lisook.com/a-bunch-of-plastic-image/ I don't notice an issue in FF.

paales commented 7 years ago

@mlisook I don't see the huge hangs on firefox anymore, but I am still seeing a fair amount of jank and the scroll performance dropping well below 60fps.

Prerequisites

screen shot 2017-08-05 at 13 51 53

You can load in the profile in the Chrome Performance inspector tab yourself: Profile.json.zip

I think the element is forcing a layout+paint. You don't notice it when a single element is running, but when multiple elements are on the same row it forces a layout multiple times before it can do another paint.

The steps it does are:

  1. Intersection observer (async)
  2. Webp promise (microtask)
  3. Measure to find img (layout update)
  4. Update src

What we're missing here is the beforeNextRender (or requestAnimationFrame) around the measurement and we're missing a will-change property as well.

mlisook commented 7 years ago

@paales re the 300ms anti-pattern hack: This was definitely a hack, left over from before I published this element. It allowed a demo I did for a prospect that had a page with 40 tiles and 1 or 2 images in each to score 90 in Lighthouse by being detected as interactive sooner rather than being swamped with 52 new observer entries right when the polyfill finished loading. It should have been removed long ago.

paales commented 7 years ago

We have tested the element with all the latest fixes applied and works good enough on Firefox 54.

With the recent release of Firefox 55 the IntersectionObserver is supported and all problems go away. http://caniuse.com/#search=IntersectionObserver