【译】HTML5 prefetch

  1. 1. 有了浏览器缓存,为何还需要预加载?
  2. 2. Chrome 的预加载技术
  3. 3. DNS prefetch
  4. 4. Resource prefetch
  5. 5. Pre render
  6. 6. 不是所有的资源都可以预加载
  7. 7. 手动触发预渲染操作
  8. 8. 兼容性
  9. 9. 警告
    1. 9.0.1. 参考链接

声明:此文带着自己的理解,不完全按原文翻译,原文地址

prefetch 即预加载,在用户需要前我们就将所需的资源加载完毕。

有了浏览器缓存,为何还需要预加载?

  • 用户可能是第一次访问网站,此时还无缓存
  • 用户可能清空了缓存
  • 缓存可能已经过期,资源将重新加载
  • 用户访问的缓存文件可能不是最新的,需要重新加载

Chrome 的预加载技术

现在的 chrome 聪明到根据你的浏览记录,预测到你可能访问或搜索哪些网站,在你打开网站之前就加载好了一些资源了。
举个栗子,当你在搜索框输入 “amaz” 时,它猜测到你可能要访问 amazon.com,可能就帮你加载了这个网站的一些资源。
如果这个预测算法精准的话,就能大大地提高用户的浏览体验了。

DNS prefetch

我们知道,当我们访问一个网站如 www.amazon.com 时,需要将这个域名先转化为对应的 IP 地址,这是一个非常耗时的过程。

DNS prefetch 分析这个页面需要的资源所在的域名,浏览器空闲时提前将这些域名转化为 IP 地址,真正请求资源时就避免了上述这个过程的时间。

1
2
3
4
5
6
<meta http-equiv='x-dns-prefetch-control' content='on'>
<link rel='dns-prefetch' href='http://g-ecx.images-amazon.com'>
<link rel='dns-prefetch' href='http://z-ecx.images-amazon.com'>
<link rel='dns-prefetch' href='http://ecx.images-amazon.com'>
<link rel='dns-prefetch' href='http://completion.amazon.com'>
<link rel='dns-prefetch' href='http://fls-na.amazon.com'>

应用场景1:我们的资源存在在不同的 CDN 中,那提前声明好这些资源的域名,就可以节省请求发生时产生的域名解析的时间。
应用场景2:如果我们知道用户接下来的操作一定会发起一起资源的请求,那就可以将这个资源进行 DNS-Prefetch,加强用户体验。

Resource prefetch

在 Chrome 下,我们可以用 link标签声明特定文件的预加载:

1
2
3
4
<link rel='subresource' href='critical.js'>
<link rel='subresource' href='main.css'>
<link rel='prefetch' href='secondary.js'>

在 Firefox 中或用 meta 标签声明:

1
<meta http-equiv="Link" content="<critical.js>; rel=prefetch">

rel=’subresource’ 表示当前页面必须加载的资源,应该放到页面最顶端先加载,有最高的优先级。

rel=’prefetch’ 表示当 subresource 所有资源都加载完后,开始预加载这里指定的资源,有最低的优先级。

注意:只有可缓存的资源才进行预加载,否则浪费资源!

Pre render

前面说到的预解析DNS、预加载资源已经够强悍了有木有,可还有更厉害的预渲染(Pre-rendering)!

预渲染意味着我们提前加载好用户即将访问的下一个页面,否则进行预渲染这个页面将浪费资源,慎用!

1
<link rel='prerender' href='http://www.pagetoprerender.com'>

rel=’prerender’ 表示浏览器会帮我们渲染但隐藏指定的页面,一旦我们访问这个页面,则秒开了!

在 Firefox 中或用 rel=’next’ 来声明

1
<link rel="next" href="http://www.pagetoprerender.com">

不是所有的资源都可以预加载

当资源为以下列表中的资源时,将阻止预渲染操作:

  • URL 中包含下载资源
  • 页面中包含音频、视频
  • POST、PUT 和 DELETE 操作的 ajax 请求
  • HTTP 认证(Authentication)
  • HTTPS 页面
  • 含恶意软件的页面
  • 弹窗页面
  • 占用资源很多的页面
  • 打开了 chrome developer tools 开发工具

手动触发预渲染操作

在 head 中强势插入 link[rel=’prerender’] 即可:

1
2
3
4
var hint =document.createElement("link")
hint.setAttribute(“rel”,”prerender”)
hint.setAttribute(“href”,”next-page.html”)
document.getElementsByTagName(“head”)[0].appendChild(hint)

兼容性

这么好用的特性,当然要考虑各浏览器的兼容程度了(哭:

IE9 支持 DNS pre-fetching 但管它叫 prefetch。

IE10+ 中 dns-prefetch 和 prefetch 是等价的。

其他方面的测试,目前还没有很好的方案,暂且只能通过查看浏览器是否缓存来测试。

在 Chrome 中打开了 chrome developer tools 开发工具会阻止页面的预渲染,所以我们看不到这个过程,但可以在 chrome://cache/ 或 chrome://net-internals/#prerender 中查看。

Firefox 可以在 about:cache 中查看。

警告

这些特定还是实验性质的,将来可能改变。

权利越大,责任越大,不要滥用!

参考链接

HTML5移动开发方案探索

2013是移动互联爆发的一年,2014也肯定也是移动互联网的天下!

笨鸟先飞,小赖打算进入移动开发,先从HTML5移动应用开始,再连带学学IOS,希望2014会有更大的收获。

查阅资料后就开始!不过要做好被移动开发各种坑坑死的打算先 - -




三种开发方式的简单比较:

Native(原生):

丰富的用户体验 平台指向性
久经考验的移动应用开发途径
Hybrid(混合):
与应用类似的使用体验
利用设备自身功能 多平台支持能力
HTML 5:

更快的开发周期 跨平台运行
* 实时更新



Native开发方法在性能和设备访问方面很出色,但成本和更新方面有缺点。Web方法更新起来简单得多,成本较低,也更容易,但是目前功能有限,也无法获得使用Native API调用所能获得的那种出色的用户体验。Hybrid开发方法提供了折中方案:在许多情况下,它集两者之所长,如果开发者面向多种操作系统更是如此。

Hybrid是同时利用HTML 5与CSS3创建移动UI,同时又通过JavaScript代码实现与移动SDK之间的通信。



目前比较知名的hybrid框架有Phonegap:

PhoneGap为移动应用开发人员提供一套名为phonegap-3.0.0.js的JavaScript API。该JavaScript API会调用PhoneGap的特殊平台引擎/桥接机制,后者则反过来调用原生平台SDK以实现对设备的操作,例如访问联系人名单或者拨打电话等。


PhoneGap还提供一套与HTML 5、JavaScript以及CSS3在非Chrome浏览器(例如不提供用户界面的浏览器)中相绑定的创建系统。



.png)


phonegap提供了接口,使我们通过编写JS代码,调用原生的API。为了快速开发,一般还会搭配一个移动开发框架,常见的有jquery mobile、KendoUI Mobile、Sencha Touch等。

Jquery mobile 优点是比较容易上手,而且为了设计jQuery Mobile页面,提供了一套便捷的代码设计工具——也就是Codiqa。

缺点是应用的列表条目一旦达到五十到六十个,性能就会出现疲软(甚至直接导致移动浏览器崩溃)。在另一方面,Sencha Touch能够载入超过两百个条目,且不会引发任何性能问题。

KendoUI Mobile是一款基于MVVM的移动应用框架,附带图表及多款非常实用的移动工具,整体方案售价为699美元。即便它有非常好的表现,但比较昂贵,就暂且不考虑了。

Sencha Touch用极高的使用复杂性外加相当夸张的学习曲线换得无与伦比的性能表现。Sencha Touch属于MVC且完全采用JavaScript机制,但由于Sencha Touch最初只针对iOS平台,而后才添加了对Android、黑莓以及Windows Phone的支持能力,因此大家应该做好心理准备——其在各平台上的性能表现并不完全一致。


查阅资料后,小赖得出的方案是:使用Phonegap+jquery mobile 开发这个HTML5 Hybrid应用。

phonegap好在提供了跨平台的方案,坏在当应用复杂起来,性能是个问题;

jquery mobile 好在提供了一些UI,轻量且快速,坏在一旦DOM操作繁多,会造成性能问题。


Hybrid的优点在于用跨平台Web技术,开发应用程序的大部分代码,又可以在需要时直接访问Native API。

我的想法是,先按Hybrid的方案做出产品原型,然后再评估是否需要针对特定功能用NativeAPI来加强改善。


以上都是Ctrl C+V加自己的理解得出的初步方案,接着就需要去具体实践,得出自己真正的开发心得和新方案来了!


寒假继续加油!


参考链接:



phoneGap可行性分析) 这个写得非常棒









参考实例:












HTML5-WebSocket API 学习

  1. 1. 服务器端 编写serverfile.js文件,建立http服务器和socket连接:
  2. 2. 浏览器端 编写 webSocket.html ,建立与服务器的连接:
  3. 3. 浏览器对WebSocket的支持性

使用nodejs的socket.io和现代浏览器的WebSocket来建立一个聊天室。

服务器端 编写serverfile.js文件,建立http服务器和socket连接:

[javascript]
var http = require(‘http’);
var io = require(‘socket.io’);

// 创建一个服务器
var server = http.createServer(function(request, response){
response.writeHead(200, {‘Content-type’: ‘text/html’});
response.end(‘小赖的WebSocket服务器启动啦!’);
});
// 监听端口
server.listen(9999);

// 创建一个WebSocket
var socket = io.listen(server).set(‘log’, 1);

// 监听连接
server.on(‘connection’, function(client) {
// 监听信息
client.on(‘message’, function(data){
console.log(‘收到客户端发来信息:’, data);
var curTime = new Date().getTime();
client.emit(‘服务器返回信息:’, data + ‘->’ + curTime);

     client.on('disconnect', function(){
         console.log('连接已断开');
     });
 });

});
[/javascript]

创建http服务器,运行http服务器成功:

浏览器端 编写 webSocket.html ,建立与服务器的连接:

[html]
<!DOCTYPE html>
<html>
<head>
<title>WebSocket API</title>
<meta charset="utf-8">
<script src="<span style="text-decoration: underline;">http://localhost:9999/socket.io/socket.io.js</span>"></script&gt;
</head>
<body>
<div id="log">显示log信息…</div>
<input id="msg" type="text" placeholder="请输入信息" />
<button id="send-btn">发送!</button>

<script>
var myWebSocket = {};
myWebSocket.socketio = {
mysocket: null,
initialize: function(){
// 建立连接
myWebSocket.socketio.mysocket = io.connect(‘<span style="text-decoration: underline;">http://localhost:9999</span&gt;’);
// 监听连接
myWebSocket.socketio.mysocket.on(‘connect’, function(){
myWebSocket.socketio.log(‘成功连接到服务器\n’);
});
// 监听信息
myWebSocket.socketio.mysocket.on(‘message’, function(data){
myWebSocket.socketio.log(‘服务器返回数据:’ + data + ‘\n’);
});
// 监听断开连接
myWebSocket.socketio.mysocket.on(‘disconnect’, function(){
myWebSocket.socketio.log(‘已断开连接\n’);
})

         // 点击发送按钮
         document.querySelector('#send-btn').onclick = function(){
             // 发送信息到服务器
             var msg = document.querySelector('#msg').value;
             myWebSocket.socketio.sendMessageToServer(msg);
             document.querySelector('#msg').value = '';
         };
     },
     sendMessageToServer: function(data){
         myWebSocket.socketio.mysocket.secd(data);
         myWebSocket.socketio.log('已发送信息到服务器:' + data +'\n');
     },
     log: function(msg) {
         document.querySelector('#log').innerHTML += msg;
     }
 }

 myWebSocket.socketio.initialize();
 &lt;/script&gt;

</body>
</html>
[/html]

然后在浏览器打开这个网页,终端显示:

这样客户端和服务器就可以通信啦!

输入信息后,点击发送,终端显示:

浏览器则显示:

然后关闭服务器的话,则显示「已断开连接」:

实现广播功能,即一个客户端发送消息,所以和服务器建立了连接的其他客户端都能看到这个消息:
修改serverfile.js文件,注意有『修改』字眼的部分:

[javascript]
var http = require(‘http’);
var io = require(‘<span style="text-decoration: underline;">socket.io</span>’);

// 创建一个服务器
var server = http.createServer(function(request, response){
response.writeHead(200, {‘Content-type’: ‘text/html’});
response.end(‘小赖的WebSocket服务器启动啦!’);
});
// 监听端口
server.listen(9999);

// 创建一个WebSocket

var socket = io.listen(server).set(‘log’, 1);

// 监听连接
socket.on(‘connection’, function(client) {
// 修改:监听信息
client.on(‘customMessage’, function(data){
console.log(‘收到客户端发来信息:’, data);
var curTime = new Date().getTime();

     // 修改:使用广播方法
     client.broadcast.emit('服务器返回customMessage信息:', data + '广播-&gt;' + curTime);

     client.on('disconnect', function(){
         console.log('连接已断开');
     });
 });

});
[/javascript]

修改webSocket.html文件,注意有『修改』字眼的部分:

[html]
<!DOCTYPE html>
<html>
<head>
<title>WebSocket API</title>
<meta charset="utf-8">
<script src="<span style="text-decoration: underline;">http://localhost:9999/socket.io/socket.io.js</span>"></script&gt;
</head>
<body>
<div id="log">显示log信息…</div>
<input id="msg" type="text" placeholder="请输入信息" />
<button id="send-btn">发送!</button>

<script>
var myWebSocket = {};
myWebSocket.socketio = {
mysocket: null,
initialize: function(){
// 建立连接
myWebSocket.socketio.mysocket = io.connect(‘<span style="text-decoration: underline;">http://localhost:9999</span&gt;’);
// 监听连接
myWebSocket.socketio.mysocket.on(‘connect’, function(){
myWebSocket.socketio.log(‘成功连接到服务器<br />’);
});
//修改: 监听customMessage信息
myWebSocket.socketio.mysocket.on(‘broadcastMessage’, function(data){
myWebSocket.socketio.log(‘收到广播信息:’ + data + ‘<br />’);
});
// 监听断开连接
myWebSocket.socketio.mysocket.on(‘disconnect’, function(){
myWebSocket.socketio.log(‘已断开连接\n’);
})

         // 点击发送按钮
         document.querySelector('#send-btn').onclick = function(){
             // 发送信息到服务器
             var msg = document.querySelector('#msg').value;
             myWebSocket.socketio.sendMessageToServer(msg);
             document.querySelector('#msg').value = '';
         };
     },
     sendMessageToServer: function(data){
         // 修改
         myWebSocket.socketio.mysocket.emit('customMessage', data);
         myWebSocket.socketio.log('已发送信息到服务器:' + data +'&lt;br /&gt;');
     },
     log: function(msg) {
         document.querySelector('#log').innerHTML += msg;
     }
 }

 myWebSocket.socketio.initialize();
 &lt;/script&gt;

</body>
</html>
[/html]

然后用多个页面打开webSocket.html,在第一个页面输入消息:

点击发送,其他页面立即收到了消息:

在第二个页面输入信息:

在其他页面收到广播:


哇!WebSocket够强大,可以实现客户端和服务端的通信,而node的socket.io更是封装了它的一系列方法,实现一个web端通信就轻而易举了,但!是!HTML5的这个新特性,你敢用嘛?!

浏览器对WebSocket的支持性

在caniuse.com查询可知,WebSocket在IE10+和其他现代浏览器才支持,低版本的IE不支持WebSocket - -!

不过好消息是,socket.io对不支持WebSocket的浏览器启用了其他策略,使得socket.io甚至能在IE6下运行!

学好node后再回来拓展这个小小聊天室呗^_^
参考资料
参考资料
参考资料