instantclick 简介
instantclick.js 是一种ajax无刷新和预加载页面的技术,对于普通博客程序,有着明显的加速作用。(instantclick.js ≈ pjax + 预加载页面)而且,使用方法也十分的简单。在github截止目前,已经由4447个star了,非常可观。
但是官方文档纯英文,可能阅读上有点障碍,所以,在此,翻译一下大部分的官方文档内容,方便新手快速使用。大部分采用直译方式,需要注意的地方 用小括号注释起来。(尽管如此,instantclick.js 仍然有一些bug亟待解决,如果你可以忽略缺点吧,我们一起开始吧!)
Github:https://github.com/dieulot/instantclick/
目录
初级阶段
- 开始使用
- instantclick
- 工作原理
- 预加载页面
- 黑名单规则
- 事件和脚本的重新加载
进阶阶段
- 跟踪页面内容的变化
- 自定义加载条
初级阶段
开始使用
下载instantclick.js
最新的发布版本是2014/12/25发布的V3.1.0 (虽然github一直有更新,但是并没有发布新的版本~)
其他的下载方式
- github上面的最新开发版本
- 通过bower(一种前端开发工具) : bower install instantclick
初始化instantclick
把 instantclick.js 和 初始化代码 放在你的页面的结束之前(</body>
标签结束之前)
...
<script src="instantclick.min.js" data-no-instant></script>
<script data-no-instant>InstantClick.init();</script>
</body>
</html>
现在instantclick 已经成功在你的网页上面生效。阅读下面的文章以便更熟练的使用instantclick。
- instantclick 工作原理:将会让你建立正确的模型以便更好的理解instantclick的机制
- 预加载页面:将会向你展示不同的预加载页面的方法
- 黑名单规则:因为有些链接你不想预加载
- 事件和脚本的重新加载:将会帮助你使instantclick更好的配合你的网页中的JavaScript。
instantclick不总是“即插即用”(不是通过两行代码就可以在你的网页上运行),你可能需要自定义一些设置来适应你的网站,这也是为什么阅读上述文章是强制性的。
instantclick 工作原理
InstantClick与传统的web应用区别不大,但是很有必要去了解这些不同的地方!
instantclick使浏览器不再刷新整个页面(即无刷新页面效果)
首先:你需要理解的核心内容是:instantclick在技术上使你的网站成为单页应用程序;浏览器不再刷新整个页面,而是通过instantclick技术来更改页面内容,这意味着:
- 你不能依赖
DOMContentLoaded
和jQuery.ready()
这两个函数来触发相关事件(这两个事件在刷新整个页面的时候才会触发,但是你可以使用[InstantClick’s
events]()来替代) - 依赖上面两个函数的第三方脚本(比如js代码)需要调整(参阅[事件和脚本的重新加载]())
- 在加载页面的时候,浏览器不会在显示原本加载进度条了,instantclick有它自己的加载进度条。
下面还有一些内容你需要了解:
- 通过instantclick加载的每个页面的<head>标签里面的样式和脚本应该是相同的(因为instantclick只会加载一次<head>标签里的内容)
- 如果<head>标签里面的某些内容依赖于网页的内容(比如在页面加载时运行的脚本或css动画),它需要调整以便正常运行。
InstantClick是渐进式增强功能:如果访问者的浏览器不支持InstantClick,您的网站链接将照常工作,只是不会提升速度了。
预加载页面
InstantClick 关于预加载方式有多种选择。你可以根据你的服务器配置来选择合适的方式。
但是不管怎样,当每个页面改变时,不会重新加载脚本和样式表,这样会使你的页面加载速度提升一倍!(与Turbolinks
、pjax
等等技术是类似的)
默认: 在鼠标悬停预加载(on mouseover
)
当用户鼠标悬停在链接上开始预加载页面。如果用户网络链接不错的话,你的页面会很快的打开。
初始化方法就是[开始使用]()设置的方式。
不会给服务器带来额外负担:在鼠标点击的瞬间预加载(mousedown
)
当用户按下你的链接按钮的瞬间,页面开始预加载。这为你的服务器带来了接近零的开销,但仍然能够带来一个很“神奇”的速度提升!
使用方法:将'mousedown'作为参数传递给InstantClick.init
InstantClick.init('mousedown');
折中的方式:鼠标悬停延迟一定时间才会预加载
如果用户在您选择的延迟过后仍悬停在链接上,则该网页将开始预加载。
推荐的延迟时间为:100ms和50ms。超过100ms效果比mousedown效果更差。低于50ms,则会与mouseover
效果相似。
要使InstantClick
延迟一定时间后预加载,请将延迟(毫秒)作为参数传递给InstantClick.init
。
InstantClick.init(50);
手机端效果
上面的任何预加载方式,在手机端的时候,当用户手指接触链接时候都会开始预加载。
如果您的网站针对移动设备(在安卓和iOS界面上使用了[FashClick]()技术)进行了优化,则当访问者从链接中释放手指时,会发生“点击”,导致预加载大约100 ms的延迟。
如果您的网站没有针对手机进行优化,延迟时间则取决于操作系统。 Android给出300 ms,iOS给出450 ms。
在同一站点上的3G请求的延迟时间通常需要大约200ms。
如何选择?
如果您的网站可以处理额外的负载,选择 在鼠标悬停时预加载方式。
如果你的网站不能,选择在鼠标点击的瞬间预加载方式。您的网站的速度仍然会超过99%的网站。
如果你想确定你的服务器是否可以,先选择在鼠标点击的瞬间预加载方式,你的服务器几乎不会有额外的压力。然后使用鼠标悬停延迟100毫秒预加载。然后50毫秒延迟(或减少更小的减少,如果你有耐心)。然后直接用在鼠标悬停时预加载,分别看你的服务器是否能够承受额外的负担。
如果服务器端分析很重要,你只能使用在鼠标点击的瞬间预加载,使用任何其他方式都会带来误差。
黑名单规则
有一些链接是不需要通过instantclick
来预加载。黑名单规则可以实现这个效果。
哪些需要进入黑名单
哪些需要进入黑名单,而不能进入白名单的:
- 链接指向操作,例如注销和切换语言。
- 链接指向需要一段时间加载的非HTML内容
- 链接指向的页面与当前页面<head>标签内的css样式和脚本不同
- 链接触发
JavaScript
的操作 - 部分链接已在内部列入黑名单,且无法列入白名单:
- 链接有
target
或者download
属性 - 链接与当前的域名或者协议不同
- 链接指向当前页面的锚点链接(
#anchor
) - 把一个链接列入黑名单
- 把一个链接加入黑名单,只需要在链接中加入
data-no-instant
属性
把一组链接列入黑名单
有时候要把一组链接一起列入黑名单,这时候比给所有链接分别添加data-no-intant
要方便的多。
把父元素内部的所有链接列入黑名单,只需要向该父元素添加data-no-instant
属性。
把一个链接或者一组链接列入白名单
如果您已将某个父元素列入黑名单,并且希望将其中的某个链接(或者子元素内部的所有链接)列入白名单,只需要向该链接或子元素添加data-instant
属性。
InstantClick
在后台中从当前链接的位置到</html>的位置,遍历所有的父元素,如果找到data-no-instant
属性,它就会认为该链接已经被列入黑名单,并停止循环遍历父元素。如果它找到data-instant
属性,它会认为该链接已经被列入白名单。(此处翻译可能需要修改)
如果您希望默认将所有链接列入黑名单,然后逐个将链接列入白名单或仅想把某个容器的链接列入白名单,请在<body>
添加一个data-no-instant
属性,然后向该链接或者容器中添加data-instant属性。
白名单模式
下面的方法已经弃用,可能会在4.0版本中删除。只有当你的网站正确激活参数(真正的参数传递给InstantClick.init
),这种方法才会有用。(此处翻译可能需要修改)
正确的方式™:如果要实现与白名单模式相同的效果,只需添加data-no-instant
到你的<body>
标签中,参见上一条目“把一个链接或者一组链接列入白名单”。
通过向InstantClick.init传递true
参数来启用白名单模式。
InstantClick.init(true);
/* or */
InstantClick.init(50, true);
/* or */
InstantClick.init('mousedown', true);
事件和脚本的重新加载
InstantClick
技术上使你的网站成为单页应用程序,因此当页面切换的时候,不会触发DOMContentLoaded
函数。因此,一些脚本可能需要调整才能与InstantClick正常工作。
InstantClick
会触发4个事件以便于挂钩到页面的整个生命周期:
change
:当前的页面一旦改变会触发该事件,即使浏览器不支持instantclick
,页面初始加载的时候也会触发该事件,这个事件可以用来替换DOMContentLoaded
.
它的回调可以接受一个可选的isInitialLoad
参数,它是一个布尔值,当它是初始页面更改或当InstantClick
不被支持时为true
,而当InstantClick
更改页面时为false。(此处翻译需要修改)
fetch
:页面开始预加载的时候receive
:页面已经预加载完成,你可以使用该事件[修改页面的内容]().wait
:用户已经点击了链接,但是页面还没有开始预加载。仅在页面不是立即显示(可能由于网络原因)的时候触发。
监听一个事件,比如change,你可以使用InstantClick.on
:
InstantClick.on('change', yourCallback);
您需要在InstantClick.init
之前调用InstantClick.on
,因为change
事件在网页初始加载时就会被触发,包括浏览器不支持pushState
的时候。(此处翻译可能需要修改)
如果在<body>标签内部有一个脚本,当instantclick
切换到另一个页面的时候,你并不希望重新加载它 ,你可以添加一个data-no-instant
属性。
<script data-no-instant>alert("I’m only run once.");</script>
如果有一些脚本与instantclick
发生冲突,建议向所有脚本添加一个data-no-instant属性,然后逐个删除每个属性,直到找到罪魁祸首。您可以通过查看Turbolinks兼容性站点上的示例(在CoffeeScript中)了解如何解决兼容性问题。
例如,以下是如何使Google Analytics
(网站统计与分析)(2013年末的代码)正常工作:
<script src="instantclick.min.js" data-no-instant></script>
<script data-no-instant>
/* Google Analytics code here, without ga('send', 'pageview') */
InstantClick.on('change', function() {
ga('send', 'pageview', location.pathname + location.search);
});
InstantClick.init();
</script>
在receive
事件里改变页面内容
有时,即时改变页面内容比为instantclick重构你的后端代码要简单。你可以使用receive事件。
这个事件有三个参数:url
, ,body
和title
。
url 接收的页面的地址,它包括哈希值。它是只读的。
body
是body
对象,title
是标题文本。如果你想在页面显示之前改变页面内容,你可以修改这两个参数并返回一个对象(或者只修改其中的一个参数)。
下面是一个例子:
InstantClick.on('receive', function(url, body, title) {
var dont_display = body.querySelector('#dont_display_me_when_loaded_with_instantclick')
if (dont_display) {
dont_display.setAttribute('hidden', '');
}
title += ' (loaded with InstantClick)';
return {
body: body,
title: title
};
});
要记住 body
对象是body
而不是document.body
!
当您有多个回调函数监听receive
函数时,每个后续回调将获得最后更改的内容。
如果你不想修改页面内容,则不用返回任何内容或返回false。
进阶阶段
跟踪页面内容的变化
当前跟踪页面内容的变化的方式目前有点笨拙。它可能稍后在InstantClick 4.0中更改。
要检查样式表或脚本(外部或内联)何时更新,请添加一个data-instant-track属性:
<link rel="stylesheet" href="style.css" data-instant-track>
<script src="script.js" data-instant-track></script>
<style data-instant-track>body { background: aliceblue; }</style>
<script data-instant-track>window.timingStart = performance.now();</script>
InstantClick将检查href或src属性(如果存在)中的更改。要指示文件已更新,请修改其属性:
<link rel="stylesheet" href="style.css?20140308" data-instant-track>
<script src="script.js?20140308" data-instant-track></script>
如果它是内联脚本或样式,InstantClick将检查元素内容中的更改。
<style data-instant-track>body { background: midnightblue; font: 13px Helvetica; }</style>
<script data-instant-track>var timingStart = performance && performance.now();</script>
当检测到任何更改时,InstantClick将重新加载页面,从而使浏览器重新评估所有脚本和样式。
自定义加载条
进度条是一个假的进度条,只是在那里给你的用户的感觉页面的加载进度。
在未来,应该可以使进度条显示真正的进度(通过查看服务器的Content-Length头)。
即使页面已经立即加载,也会显示进度条,在将来这将更改。你可以在github讨论。
当访问者缩放页面或旋转其设备时,该栏的大小和位置会自动调整,因此即使您的网站未针对移动设备进行优化,也会正常工作。
默认情况下,进度条的颜色为#29d
, 你可以改变CSS:
#instantclick-bar {
background: white;
}
你也可以让进度条消失:
#instantclick {
display: none;
}
使进度条消失的方式不是最佳的。在稍后的InstantClick
版本中,可能可以通过向InstantClick.init
传递参数来实现这个效果。