对 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. 个人博客感觉用处不大…
    图片什么的很少…
    图片站需要啊…

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

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

时间过去太久,评论已关闭。
如果您有话要说,请到讨论区留言并给出此文章链接。
谢谢您的理解 :-)