GithubHelp home page GithubHelp logo

malchata / yall.js Goto Github PK

View Code? Open in Web Editor NEW
1.4K 28.0 141.0 2.18 MB

A fast, flexible, and small SEO-friendly lazy loader.

License: MIT License

JavaScript 57.67% HTML 42.33%
lazy-loading webperf lazyload-script lazyloading lazyload lazy-load performance image autoplay background

yall.js's People

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

yall.js's Issues

How do you plan to handle dynamically loaded HTML

Under the Limitations section I noticed you mentioned that this library does not work for dynamically injected markup, however the library should support this at some point in the future; I was wondering if you had a plan for implementing this. It seems like using MutationObserver is a good idea, as it is widely supported (including back to IE11), and should be able to efficiently listen to DOM mutations. I'm guessing we could observe on document.body or something and listen for childList mutations, determine if a child has the .lazy class, and therefore should also be observed?

Maybe we could make mediaObserver a variable global to this module, so we could .observe future elements that our MO detects. Thoughts?

Implement IntersectionObserver

This article by Dan Callahan alerted me to the existence of IntersectionObserver, a browser feature that may give us a better alternative to doing checks with getBoundingClientRect.

Add methods to attach/detach lazy loading

Would appreciate methods that would allow to temporarily suspend lazy loading. In my case this is important when smooth scroll animation is running. This makes scroll animation jerky and lazy-loads images, which are not neccessary.

Background images inside style attributes

Hi there,

This is a bit like #19 but not exactly.

I'm trying to automate some code to lazy load images on wordpress sites, however, a wordpress plugin doesn't always have easy control over the css code on the site or it's structure. But, we can parse the html and rewrite portions of the html code relatively easily.

Is there any way we can lazy load the image below?
<div class="tve_post_grid_image_wrapper" style="background-image: url(https://example.com/wp-content/uploads/2017/10/Coffee-Subscription-Boxes.jpg ); height: 195px">

I was thinking that rewriting the html to something like this, and then let yall.js deal with it, makes sense:
<div class="tve_post_grid_image_wrapper lazy-bg" style="background-image: url('data:image/gif;base64,R0lGODlhAQABAIAAAAAAAP///yH5BAEAAAAALAAAAAABAAEAAAIBRAA7') data-background-image: url(https://example.com/wp-content/uploads/2017/10/some-image.jpg ); height: 195px">

Is this something you could add in the future, or do you suggest some other method that doesn't involve creating extra css classes for the background images, or replacing the style attribute?

Images NOT showing if you use browser Back button to go back to the previous page with yall lazy loaded images

Images NOT showing if you use browser Back button to go back to the previous page with yall lazy loaded images. That previous page loaded fine initially, but then you click on a link and navigate to second page ... then you hit browser back button (chrome and edge) the images that you saw on the first page are not visible anymore and instead, in developer tools you see the 1px-1px placeholder.jpg image in place of the real image.
Maybe we are doing something wrong. Could you please advise? Thanks a lot.

TS

images class attribute is lost

Once yall has executed, my images are losing it's class property and a width and height attribute is forced to appear.

That fails with my needs, because I'm using that image class to use it as object-fit:'cover' in it's className.

Google Page Speed still asking to defer offscreen images

Hi fellas,

I've implemented yall on our company site, i have included the polyfill.io script in the example but google page speed is still telling me to defer off screen images even though they are.

Any ideas as to why? Every image has the lazy class attached and the data-src URL. I'm baffled.

Thanks

Create an ultra-modern version?

Since support for IntersectionObserver has been implemented, I've been wondering if there's interest in a version of yall.js that only uses IntersectionObserver and doesn't fall back to binding scroll/resize event listeners for older browsers. At this time (22 October, 2017), IntersectionObserver support is at about ~63%: http://caniuse.com/#feat=intersectionobserver

Some cursory tinkering reveals that relying only on IntersectionObserver could slim this script down to 726 bytes. Thoughts?

Don't use multiple IntersectionObservers

As @xPaw pointed out in #9, the current IntersectionObserver code creates multiple instances of the IntersectionObserver class. The current solution does work, and it is still more performant (in my cursory testing) than binding scroll handlers and such, but it would be more performant to have a 1:many relationship between observers and elements, rather than a 1:1 relationship as currently exists.

If the uncompressed version is used: js errors

When i use the uncompressed Version (yall.js) errors appear in the console. In Internet Explorer 11 and on iPad, lazy loading then does not work.

For example Line 39 causes a mistake, because "...userOptions" it is actually a comment :

  // Default options, merged with user options.
  const options = {
    lazyClass: "lazy",
    lazyBackgroundClass: "lazy-bg",
    lazyBackgroundLoaded: "lazy-bg-loaded",
    throttleTime: 200,
    idlyLoad: false,
    idleLoadTimeout: 100,
    threshold: 200,
    observeChanges: false,
    observeRootSelector: "body",
    mutationObserverOptions: {
      childList: true,
      subtree: true
    },
    ...userOptions
  };

(If I want to compress the uncompressed file, errors also appear.)

null is not an object (evaluating 't.tagName')

n(e){if("IMG"===e.tagName){var t=e.parentNode;"PICTURE"===t.tagName&&i(t.querySelectorAll("source")).forEach(function(e){return s(e)}),s(e)}

I found a problem since I start using yall.js
It's tracked by my Sentry and most of the issues came from Safari/IOS/Iphone.

image

Image not loaded in random cases on Safari.

Hi,
I am experiencing an issue where is some random cases image is not loaded in Safari.
yall.js 3.1.1
Safari 12.1.1

Here's a quick screen recording of the issue:
https://drive.google.com/file/d/1X_tKFQF4373sqryXPo6gfT1i_gUna8C5/view

When I scroll back to that specific image which is not loaded it then gets loaded.
Also this is not happening for a specific image, but for a random image on every page refresh.

document.addEventListener("DOMContentLoaded", function () {
        yall({
            threshold: 1800
        });
 });

Is anyone having the same issue?

Only "lazy" class?

Hello, first, thank you very much for the time you have spent, spend, on yall.

Is there any way to tell yall to observe more than one class?.
I mean default is "lazy", anyway I can add one more.

Scenerio:
Iframes (youtube videos) created in an editor (Quill.js) as part of a post (not wp) and no chance to change classes or add them because it is javascript and when they, iframes, are loaded in page with their own class I have no chance to add "lazy" unless I edit the script, which is far away from my knowledge.

Thank you and all the best!

More rigorous viewport checks.

Currently, yall.js checks if images are beneath the viewport, but not above. This leads to scenarios where, if a page is reloaded or a deep link is hit, any images above the viewport are loaded when yall inits.

For better performance, yall.js should check if an image is below or above the viewport to avoid loading images that are above, but still out of the user's viewport.

npm install can fail on windows

npm install can fail for yall.js because of this step:

rm -rf ./dist

rm may or may not be a valid command on windows depending on the console used

I ran it from a Powershell console and even though rm is aliased it still failed at that command with this error message:

 [email protected] postinstall C:\Code\..\node_modules\yall-js
> npm run build


> [email protected] build C:\Code\..\node_modules\yall-js
> npm run clean && npx rollup -c


> [email protected] clean C:\Code\..\node_modules\yall-js
> rm -rf ./dist

'rm' is not recognized as an internal or external command,
operable program or batch file.
npm ERR! code ELIFECYCLE
npm ERR! errno 1
npm ERR! [email protected] clean: `rm -rf ./dist`
npm ERR! Exit status 1
npm ERR!
npm ERR! Failed at the [email protected] clean script.
npm ERR! This is probably not a problem with npm. There is likely additional logging output above.
npm WARN Local package.json exists, but node_modules missing, did you mean to install?

npm ERR! A complete log of this run can be found in:
npm ERR!     C:\..\AppData\Roaming\npm-cache\_logs\2019-07-29T15_06_46_005Z-debug.log
npm ERR! code ELIFECYCLE
npm ERR! errno 1
npm ERR! [email protected] build: `npm run clean && npx rollup -c`
npm ERR! Exit status 1
npm ERR!
npm ERR! Failed at the [email protected] build script.
npm ERR! This is probably not a problem with npm. There is likely additional logging output above.
npm WARN Local package.json exists, but node_modules missing, did you mean to install?

npm ERR! A complete log of this run can be found in:
npm ERR!     C:\..\AppData\Roaming\npm-cache\_logs\2019-07-29T15_06_46_044Z-debug.log
npm WARN rollback Rolling back [email protected] failed (this is probably harmless): EPERM: operation not permitted, lstat 'C:\Code\..\node_modules\fsevents\node_modules'
npm WARN assets No description
npm WARN assets No repository field.
npm WARN assets No license field.
npm WARN optional SKIPPING OPTIONAL DEPENDENCY: [email protected] (node_modules\fsevents):
npm WARN notsup SKIPPING OPTIONAL DEPENDENCY: Unsupported platform for [email protected]: wanted {"os":"darwin","arch":"any"} (current: {"os":"win32","arch":"x64"})

npm ERR! code ELIFECYCLE
npm ERR! errno 1
npm ERR! [email protected] postinstall: `npm run build`
npm ERR! Exit status 1
npm ERR!
npm ERR! Failed at the [email protected] postinstall script.
npm ERR! This is probably not a problem with npm. There is likely additional logging output above.

npm ERR! A complete log of this run can be found in:
npm ERR!     C:\..\AppData\Roaming\npm-cache\_logs\2019-07-29T15_06_46_577Z-debug.log

This issue can be avoided by running this command:

npm install --ignore-scripts

However, the npm script should probably be tweaked to avoid the error. Perhaps the dist folder should be allowed to live?

Add an onYallLoad callback option?

Hi - thanks for the useful script. I have a feature suggestion for you.

In my case I am periodically (re)loading elements containing images in the page. Simply adding the lazy class on all images, and then triggering yall works okay but the placeholder image (which in this case is not derived from the desired image) flickers briefly as a result.

My approach to resolving this is to 'remember' which images have been previously seen & not to lazy load those.

Implementing that remembering process simply requires a callback(imageSrc) call at the end of the yallLoad function.

That might be generally useful for other elements too? And other users?

Regards,
Gordon

Broken loop in yallApplyFn

yallApplyFn uses a for ... in loop to loop over an array. However, this loop also considers all enumerable object keys and not only array indices. This can break the intended functionality in cases where e.g. Array.prototype has been extended by custom keys.

Doesn't seem to work in MS Edge

the current version does not seem to work in MS Edge. i can see placeholders, but loading of images does not take place. Is there a work-around, or is there any plan to get it working

Update [email protected]

Hi,

Thanks for this usefull tool !

When i install yall with yarn, i have the message below :
warning yall > [email protected]: This version is no longer maintained. Please upgrade to the latest version.

Please can you update joi version ?
Thanks

EDIT : Me again :), when i compile with Webpack, i have this messages :

ERROR  Failed to compile with 2 errors                                                                                                                    09:33:28

These dependencies were not found:

* dns in ./node_modules/isemail/lib/index.js
* net in ./node_modules/joi/lib/string.js

Are this libraries not installed with yall ?

Encapsulated code

It looks like there are three functions exposed to the global namespace (from the minified version).
Is it possible to encapsulate the code and only expose the 'yall' function to the global namespace?

Thanks

Puppeteer script fails, fetch as google fails

I implemented Yall, and it loads very nicely on my desktop, and even the Puppeteer screenshot, but the script fails because the comparison is different, and Fetch as google shows a blank.

This is what Google says:
https://developers.google.com/search/docs/guides/lazy-loading

Test
After you set up your implementation, you should make sure it works correctly. One way you do this is by using a Puppeteer script to locally test your implementation. Puppeteer is a Node.js library for controlling headless Chrome. To run the script, you'll need Node.js. Use the following commands to check out the script and run it:

So without scroll events, it fails.. I don't know what reason? It is using intersection observer, but still does not work through this script. Worse is that Google fetch fails completely...

I even tried to Polyfill, and it doesn't load in fetch as Google. Very strange.

Any ideas? Have you tested this on Fetch as Google and Puppeteer?
Only Zepto Lazy was able to load properly with Fetch as Google. Even the famous verlok/lazyload did not work, but the old Fetch as Google is gone now. It would load only the first image. Now we can never know if the fetch works properly for 2nd, 3rd images, etc.. only first.

Just to note, the Puppeteer screenshot with scroll does end up loading the images. But the one without scroll is missing them.

I have yet to find one script that passes that test, and most other don't pass the fetch as Google test.

Seems like this lazy loading is more of a headache than anything concerning compatibility and Google. I've spent so much time trying to find a good solution.

Browser loading the <noscript> image files by default even if they are hidden by 'display:none'

HI malchata,

We are using your suggestion of noscript elements everywhere we are using lazy loading using yall.js. We noticed that yall.js seems to be working as expected when the browser can run javascript. BUT, it seems those lazy loaded images are all being preloaded any way by the browser because of how the browser treats the noscrip elements. Apparently, when the browser can run js, the noscript elements still makes the browser/chrome to download the image inside the .

...

<img class="lazy sampleimage" data-src="image1.jpeg" src="PLACEHOLDER-IMAGE.png" alt="This is a image when browser can do js.">
<noscript>
        <img src="image1.jpeg" class=" sampleimage" alt="This is image when browser cannot do js.">
</noscript>

...
I was thinking we can add a simple js-code to just display:none all elements so they will not require their child images to be loaded by the browser. Also, when the browser cannot run js, this code will not run and we will have the element to fall back to display the img

While it seems to be a quick fix, I am not sure if this is the best approach. I'd like to have your opinion on how to handle the issue of browser loading the image files by default.

SCRIPT1028: SCRIPT1028: Expected identifier, string or number

Microsoft Edge error

SCRIPT1028: SCRIPT1028: Expected identifier, string or number
yall.js (137,5)

I also get

SCRIPT5009: SCRIPT5009: 'yall' is not defined

My document works sort of in Google Chrome (see #24) but in Microsoft Edge, any images that are controlled with yall.js are not working.

My code

<img class="lazy" alt="alt text" src="img/placeholder.jpg" data-src="img/image.jpg">

Just before closing body tag (</body>)

<script src="js/yall.js"></script>
<script>document.addEventListener("DOMContentLoaded", yall);</script>

2.3.2 not working with IE11

I am getting an Unspecified Error here: ed.top<=innerHeight+z
I am using the yall.min.js 2.3.2. The error happens after clicking the back browser button.

Lazy Loading Fails With Polyfil

When using the intersection-observer polyfill package from NPM, lazy loading doesn't work. The compatibility check here

if (io in win && `${io}Entry` in win && "isIntersecting" in win[`${io}Entry`].prototype) {
seems to be failing.

SVGs not loading in OSX & iOS Safari

SVG files fail to load in Safari. The Javascript console has this error:

Unhandled Promise Rejection: EncodingError: Invalid image type.
[N] (anonymous function)
[N] promiseReactionJob

I made a test on plunker. You can use it to test here: https://next.plnkr.co/plunk/GJEd9DNdH9xRHzJanfau

Essentially the test loads a .jpg into the src attribute and an svg into the data-src attribute. I pasted the latest yall.js version (2.1.0) into the plunk script file and added jquery 3.1.1 above it.

observeRootSelector not working for list of IDs

From the manual of yall.js "... you can confine the observer to any valid CSS selector".
However it doesn't work if I use a list such as "#id1,#id2,#id3,#id4".
It works with a single ID such as "#id1".

yall doesn't seem to work on iOS

Hi,
while testing yall's lazy loading on iOS, we found out, that no image was loaded there at all. I thought maybe it's something with my page setup. However, I create a small JSbin which allows reconstructing the issue outside the original environment.

I only see the placeholder image but the lazy-loaded nature image never appears in iOS:
https://jsbin.com/gexusareze/edit?html,output

I tested it on iOS 9 through Browserstack. Can you please check that issue?

Thank you,
bb

Hardcoding strings to variables might not actually produce smaller gzip output

From uglifyjs' repo:

If your code is very hand-optimized concerning var declarations, this lifting variable declarations might actually increase size.

There's absolutely no need to have shortened variable names in source code as the minified code has mangled variables anyway. It will increase readability a lot by having properly named variables (the minified output will still be the same size).

Can div or span be used instead of img?

Does this plugin support using a div or span instead of an img tag to lazy load an image? My use case is that I don't want to use a placeholder image and would like to use a generic div or span element to indicate where the lazy-loaded image should render because I don't want to use an img element where it is it not semantically valid to do so.

Firefox slider with lazyloading doesnt work

Firefox version 68 (should happens in other versions as well)
Yall version 3.1.1
jQuery FlexSlider version 2.2.2

Only the first slide is lazy loaded and the rest shows blank or default placeholder always.

We use observer yall({ observeChanges: true }) with polyfill.

We however noticed that if we scroll down and again scroll up the latest slider in view is loaded (but not all the others)

option to bypass `classList` mutation?

hey @malchata

it would be useful if yall offered an option to avoid classList mutation. it would require a bit more internal book-keeping, likely via a couple Set objects, e.g. bgLoaded and srcLoaded.

the main motivation for this is when used with a virtual-dom lib. let's say hyperscript creates an element h("img", {class: "lazy", "data-src": "123.jpg"}) but then some action causes a redraw that results in h("img", {class: "lazy active", "data-src": "123.jpg"}). the vdom lib does the diff against the prior vnode and simply resets the className when it detects the change. if yall is relying on lazyBackgroundLoaded being present or lazyClass being absent, this would break these assumptions.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.