对 WordPress Lazy Load 图片延迟加载插件稍作改进

之前介绍了用于 WordPress 页面图片按需延迟加载效果的插件 Lazy Load,启用后可以显著提高文章中有图片的页面的加载速度,减少页面加载时间。但是目前该插件仅对文章/页面内容中的图片进行处理,并且相关的 JavaScript 文件至少有 2 个是可以合并的。

我比较喜欢折腾,有时候会使用工具(比如百度统计后台的页面速度分析工具)来分析页面的优化,然后根据建议进行调整。所以希望对 2 个插件本身的 JavaScript 文件进行合并,减少一次浏览器请求。另外将 Lazy Load 效果从文章/页面内容内部的图片,扩展到评论作者头像上。

0. UPDATE

2012.09.04

今天 Lazy Load 插件发布了更新,版本号升级为 0.5。本次更新加入对评论作者头像(Avatar)的 Lazy Load 支持,不再对控制后台的图片执行 Lazy Load,同时还改进了与 Jetpack Carousel 的兼容性以及修正了一个小 bug。

所以本文也相应更新部分说明,并将最后的打包文件进行了相应的修改。

以下修改基于 Lazy Load 当前版本 0.4 0.5。以后如有更新将会在本页修改说明。

1. 将 Lazy Load 效果扩展作用于评论作者头像

:0.5 版开始,Lazy Load 已加入对 Avatar 图片的支持。

对于 WordPress 而言,除了主题中使用的图片,以及文章/页面内容中包含的图片之外,还有一个就是评论作者头像(avatar)。虽然评论作者头像 Avatar 是从别的服务器上下载而不是本地服务器下载的,不会给自己的服务器造成多大压力。但是当页面显示了评论作者头像而此页面上的评论又比较多的时候,页面加载速度就会大受影响。

要对评论作者头像实现 Lazy Load,只需要对 WordPress 内置的 get_avatar() 函数使用 filter 就可以了。方法是:

编辑 Lazy Load 插件文件夹下的 lazyload.php 文件,在第 21 行下面添加下面的代码,

// get_avatar filter
if ( ! is_admin() ) // 在 WP 控制台(Dashboard)中的时候不应用此效果
    add_filter( 'get_avatar', array( __CLASS__, 'add_image_placeholders' ), 11 );

保存后上传覆盖原来的文件即可。

改进后的 Lazy Load 还是无法处理 WordPress 工具条上的作者头像(Avatar)

改进后的 Lazy Load 还是无法处理 WordPress 工具条上的作者头像(Avatar),显示为用于 Lazy Load 的替代图片(这里是灰色的空白)

请注意:这样做有一个小的遗憾就是,当我们选择在浏览前台页面显示 WordPress 工具条的时候,工具条上右边的自己的 Avatar 也不会显示。因为这个工具条实际上是在页面 wp_footer() 之后才生成的,而插件的工作范围是 wp_footer() 函数之前(插件的 JavaScript 输出最晚就在这里)。如图所示:

2. 合并 Lazy Load 内部的 2 个 JavaScript 文件

在 Lazy Load 插件文件夹下面还有个 js 文件夹,有 3 个文件,分别是:

  • jquery.sonar.js – 未经压缩;仅存档,页面中不使用,与下一文件内容相同
  • jquery.sonar.min.js – 经过压缩,页面中调用,实现 Lazy Load 效果,内容同上
  • lazy-load.js – 调用 jquery.sonar.min.js 中定义的函数来动态处理页面中的内容

插件在工作时使用了上面后两个 JavaScript 文件,而且必须同时调用,且有先后顺序:jquery.sonar.min.js 在前,lazy-load.js 在后。实际上,在 jquery.sonar.min.js 之前还必须调用 jquery.js(或 jquery.min.js)文件。

但是我们知道,多一个资源,浏览器就必须多发送一次请求来下载此资源。对于插件作者而言,这样安排是可以理解的。将不同功能的 JavaScript 文件分开来放,显得更加有条理,也便于使用者(比如像我这样没事儿喜欢折腾一下的人)理解。所以我就把这两个文件内容合并,另存为一个新的 JavaScript 文件,同时让该插件调用新的合并的 js 文件而不再调用旧有的 2 个 js 文件。方法如下:

  1. 新建一个 all.js 文件,放在 Lazy Load 插件文件夹下的 /js 文件夹下;
  2. 将 jquery.min.js 中的内容复制进 all.js;
  3. 将 lazy-load.js 中的内容复制进 all.js,放在刚才的内容后面(该文件内容未压缩,能压缩一下就更好,文后附上压缩过的文件内容);
  4. 修改 lazy-load.php 文件,将
    static function add_scripts() {
        wp_enqueue_script( 'wpcom-lazy-load-images', self::get_url( 'js/lazy-load.js' ), array( 'jquery', 'jquery-sonar' ), self::version, true );
        wp_enqueue_script( 'jquery-sonar', self::get_url( 'js/jquery.sonar.min.js' ), array( 'jquery' ), self::version, true );
    }

    替换为,

    static function add_scripts() {
        // wp_enqueue_script( 'wpcom-lazy-load-images', self::get_url( 'js/lazy-load.js' ), array( 'jquery', 'jquery-sonar' ), self::version, true );
        // wp_enqueue_script( 'jquery-sonar', self::get_url( 'js/jquery.sonar.min.js' ), array( 'jquery' ), self::version, true );
        // combine and compress to all.js, cnzhx.net
    	    wp_enqueue_script( 'cnzhx-sonar-lazyload', self::get_url( 'js/all.js' ), array( 'jquery' ), self::version, true );
    }
  5. 保存并上传 all.js 和 修改后的 lazy-load.php 文件。

附,最小化过的的 all.js 文件,第一行是 jquery.sonar.min.js 的内容,第二行是 lazy-load.js 的内容:

(function(e,h,l,c){e.fn.sonar=function(o,n){if(typeof o==="boolean"){n=o;o=c}return e.sonar(this[0],o,n)};var f=l.body,a="scrollin",m="scrollout",b=function(r,n,t){if(r){f||(f=l.body);var s=r,u=0,v=f.offsetHeight,o=h.innerHeight||l.documentElement.clientHeight||f.clientHeight||0,q=l.documentElement.scrollTop||h.pageYOffset||f.scrollTop||0,p=r.offsetHeight||0;if(!r.sonarElemTop||r.sonarBodyHeight!==v){if(s.offsetParent){do{u+=s.offsetTop}while(s=s.offsetParent)}r.sonarElemTop=u;r.sonarBodyHeight=v}n=n===c?0:n;return(!(r.sonarElemTop+(t?0:p)<q-n)&&!(r.sonarElemTop+(t?p:0)>q+o+n))}},d={},j=0,i=function(){setTimeout(function(){var s,o,t,q,p,r,n;for(t in d){o=d[t];for(r=0,n=o.length;r<n;r++){q=o[r];s=q.elem;p=b(s,q.px,q.full);if(t===m?!p:p){if(!q.tr){if(s[t]){e(s).trigger(t);q.tr=1}else{o.splice(r,1);r--;n--}}}else{q.tr=0}}}},25)},k=function(n,o){n[o]=0},g=function(r,p){var t=p.px,q=p.full,s=p.evt,o=b(r,t,q),n=0;r[s]=1;if(s===m?!o:o){setTimeout(function(){e(r).trigger(s===m?m:a)},0);n=1}d[s].push({elem:r,px:t,full:q,tr:n});if(!j){e(h).bind("scroll",i);j=1}};e.sonar=b;d[a]=[];e.event.special[a]={add:function(n){var p=n.data||{},o=this;if(!o[a]){g(this,{px:p.distance,full:p.full,evt:a})}},remove:function(n){k(this,a)}};d[m]=[];e.event.special[m]={add:function(n){var p=n.data||{},o=this;if(!o[m]){g(o,{px:p.distance,full:p.full,evt:m})}},remove:function(n){k(this,m)}}})(jQuery,window,document);
(function(a){function b(){a("img[data-lazy-src]").bind("scrollin",{distance:200},function(){c(this)});a("[data-carousel-extra]").each(function(){a(this).find("img[data-lazy-src]").each(function(){c(this)})})}function c(a){var b=jQuery(a),c=b.attr("data-lazy-src");b.unbind("scrollin").hide().removeAttr("data-lazy-src").attr("data-lazy-loaded","true");a.src=c;b.fadeIn()}b();a("body").bind("post-load",b)})(jQuery)

虽然将 Lazy Load 这样的功能整合进入主题也是一个很好的主意:将 Lazy Load 的内容整合进入主题的 functions.php 文件(没有的话需要创建一个),不过对于我这样使用多站点(MultiSite)模式的就不太方便了。

免得有人想修改可是又懒得修改,放上我修改后的打包文件吧,上传并覆盖原来的 Lazy Load 插件文件夹就可以了。不过如果自动升级的话就会覆盖掉我修改的部分,到时候根据情况再更新这里的文件吧:水景一页修改版 Lazy Load 插件©

本文发表于水景一页。永久链接:<https://cnzhx.net/blog/improvements-to-wordpress-lazy-load/>。转载请保留此信息及相应链接。

3 条关于 “对 WordPress Lazy Load 图片延迟加载插件稍作改进” 的评论

    • 嗯,这个就看情况用吧。我最近发现有些页面图片太多,一次性全都加载的话带宽吃紧,所以就用上了这个。

  1. 引用通告: WordPress 插件:LazyLoad 按需/延迟加载网页图片 | 水景一页

雁过留声,人过留名

您的电子邮箱地址不会被公开。 必填项已用 * 标注

特别提示:与当前文章主题无关的讨论相关但需要较多讨论求助信息请发布到水景一页讨论区的相应版块,谢谢您的理解与合作!请参考本站互助指南
您可以在评论中使用如下的 HTML 标记来辅助表达: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <s> <strike> <strong>