Skip to main content
mod_pagespeed 1.15 — Cyclone Cache, modernized optimizations, IIS + .NET support, and six years of security updates

Lazy-load images

Images

Defers off-screen images until they scroll into the viewport.

Filter lazyload_images · Filter docs

A mod_pagespeed 1.15 filter. ModPageSpeed 2.0 applies it as part of one always-on pipeline, not as a separate switch.

Both frames render identically — that's the goal. The win is in the bytes and requests below, not the look. They're served live by mod_pagespeed 1.15 on demo-httpd-1.1.modpagespeed.com; the optimized frame applies only this filter. Right after a cache purge it may briefly match the original while the worker rewrites it — reload to see the result. This filter is beacon-driven: mod_pagespeed instruments the page, a real browser reports back, then it serves the optimized form and re-measures every few minutes — so the optimized frame can take a reload, or briefly revert to the original, before it reflects the change.

Measured impact

HTTP requests

5 3
−2

Total bytes

60.8 KB 9.6 KB
−84%

What changed in the source

The page's HTML, before and after this filter. Red lines are removed, green lines are added.

                
                  
… 38 unchanged lines …
loaded once you scroll down.</p>
<p>*</p>
<p>*</p>
- <img src="images/Puzzle2.jpg" srcset="images/Puzzle.jpg 2x"><br/>
- <img src="images/IronChef2.gif"><br/>
- <img src="images/Cuppa.png"><br/>
- </body>
+ <script type="text/javascript" data-pagespeed-no-defer>//<![CDATA[ (function(){function f(a,b,c){if(a.addEventListener)a.addEventListener(b,c,!1);else if(a.attachEvent)a.attachEvent("on"+b,c);else{var d=a["on"+b];a["on"+b]=function(){c.call(this);d&&d.call(this)}}};window.pagespeed=window.pagespeed||{};var g=window.pagespeed;function k(a){this.l=[];this.j=0;this.m=!1;this.v=a;this.u=null;this.A=0;this.h=!1;this.g=0}function m(a,b){var c=b.getAttribute("data-pagespeed-lazy-position");if(c)return parseInt(c,0);c=b.offsetTop;var d=b.offsetParent;d&&(c+=m(a,d));c=Math.max(c,0);b.setAttribute("data-pagespeed-lazy-position",c);return c} function n(a,b){if(!a.h&&(b.offsetHeight==0||b.offsetWidth==0))return!1;var c=0;typeof window.pageYOffset=="number"?c=window.pageYOffset:document.body&&document.body.scrollTop?c=document.body.scrollTop:document.documentElement&&document.documentElement.scrollTop&&(c=document.documentElement.scrollTop);var d=window.innerHeight||document.documentElement.clientHeight||document.body.clientHeight;var e=c;c+=d;var h=b.getBoundingClientRect();h?(c=h.top-d,e=h.bottom):(d=m(a,b),b=d+b.offsetHeight,c=d-c,e= b-e);return c<=a.j&&e+a.j>=0}
+ k.prototype.o=function(a){q(a);var b=this;window.setTimeout(function(){var c=a.getAttribute("data-pagespeed-lazy-src");if(c)if((b.m||n(b,a))&&a.src.indexOf(b.v)!=-1){var d=a.parentNode,e=a.nextSibling;d&&d.removeChild(a);a.i&&(a.getAttribute=a.i);a.removeAttribute("onload");if(a.tagName&&a.tagName=="IMG"&&g.CriticalImages){var h=!1,l=function(){h||(h=!0,b.h&&(b.g--,b.g==0&&g.CriticalImages.checkCriticalImages()))};f(a,"load",function(){g.CriticalImages.checkImageForCriticality(this);l()});f(a,"error",
+ function(){l()})}a.removeAttribute("data-pagespeed-lazy-src");a.removeAttribute("data-pagespeed-lazy-replaced-functions");d&&d.insertBefore(a,e);if(d=a.getAttribute("data-pagespeed-lazy-srcset"))a.srcset=d,a.removeAttribute("data-pagespeed-lazy-srcset");a.src=c}else b.l.push(a)},0)};k.prototype.loadIfVisibleAndMaybeBeacon=k.prototype.o;k.prototype.B=function(){this.m=!0;r(this);for(var a=document.getElementsByTagName("img"),b=0,c;c=a[b];b++)t(c,"data-pagespeed-lazy-src")&&this.o(c)};
+ k.prototype.loadAllImages=k.prototype.B;function r(a){var b=a.l,c=b.length;a.l=[];for(var d=0;d<c;++d)a.o(b[d])}function t(a,b){return a.g?a.g(b)!=null:a.getAttribute(b)!=null}k.prototype.C=function(){for(var a=document.getElementsByTagName("img"),b=0,c;c=a[b];b++)t(c,"data-pagespeed-lazy-src")&&q(c)};k.prototype.overrideAttributeFunctions=k.prototype.C; function q(a){t(a,"data-pagespeed-lazy-replaced-functions")||(a.i=a.getAttribute,a.getAttribute=function(b){b.toLowerCase()=="src"&&t(this,"data-pagespeed-lazy-src")&&(b="data-pagespeed-lazy-src");return this.i(b)},a.setAttribute("data-pagespeed-lazy-replaced-functions","1"))} g.D=function(a,b){function c(){if(!(d.h&&a||d.u)){var e=200;(new Date).getTime()-d.A>200&&(e=0);d.u=window.setTimeout(function(){d.A=(new Date).getTime();r(d);d.u=null},e)}}var d=new k(b);g.lazyLoadImages=d;f(window,"load",function(){d.h=!0;d.m=a;d.j=200;if(g.CriticalImages){for(var e=0,h=document.getElementsByTagName("img"),l=0,p;p=h[l];l++)p.src.indexOf(d.v)!=-1&&t(p,"data-pagespeed-lazy-src")&&e++;d.g=e;d.g==0&&g.CriticalImages.checkCriticalImages()}r(d)});b.indexOf("data:")!=0&&((new Image).src=
+ b);f(window,"scroll",c);f(window,"resize",c)};g.lazyLoadInit=g.D;})();
+
+ pagespeed.lazyLoadInit(true, "/pagespeed_static/1.JiBnMqyl6S.gif");
+
+ //]]></script><img data-pagespeed-lazy-src="images/Puzzle2.jpg" data-pagespeed-lazy-srcset="images/Puzzle.jpg 2x" src="/pagespeed_static/1.JiBnMqyl6S.gif" onload="pagespeed.lazyLoadImages.loadIfVisibleAndMaybeBeacon(this);" onerror="this.onerror=null;pagespeed.lazyLoadImages.loadIfVisibleAndMaybeBeacon(this);"><br/>
+ <img data-pagespeed-lazy-src="images/IronChef2.gif" src="/pagespeed_static/1.JiBnMqyl6S.gif" onload="pagespeed.lazyLoadImages.loadIfVisibleAndMaybeBeacon(this);" onerror="this.onerror=null;pagespeed.lazyLoadImages.loadIfVisibleAndMaybeBeacon(this);"><br/>
+ <img data-pagespeed-lazy-src="images/Cuppa.png" src="/pagespeed_static/1.JiBnMqyl6S.gif" onload="pagespeed.lazyLoadImages.loadIfVisibleAndMaybeBeacon(this);" onerror="this.onerror=null;pagespeed.lazyLoadImages.loadIfVisibleAndMaybeBeacon(this);"><br/>
+ <script type="text/javascript" data-pagespeed-no-defer>pagespeed.lazyLoadImages.overrideAttributeFunctions();</script></body>
</html>

Run this on your own site

This is one of 49 filters mod_pagespeed 1.15 applies in place — self-hosted on Apache, nginx, and IIS. Install and run it: it optimizes right away and adds an X-PageSpeed-Warn: unlicensed header until you license it. Production use requires a commercial license — but the software never locks you out.