入门
开始
下载
最新版本 3.1.0,于2014年12月25日发布。
生产版本 2.7KB gzip+minify压缩
开发版本 21KB 完整源代码
最新开发版
Bower : bower install instantclick
初始化
在
</body>
</html>
之前且在页面末尾初始化它
像是这样:
...
<script src="instantclick.min.js" data-no-instant></script>
<script data-no-instant>InstantClick.init();</script>
</body>
</html>
InstantClick 现在在你的网站上启用成功,阅读这些了解更多:
-
工作原理
-
预加载
-
黑名单
-
内容和JavaScript的重新加载
InstantClick 并不总是“即插即用”,您可能需要调整您的网站。
这就是为什么您还需要阅读上述文章。
工作原理
InstantClick 与传统的 Web 开发几乎没有区别,但了解它们很重要。
避开了浏览器的页面更改周期
要理解的最重要的事情是:
- 使用 InstantClick 使您的网站成为单页应用
- 网页浏览器通过 InstantClick 改变页面内容。
这意味着:
- 您不能使用
DOMContentLoaded
或jQuery.ready()
触发您的代码(改用 InstantClick 的事件)。 - 引用的第三方脚本可能需要调整(请参阅内容和JavaScript的重新加载)。
- 浏览器不会在页面更改时显示自己的进度条,InstantClick 会使用自带的进度条.
InstantClick使用pushState和Ajax(pjax)来实现,只替换<body>
和头部的<title>
,浏览器不必重新解析编译页面,这样在页面跳转的过程中,浏览器不会闪一下白屏,看上去页面在瞬间就加载完成了,同时您的JavaScript脚本仅被加载一次(带来了不错的、明显的速度提升)。
有必要说明:
- 如果在
<head>
里加载 InstantClick,您的JavaScript内容应该相同。 - 如果您的某些
<head>
里的内容会作用于网页(例如在页面加载时运行的脚本或 CSS 动画),则需要进行一些调整。
InstantClick 是渐进式增强:如果访问者的浏览器不支持 InstantClick,您网站的链接将照常工作,只是没有速度提升。
预加载
InstantClick 有不同的预加载选项,根据服务器的任意选择。
鼠标悬停(Default)
当访问者的鼠标悬停在一个链接上时,预加载就开始了。如果访问者有一个良好的网络环境并且您的页面不需要花费太长时间来加载,那么页面将可以立即显示出来。
只需按照 入门-开始-初始化 里的教程直接初始化 InstantClick即可。
按下鼠标
当访问者按下鼠标时预加载。这为您的服务器带来了近乎零的开销,并且仍然带来了“令人惊讶”的速度提升。
要使用,只需将 mousedown
作为参数传递给 InstantClick.init
例如:
InstantClick.init('mousedown');
折中方案
如果在您选择的延迟过后访问者仍然悬停在链接上,页面将开始预加载。
建议的延迟时间是100毫秒和50毫秒。超过 100 毫秒实际上可能比鼠标按下更糟;不到 50 毫秒可能不会被察觉,浪费服务器的资源。
要在延迟后预加载 InstantClick,请将延迟(以毫秒为单位)作为参数传递给InstantClick.init
例如:
InstantClick.init(50);
关于移动设备
无论使用这些选项中的任何一个,当访问者的手指触摸链接 (touchstart) 时就会开始预加载。
如果您的网站针对移动设备进行了优化(Android 上的设备宽度 viewport,iOS上使用 FastClick),则当访问者将手指从链接上松开时会发生“点击”,从而为预加载提供大约 100 毫秒的延迟。
如果您的网站未针对移动设备进行优化,则取决于操作系统。Android 为 300 毫秒,iOS 为 450 毫秒。
同一站点上的 3G 网速请求通常需要大约 200 毫秒。
选择哪一个
如果您的服务器能处理额外负载,建议在鼠标悬停时预加载。
如果您的网站不能或者会耗费太多的流量、请求,请使用按下鼠标来进行预加载。无论如何,您的网站仍将比 99% 的网站快。
如果您想确定您的服务器是否可以,请从按下鼠标这个方式开始,这因为这对您的服务器施加几乎为零的额外压力。然后再使用具有 100 毫秒延迟的鼠标悬停)。然后调整到 50 毫秒延迟(或者,如果您有耐心,可以进行更小毫秒数的增减)。最后甚至可以直接用鼠标悬停)。
如果服务器对于流量、请求数过于敏感,那么我们只建议您使用按下鼠标方案,因为使用其他任何预加载方式都会增大您的服务器开销。
黑名单
有些链接不需要使用 InstantClick 进行预加载,黑名单帮助您这样做。
什么是黑名单
什么适合加入黑名单:
- 动作性链接,例如 注销 和 切换语言 等等。
- 需要一段时间加载的非 HTML 内容的链接。
- 具有不同 CSS / JavaScript 的页面的链接
<head>
。 - 会被 JavaScript 操作的链接。
一些链接已经列入内部黑名单:
- 带有
target
或download
属性的链接。 - 具有不同域或协议的链接。
- 指向同一页面上的
#anchor
的链接。
将链接加入黑名单
要将链接加入黑名单,请为其添加data-no-instant
属性。
<a href="/blog/" data-no-instant>博客</A>
将一组链接加入黑名单
有时将一组链接加入黑名单可能更方便,而不是 data-no-instant
向所有链接添加属性。
要将父元素中的所有链接列入黑名单,请添加 data-no-instant
到该元素。
将一个链接或一组链接加入白名单
如果您已将父元素加入黑名单但又想将某一链接(或子父元素中的所有链接)列入白名单 data-instant
,请向该链接或子父元素添加属性。
原理是 InstantClick 遍历所有父元素,从当前链接到<html>
,如果它找到一个 data-no-instant
属性,它认为该链接会被列入黑名单并停止循环遍历父元素。如果找到 data-instant
,则认为该链接已列入白名单。
如果您想默认将所有链接列入黑名单,然后将链接一一列入白名单,或者仅将容器中的链接列入白名单,请在 <body>
中添加 data-no-instant
属性并在 container
/ 链接中添加 data-instant
属性。
内容和JavaScript的重新加载
InstantClick 在技术上使您的网站成为单页应用程序,所以不再有 DOMContentLoaded
对页面进行操作。因此,可能需要调整其他 JavaScript 才能与 InstantClick 一起正常工作。
InstantClick 触发四个事件来为页面的生命周期提供 Hook:
-
change
:页面已更改,也会在初始页面加载时触发。如果访问者的浏览器不支持 InstantClick,会替换成替换DOMContentLoaded
.它的回调函数使用一个可选的
isInitialLoad
参数,它是一个布尔值,当页面更改或者 InstantClick 不被支持时为true
,当 InstantClick 更改页面时为false
。 -
fetch
:页面开始预加载。 -
receive
: 页面已被预加载。您可以修改其内容)。 -
wait
:用户点击了一个链接,但页面尚未预加载。仅在页面未立即显示时才会触发。
要监听一个事件,例如 change
,使用 InstantClick.on
:
InstantClick.on('change', yourCallback);
例如:
//InstantClick配合Nprogress使用
InstantClick.on('click', function() {
NProgress.start();
})
InstantClick.on('change', function() {
NProgress.done()
});
InstantClick.init();
你需要在 InstantClick.init
之前调用 InstantClick.on
,因为更改事件在页面加载时触发,包括浏览器不支持 pushState 时。
如果在 <body>
中有一个 JavaScript,而您不希望在 InstantClick 显示一个页面时重新加载它,那么为它添加一个 data-no-instant
属性。
例如:
<script data-no-instant>alert("I’m only run once.");</script>
如果其他 JavaScript 与 InstantClick 冲突,建议为所有脚本添加一个 data-no-instant
属性,然后逐个删除每个的属性,直到找到罪魁祸首。
例如:
<script data-no-instant>
InstantClick.on('change', function(isInitialLoad) {
if (isInitialLoad === false) {
// 百度分享
window._bd_share_main.init()
// 百度统计
_hmt.push(['_trackPageview', location.pathname + location.search])
//MathJax
if (typeof MathJax !== 'undefined')
MathJax.Hub.Queue(["Typeset",MathJax.Hub]);
//google analytics
if (typeof ga !== 'undefined') // support google analytics
ga('send', 'pageview', location.pathname + location.search);
//google code prettify
if (typeof prettyPrint !== 'undefined') // support google code prettify
prettyPrint();
}
});
InstantClick.init();
</script>
在receive时更改内容
有时,动态页面的更改比 InstantClick 重新构建的后端更简单。receive
允许你这样做。
它得到三个参数:url
,body
和title
。
url
是接收到的页面的地址,它包括 Hash。它是只读的。
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
时,您有多个监听的回调函数,每个回调函数后续将获得最后更改的内容。
如果您不想更改 receive
的页面,请不要返回任何内容或返回false
。
进阶
检查CSS或Script变化
要检查 CSS 或 Script (外部或内联)是否更新,请添加 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>
如果是内联 Script 或 CSS,InstantClick 将检查内容的变化。
<style data-instant-track>
body {
background: midnightblue;
font: 13px Helvetica;
}
</style>
<script data-instant-track>
var timingStart = performance && performance.now();
</script>
当检测到任何更改时,InstantClick 将重新加载页面,从而使浏览器重新评估所有脚本和样式。
自定义进度条
进度条是一个虚假的进度条,只是为了让您的用户感觉到正在发生的事情。
当访问者放大页面或旋转他的设备时,大小和位置会自动调整,因此即使您的网站没有针对移动设备进行优化,它也能正常工作。
默认情况下,进度条的颜色是#29d
,您可以使用 CSS 更改它:
#instantclick-bar {
background: white;
}
你也可以让进度条消失:
#instantclick {
display: none;
}
其他
产品路线图
Dieulot 新作: instant.page
Github 链接: instant.page