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

Render Blocking Script #42

Open
R2wix9mtdI opened this issue Jun 24, 2021 · 4 comments
Open

Render Blocking Script #42

R2wix9mtdI opened this issue Jun 24, 2021 · 4 comments

Comments

@R2wix9mtdI
Copy link

Great Pollyfill to support WebP. The only thing I notice now that Web Core Vitals is upon us is that there is no defer or async parameter in the HTML installation. Can you forsee any issues adding this parameter? and if so which one is supported?

Thanks

Kevin

@chase-moskal
Copy link
Owner

@R2wix9mtdI

👋 hello!

yes, webp-hero has some major deficiencies that could be fixed:

  1. webp-hero doesn't have any conditional loading of its 1MB bundle, so it's even loaded in browsers that actually support webp
    • 👍 a fix for this would be straightforward to implement
  2. webp-hero's actual decoding process for the webp images happens on the main thread, and can take a lot of time, locking up the main thread, which unpleasantly freezes the ui
    • it's conceivable we could move the webp decoding into a web worker thread, such that the decoding happens seamlessly without disturbing the user experience
    • it's also conceivable we could replace all images with a placeholder (maybe even a loading spinner) until the webp decoding is completed
    • 😕 a fix for this might not be straightforward: my recall here is foggy, but i think the issue was that a canvas element is required for the decoder to operate, and that canvas elements are not available within web workers
    • (after some quick research) it looks like ie11 doesn't support the OffscreenCanvas solution, and webp-hero largely exists for ie11 support
    • (conjecture) i imagine the possibility to spoofy/spy on the canvas calls that the decoder makes, record them all, and then replay them in the main thread — i think that could possibly solve the problem, but it would be slightly elaborate
  3. out of the box, webp-hero only supports simple <img> elements
    • (not css background-image or <picture> elements)
    • it doesn't support new images added to the dom dynamically
    • 👍 a fix for this would be straightforward

@chase-moskal
Copy link
Owner

i personally don't have time to address these issues any time soon, but i'm open to provide some guidance to anybody looking to contribute (we could chat on discord), and i'm happy to merge quality pull requests

@henriquemilli
Copy link

henriquemilli commented Aug 6, 2021

Hello @chase-moskal,

I have written a super dump script to address the conditional loading and the srcset issue.

Compared to your fine work, my code is trash, but it does the job well enough in my use case.

I will just paste it here for now, if you have any suggestions for me to turn it into a quality pull request, I will be happy to work further on it.

const testImg = 'data:image/webp;base64,UklGRjIAAABXRUJQVlA4ICYAAACyAgCdASoCAAEALmk0mk0iIiIiIgBoSygABc6zbAAA/v56QAAAAA==';
const webBundleUrl = 'https://unpkg.com/[email protected]/dist-cjs/polyfills.js';
const webPolyfillUrl = 'https://unpkg.com/[email protected]/dist-cjs/webp-hero.bundle.js';

(function () {
    var img = new Image();

    img.onload = () => {
        support = !!(img.width == 2 && img.height == 1)
        if (!support) {
            injectWebpSupport();

        } else {
        };
    };

    img.onerror = () => {
        injectWebpSupport();
    };

    img.src = testImg;
})();

function injectWebpSupport() {
    var bundle = document.createElement('script');
    var polyfill = document.createElement('script');

    bundle.onload = function () {
        document.head.appendChild(polyfill);
    };
    polyfill.onload = function () {
        var webpMachine = new webpHero.WebpMachine();
        webpMachine.polyfillDocument();
        rmSrcset();
    };

    bundle.src = webBundleUrl;
    polyfill.src = webPolyfillUrl;
    document.head.appendChild(bundle);
};

function rmSrcset() {
    img = document.getElementsByTagName('img');
    for (let i = 0; i < img.length; i++) {
        img[i].removeAttribute('srcset');
    };
};

Perhaps @R2wix9mtdI can adapt this to solve his issue

@chase-moskal
Copy link
Owner

@henriquemilli -- this is a good technique to conditionally load the webp hero bundle

as for integrating it with webp-hero in a pull request, i think we'd ideally like to create something like source/conditionally.ts which would contain a technique like yours

i'm not sure how to find the script src url of the bundle locally from conditionally.ts.. i can imagine how to do that in es modules, which have access to import.meta.url, but i'm not so sure for a standard js script... it might be tricky.. an alternative would be to include a shortened version of the conditional loading as the recommended strategy in the readme's installation guide

as for the srcset, i think ideally we don't just want to remove srcset, but instead be prepared to decode any active webp image within the srcset

anyways, thanks for your code, it would be great if we could incorporate that kind of technique into webp-hero by default

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

No branches or pull requests

3 participants