LMLJS, 为更少的等待而生!

LMLJS 是一款可爱滴 JavaScript 框架, 内置 Deferred 对象,实现网页图片可视区域加载,异步加载 Js 等静态资源,异步加载 HTML 中 Iframe,异步加载 CSS 样式中图片,让网页以最快的速度 onLoad,让用户在最短的时间内看到网页内容,遵循 MIT 开源协议。

如何获取 LMLJS?

LMLJS 项目地址:https://github.com/leiminglin/LMLJS。将 lml.js 文件中的代码拷贝到网站的 HEAD 标签中的 SCRIPT 标签里面,这么做只是为了让 LMLJS 在所有 JS 前执行。不建议将 LMLJS 单独放在一个 .js 文件中,这样浏览器需要发出一次请求获取 LMLJS,违背了 LMLJS 设计的初衷 - 为更少的等待而生。

启动 LMLJS

LMLJS 启动非常简单。如下代码所示:

<script>

window.onload = function(){
	lml.run();
};

</script>

异步执行 JavaScript 脚本

在页面中,如果需要执行 JavaScript 代码,若 执行过程可能比较耗时,比如需要发出请求等,可以将代码放到 LMLJS 的 then 方法中,待网页完全加载后再执行。如下代码所示:

<script>

lml.deferred.then(function(){

	/* do something here */

	lml.deferred.promise();
});

</script>

异步 CSS

异步 CSS 是指异步加载 CSS 中的图片。若网页中的 CSS 含有背景图片需要发出请求,可以使用 LMLJS 提供的 lazyCss 功能,将 CSS 内容用 textarea 包裹起来,让图片在页面渲染完成后发出请求。也可以使用其他标签包裹,只要 class 属性里面含有 lazyCss 即可。为了让 TEXTAREA 不被显示出来,需要加上一个 hidden 样式隐藏掉,下文中的 hidden 都代表这个意思。如下代码所示:

<textarea class="lazyCss hidden">

.sitebg{
	background:url(/static/bg.jpg);
}

</textarea>

异步 HTML

异步 HTML 是指异步加载 HTML 中的 Iframe JavaScript 等。若网页中需要嵌入视频或者其他的页面,这样的内容可能会拖慢网页的渲染速度,这种情况下可以使用 LMLJS 提供的 lazyHtml 功能实现异步渲染部分 HTML,异步加载的 HTML 必须要用 TEXTAREA 包裹。如下代码所示:

<textarea class="lazyHtml hidden">

<iframe height=300 width="90%"
	src="http://player.youku.com/embed/XODUzNzcwMzg4"
	frameborder=0 allowfullscreen>
</iframe>

</textarea>

下面的视频是使用 LMLJS 异步加载的。

加载 JavaScript 文件

使用了 LMLJS 后,不建议页面的源代码中直接使用 SCRIPT 标签引入外部 JS 资源,可以使用 LMLJS 提供的 loadJs 方法进行加载,需要注意的是:为了兼容 1.0 版本, loadJs 的默认回调函数仍然是 deferred.promise(); ,但建议传递一个回调,如果没有就传递空函数,如果需要加载的 JavaScript 文件中含有依赖关系,可以传入数组实现依次加载,1.1 版本增加了 competeLoad() 方法实现竞争加载,应用场景为:当项目中使用了很多的 JS CDN 服务商,可以使用此方法达到最快的加载效果,此方法适用于加载相同的 JS 文件。如下代码所示:

<script>

/* 普通加载 */
lml.loadJs(js_src);
lml.loadJs(js_src2, callback);

/* 依次加载 js_src 和 js_src2 */

lml.loadJs([js_src, js_src2], function(){});

/* 竞争加载 js_src 和 js_src2 */
lml.loadJs.competeLoad([js_src, js_src2], function(){
	/* callback */
});

/* loadJs 方法无需放在 deferred 的 then 方法中,在页面 DOMContentLoaded 后才会开始自动加载*/
</script>

loadJs 方法的第三个参数可以不传递,传入 1 代表强制加载,强制加载的意思就是如果页面已经加载了某个 JS 文件,仍然会再次请求这个 JS 文件;如果不传递,已经加载过的 JS 文件不再加载,也就是 DOM 节点中不会出现两个一样的 JS 标签,然后直接执行回调函数。

创建 Deferred 对象

若网页中有很多异步任务,且任务的优先级顺序比较复杂,通过 LMLJS 默认提供的一个 deferred 对象还不能够满足的情况下,可以使用 createDeferred 方法创建一个新的 deferred 对象嵌套在 then 方法中,来实现更复杂的异步执行流。上面的例子实现 JS 文件的依次加载同样也可以通过创建新的 deferred 对象来实现,事实上已经无需这样做了。如下代码所示:

<script>

lml.deferred.then(function(){

	var deferred2 = lml.createDeferred();

	deferred2.then(function(){
		/* deferred2 对象异步执行流 */
	});

	lml.deferred.promise();
	deferred2.promise();
});

window.onload = function(){
	lml.deferred.promise();
};

</script>

可视区域图片异步加载

LMLJS 内置了可视区域异步加载图片功能,当页面在滚动的过程中,图片标签出现在可视区域范围内,则开始加载图片资源,防止在页面中图片很多的情况下页面渲染太慢,同时也减少了服务器压力,避免了不必要的流量浪费。要实现图片在可见范围加载,需要将图片的 src 属性改为 osrc 属性,另外可以附加上一个 osrc-bak 属性作为备份图片,备份图片仅在图片加载失败后尝试的补救措施。如下代码所示:


<img
	width="635"
	height="476"
	osrc="http://git.oschina.net/leiminglin/images/raw/master/2014/12/IMG_20141224_122726.jpg"
	osrc-bak="https://raw.githubusercontent.com/leiminglin/images/master/2014/12/IMG_20141224_122726.jpg"
	alt="世纪大道午后时光-LMLPHP后院"
	title="世纪大道午后时光-LMLPHP后院"
/>

下面的图片需要在可见范围内才会被加载。

世纪大道午后时光-LMLPHP后院
2024-12-06 13:30:31 1733463031