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

Lazy-load not working in Safari #7

Closed bramvanderholst closed 7 years ago

bramvanderholst commented 7 years ago

Hi,

Found an issue with lazy-load in Safari. When implementing plastic-image inside another element (in the shadow dom) the IntersectionObserver never gets triggered. Seems to be working fine in all browsers except Safari.

Issue can be reproduced by added plastic-image in a simple wrapper element:

<link rel="import" href="../../bower_components/plastic-image/plastic-image.html"/>

<dom-module id="img-wrapper">
  <template>
    <style>
      :host {
        height: 300px;
        display: block;
      }
      plastic-image {
        height: 100%;
        display: block;
      }
    </style>
    <plastic-image use-element-dim
                   lazy-load
                   static
                   preload
                   fade
                   sizing="cover"
                   placeholder="[[placeholder]]"
                   srcset$="[[srcset]]"></plastic-image>
  </template>

  <script>
    Polymer({
      is: 'img-wrapper',

      properties: {
        placeholder: String,
        srcset: String,
      }
    });
  </script>
</dom-module>

Placeholder image loads just fine. _lazyLoadCallback never gets triggered.

mlisook commented 7 years ago

I've confirmed this issue with Safari. Continuing to investigate.

mlisook commented 7 years ago

This function in the polyfill is returning false in Safari for all elements in shadow DOM:

IntersectionObserver.prototype._rootContainsTarget = function(target) {
  return (this.root || docElement).contains(target);
};

So the element is not considered part of the document tree.

As used in plastic-image the term this.root would always be false.

Continuing to investigate.

mlisook commented 7 years ago

The IntersectionObserver polyfill was just patched 6 days ago to address Polyfill fails in Safari 10.1 #206 - see pull request Add support for targets in shadow DOM #218.

It appears that pollyfill.io is not using the latest version.

mlisook commented 7 years ago

Confirmed workaround:

Include the latest intersection-observer.js from WICG/IntersectionObserver/polyfill in the header of the base document allows the lazy load function to work in Safari.

The thought in using polyfill.io was that the latest versions of pollyfill would always be used and the element would not have to be updated every time this polyfill was changed. It is possible this needs to be revisited.

mlisook commented 7 years ago

Now that I understand that polyfill.io does not dynamically update the registered polyfills it is serving, but rather it requires a new release of polyfill-server, which is not on a regular cadence, it does not make sense for the consumer of this element to have to separately load the polyfill code.

So until an update to polyfill.io which includes intersection-observer ^0.3.0, the element will serve a local copy of the 0.3.0 version instead of using polyfill.io. I expect to reverse that change after polyfill.io is updated.

This modification was merged in Serve polyfill from element source #9. New element version is 1.0.2..