malchata / yall.js Goto Github PK
View Code? Open in Web Editor NEWA fast, flexible, and small SEO-friendly lazy loader.
License: MIT License
A fast, flexible, and small SEO-friendly lazy loader.
License: MIT License
Hey,
Will there be a way to import es5 file in the future? Currently only .mjs
does have export where es5 version doesn't export anything :( https://github.com/malchata/yall.js/blob/master/dist/yall.min.js.
Is this something that will be addressed or are we forced to compile yall.js with babel ourselves?
Thanks
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?
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
.
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.
Hello!
Is there a way to create a fade-in transition for lazy loaded images?
Thanks!
@malchata, are you interested in a pull request?
Hi, as per the title: does Yall also work for IE10?
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. 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
hey @malchata ,
i don't really feel like polyfilling Intersection Observer and would prefer to just immediately load everything. is this something you could add?
thanks!
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.
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
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?
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.
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.)
I've noticed that some files are missing in the newest version (3.1.5).
https://registry.npmjs.org/yall-js
Here you can see that the newest version only contains 4 files, compared to the previous version with its 6 files.
Since the .min.js file is missing this might be a problem to some more people.
Uncaught (in promise) DOMException: The source image cannot be decoded.
Any idea why? It works for other images.
Thank you for making this JavaScript script.
I am using the yall-2.0.1.min.js
file.
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?
In the package.json, we list "@babel/plugin-proposal-export-default-from" as a dependency, even though I believe it's only used in development.
We should remove it so future installers don't add this to their dependency graph.
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!
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 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?
What to do when video poster attribute used?
Poster image is not lazy loaded.
How about data-poster included?
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
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.
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
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 ?
You need some kind of interaction with the page (scroll, orientationchange, touchmove) for the image to load.
Tested on Safari, Chrome and Firefox.
Example here:
https://codepen.io/kalled/pen/XqwbwV
I'm a bit busy this week but hopefully I can look into this after the weekend.
Soon, we'll have an API available in some browsers that will allow us to asynchronously decode images. When images are appended to the DOM, the decoding phase can cause delays in the next frame, which can result in jank. By implementing this API, we'll add a little weight to yall.js, but it will definitely be worth it for a better lazy loading experience.
More info: https://bugs.chromium.org/p/chromium/issues/detail?id=705669
In params array operator '...' in string '...userOptions' causes an error on some iOS and MacOS.
Hey Malchata,
I followed along with you here: https://developers.google.com/web/fundamentals/performance/lazy-loading-guidance/images-and-video/
Within that article, you had the ability to use lazy loading with Background Images. Is there a way to use that similarly with yall.js?
Thanks
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
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.
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.
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>
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.
Under Words of Wisdom there's a link to LQIP but that link returns a 404 page.
When using the intersection-observer
polyfill package from NPM, lazy loading doesn't work. The compatibility check here
Line 88 in 13e7c5c
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.
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".
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
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).
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.
I used the Google Webmasters Google Fetch tool and images are not being rendered. Did yall.js fail?
Maybe this means Googlebot will not index the images?
Chrome 41 is used by Google Fetch tool.
loadImage = function(img){
...
elements.splice(elements.indexOf(img), 1);
},
This doesn't work. Firstly, it doesn't remove the observer entry correctly, secondly, if the element is not found i.e. elements.indexOf(img) === -1
, the splice removes the last element of the array! The result is that some images don't get loaded.
There's an easy fix, I'll put through a PR.
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)
Tested on OSX and IOS, the image actually loads only if browser is resized or scrolled, this is related to issue #20 i think?
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.
A declarative, efficient, and flexible JavaScript library for building user interfaces.
๐ Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. ๐๐๐
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google โค๏ธ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.