2011年10月16日星期日

浏览器窗口标题栏闪烁通知

对于WebIM 对话或其它各种Comet应用场景,当收到新消息时,希望能够及时提醒用户。


但是用户
可能将窗口切换到计算机上其它窗口上了,比如看其它网页、聊一下QQ、收发一下邮件等各种其它事情,此时web窗口就不在用户焦点上了,收到的新消息时很可能看不到。而javascript控制的web窗口并不能很好融入到OS级别的窗口系统中。比较普遍的一种做法就是让浏览器标题栏不断闪烁,应用程序的标题闪烁是很容易被注意到的,不管是浏览器和其它各种程序之间,还是浏览器多tab或windows之间。这算是最接近OS级别窗口的提示方式了。


实现的目标:
  • 当对话窗口失去焦点(切换到其它程序或其它浏览器窗口),并且收到新消息时,标题栏闪烁。
  • 没有失去焦点时不闪烁提示。焦点重新回到窗口时,标题栏恢复正常不再闪烁。


一、标题栏的闪烁
要实现标题栏闪烁的效果很简单,只要让 title 的内容来回变化就可以。
比如每500ms,
document.title=“【您有新的消息】”
下次
document.title=“【      】”
这样来回变化就实现了闪烁效果。



二、浏览器窗口焦点的判断
根据目标的要求,首先要知道当前窗口激活状态。

注册window.onblur和window.onfocus函数来记录焦点变化,但是IE上的行为有差异,不能直接用,而应该用document.onfocusin和document.onfocusout。
关于window或Dom元素的focus焦点这方面的行为,各浏览器行为有差异,尤其IE的行为有很多bug。

//当前浏览器窗口是否处于焦点
var isWindowFocus = true;
function focusin() { isWindowFocus=true;}
function focusout() { isWindowFocus=false;}
//注册焦点变化监听器
if ("onfocusin" in document){//for IE 
    document.onfocusin = focusin;
    document.onfocusout = focusout;
} else {
    window.onblur = focusout;
    window.onfocus= focusin;
}



三、具体实现
使用方式:每当收到新消息时就调用 doFlashTitle 方法实现闪烁,调用者不做任何判断。
要求:
1.如果当前窗口失去焦点一直执行title闪烁,如果当前处于窗口焦点则什么也不做。
2.当窗口重新获得焦点时,停止闪烁(退出闪烁循环)。
3.多次调用,闪烁循环本身只应执行一次。也就是说闪烁函数只同时运行一个,否则多个同样的调用一起执行的话会导致标题闪动异常(快),消耗资源。

//实现标题闪动效果

var flashStep=0;  //交替变量
var flashTitleRun = false; //是否正在执行
var normalTitle = "正常显示的标题"; 
function flashTitle()  
{  
 //仅窗口不在焦点时闪烁title,回到焦点时停止闪烁并将title恢复正常
 if(isWindowFocus){//当前处于焦点
  document.title=normalTitle;
  flashTitleRun = false;
  return;//退出循环
 }
 
 flashTitleRun = true;
 flashStep++;  
 if (flashStep==3) {flashStep=1;}  
 if (flashStep==1) {document.title="【您有新的消息】";}  
 if (flashStep==2) {document.title="【      】";}  
 setTimeout("flashTitle()",500);  //循环
} 
//调用这个执行标题闪烁,而不是直接调用flashTitle,保证多次调用只会执行一次。
function doFlashTitle(){
 if(!flashTitleRun)//没有执行时,才执行
      flashTitle();
}


四、小结
title闪烁并不难,但跨浏览器的焦点判断的问题比较多,IE非常诡异。参考资料都是焦点判断方面的。
只能判断出窗口焦点是否激活,没有办法判断窗口对人是不是可见的。

在js中调用window.focus()方法,窗口到底会不会被激活是完全不可靠的。而在IE上执行此方法,不管窗口是否激活了,都会导致focus事件的触发,使得上述的判断方法认为已经获得焦点了,但其实没有。所以最好就不要再使用window或dom的focus方法,以免干扰判断。而非IE浏览器正常,只有窗口确实被激活了才触发focus事件。


参考资料:

hotmail前端优化

前两天(2011-7-1),有一篇hotmail前端优化的文章,使用户响应比以前快10倍,自己简单小结一下。原文地址:这里 。不过,只能说hotmail以前优化做得太少了,这些gmail老早就做了。(遗憾的是国内用户最近访问hotmail也不太顺畅)


现代浏览器越来越强大,可以把更多的工作从server端交给浏览器去做。更一般地说,C/S模型中,如果C越强大,就可以考虑把更多S的工作放到C中去完成。


缓存、预加载、异步操作。
优化的关键是找到平衡点。


缓存:
已加载的数据缓存住,不要每次都重新加载。
即使今天的美国,网络依然是瓶颈。所以数据离浏览器越近就越快。
如果数据不在浏览器,应该使用更加有效的方式获取。
浏览器中可以直接用DOM对象缓存,需要的时候直接切换过去。


缓存的平衡:
缓存何时需要更新,比如有新邮件时?server通知浏览器,然后浏览器获取数据。也就是,服务器推送通知。
退出hotmail时清掉缓存,保证隐私安全。当然,如果没有安全方面的问题,可以考虑缓存更长时间。


预加载:
如果内容已经有了,响应自然就是即时的。
预加载的数据类型:可以是数据,也可以是代码。

什么时候预加载什么?
原则上说应该预加载最有效的、命中率高的内容。而这要基于用户的行为特征,也就是通过用户(各阶段的)行为分析来决定。
比如:
  • 用户一上来一般会查看列表中新邮件标题,然后会选择查看他们,利用用户这个停顿的时机来预加载新邮件的内容。
  • 用户看这封邮件的内容很可能也会看挨着的下一封或上一封邮件的内容,所以可以预加载下一封邮件内容。
  • 用户看这封邮件的时候,下一步的行为可能是删除或回复,所以可以预加载好删除和回复的代码和数据(发送时需要有地址簿的数据)。

时机的技巧:利用人在操作的间歇预加载。人不是机器,人的行为是由一系列的动作组成,中间会有或长或短的间歇时间,就算对人而言是很短的间歇,对机器而言也是很长的间隔时间了。

为了效果更好,设计上也应该需要调整。

加载技巧:可以将下载的内容分成小块,并按一定的优先顺序下载,用户最需要的应该尽快可用。而不是一次加载太多的数据,那样可能造成不能及时响应。

考虑到巨大的用户量,前端应要防止server过载,保持服务有效 。另外,后台还要努力提升存储系统的吞吐率。

我顺便补充一下懒加载:
预加载和懒加载是两个相反的行为,但都是性能优化的手段,改善用户体验,具体看怎么用了。
预加载那些用户下一步马上需要的,如初次加载就包含,或在初次加载之后,利用用户的下一步行为的间歇时间提前加载。
而懒加载是先不加载那些用户不会马上用到的,或不常用到的部分,这样减少了加载内容。


异步操作:
没啥说的,界面立刻响应,任务在后台执行,而不是等待。

最后,性能是特性,优化无止境。

Macbook Pro 使用小记

本周(2011年5月)到手Macbook Pro,很激动。刚刚使用了几天,简单记下自己的感受。

Macbook Pro的硬件配置和做工真没得说,非常完美。
触控板很强大、很好用,鼠标可以基本不用了,但要稍微学习一下。
主要说说软件系统的差异。

鼠标右键功能使用较少,大部分功能设计使用单键就可以搞定。


Dock:
很多程序关闭按钮的行为不是退出,而是类似于最小化到dock中,需要Command+Q或菜单来退出。

Finder相当于资源浏览器,但是没有地址栏不太习惯。
命令行终端和linux差不多,特权命令也需要sudo执行。


widget小工具集也不错。


键盘与菜单:
快捷键不一样,大多需要Command键组合,很多组合习惯也不一样。
程序中“关于”菜单,是最左边的菜单中的第一项,而windows一般是最右边菜单的最后一项。
程序的菜单不是在应用程序上,而是统一在桌面顶部,切换程序菜单就跟着变。

Mac笔记本上的按键比标准键盘少很多。
F1-F12功能不一样,直接按就可以,不需要Fn,而一般笔记本相反,都需要Fn来使用功能。
键盘没有Home、End、PageUp、PageDown,需要 Fn+4个方向键 替代。
光标移到行首或行尾:command+左箭头或右箭头。
标准键盘右两个删除键:backspace(向左删)和Del(向右删),而Mac上只有一个delete键,作用和backspace键一样,如果想向右删需要用Fn+delete。
剪切、复制、粘贴、撤消:不是用Ctrl,而是Command组合。


窗口的关闭、最小化、最大化:
这三个按钮在窗口左上角,而windows是右上角。
关闭按钮也是反的,在三个按钮的最左边,而不是最右边。
最大化按钮很不一样,不是真的最大化,而是根据窗口内容的最合适大小(一般比最大化小很多),只能自己拖到更大的大小。小提示:chrome浏览器用 “shift+最大化” 可以真的最大化。

Cmd+X只能操作文本,不能操作文件或文件夹。必须用拖拽的方式实现:
拖动到其它目录就是剪切,或者Command+拖拽强制剪切到外部存储设备;
Option+拖拽是复制;Cmd+Option+拖拽是创建快捷方式。

windows上弹出的提示窗口一般出现在桌面右下角,而Mac是右上角。

文件系统方面:Mac可以读写Fat格式文件。注意:mac可以读ntfs格式的数据,但不能写ntfs(修改、删除、新建),比如使用ntfs格式的移动硬盘。

软件:Mac上有自己的App Store,没事可以进去看看,很多常用软件都有,但不是很全。

安装软件:安装包一般是一个dmg格式的文件,其实就是一个镜像。常见有两种安装方法:
  1. 带安装向导的,一路点下去即可。一般也提供了卸载程序。
  2. 直接将程序拖动到应用程序文件夹。删除也是从应用程序中拖到回收站。

Mac上自带了大量应用软件和实用工具,不介绍了,挺好玩的。
默认就有Java、Python、Ruby等语言支持,这对开发人员非常友好。
Mac自带的中文输入法不太好用,可以自己安装FIT输入法(和SunPinyin合作了),搜狗和QQ输入法也出了Mac版了。
MPlayerX播放器不错,可以播rmvb这种国内经常使用的格式。

我常用的软件:
  • 浏览器:Chrome、Firefox、Safari
  • 输入法:FIT输入法(SunPinyin)、搜狗输入法、QQ输入法
  • BT下载工具:Vuze
  • MPlayerX播放器
  • 编辑器:TextWrangler、jEdit、Bluefish、MacVim
  • Twitter for mac
  • 虚拟机:VirtualBox
  • Dropbox
  • The Unarchiver(7zip、rar解压)
  • QQ、MSN都有官方的Mac版,自带iChat就支持Gtalk
  • http://www.microsoft.com/mac/ 除了MSN,还有Mac版的远程桌面,方便访问Windows
  • chnroutes vpn路由


开发工具:

  • XCode,包括了unix常用工具gcc等,开发人员必备。已经免费了,自带系统光盘中有,也可以从App Store中下载。
  • Eclipse
  • 自带终端(Terminal),多种风格、保存书签等功能都有
  • 安装各种Linux开源软件的工具,MacPorts、Homebrew 和fink,推荐Homebrew
  • Mysql官方有Mac版,App Store有免费的Navicat for mysql Lite


文件名关联办法:右键-显示简介-打开方式(调整为希望的默认程序)-全部更改
注意:右键-打开方式-其它-总是以此方式打开,只对当前文件有效,不是都改。
技术上是和叫做Launch Service的系统服务有关。


Mac自带终端(Terminal),因为没有PageUp、PageDonw,查看man、less等命令时无法翻页,使用Fn或Command组合也不成。解决方法是用传统Unix的空格/b或ctrl+f和ctrl+b