毫秒点击延迟也成为了移动端网站让用户感觉卡顿的罪魁祸首之一』金沙网址

内部Hybrid App经验解读,hybridapp经验解读

郑昀编纂
关键词:Hybrid,Zepto,Fastclick,Backbone,sui,SPA,pushState,跨域,CORS


   内部做 Hybrid App 开发历程也不短了,杨海波、潘军和刘勤红与前端组、App
组一起总结了不少宝贵的经验教训,逐步形成我们自己的标准打法。下面选了几个经验点(坑)做进一步解读。
  0x00,click 事件还是 tap 事件? 如300 毫秒点击延迟的来龙去脉一文所言『尽管苹果公司创造的双击缩放行为,是一种在移动设备上访问桌面端站点的不错的解决方案,但随之引入的
300
毫秒点击延迟也成为了移动端网站让用户感觉卡顿的罪魁祸首之一』,此文把原因和对策讲得清楚透彻,此处郑昀不再赘述,感兴趣的同学自习一下。
  那么,我们看到,时至今日,有三种应对措施:  
但我们在实践过程中,也领教了著名的 Zepto tap 『点透』坑
对此,yexiaochai 分析道: 『 1,一旦引入 touch
库便会在全局绑定事件,每次点击皆会触发无意义的 tap 事件 ; 2,zepto
为了实现 doubleTap 等功能,2B 地在 touchend 上设置了一个
setTimeout,然后整个世界都充满了翔了。 由于 setTimeout
的抛出主干流程,导致其 event 参数失效,这个时候就算在 tap 事件函数中执行
e.preventDefault() 或者什么都是无效的,这是导致 zepto
tap“点透”的罪魁祸首。 』
点透的效果可以看  所述。总之,有人建议,如果你还打算继续用
Zepto,那么它的 tap 事件已经没用了,那你可以自己 build 一个无 touch
模块的 Zepto,以便减小文件大小并提高运行效率。 Fastclick 是怎么做的呢?
Fastclick 将事件绑定到你传入的元素 上,在 touchstart 和 touchend
后(会手动获取当前点击 el),如果是类 click 事件便手动触发 dom 元素的
click 事件。所以 click 事件在 touchend
便被触发,于是整个响应速度就起来了。这里虽然使用了 touch 事件,但 touch
事件是绑定到了具体 dom 而不是 document 上 ,所以 e.preventDefault
是有效的,我们可以阻止冒泡,也可以阻止浏览器默认事件。  
最终我们采用 Fastclick 的 click 事件来规避点击延迟响应。  
0x01,Zepto 的 show/hide 有时不靠谱 在 Hybrid App
开发初期,我们引入了 Zepto 的 fx_methods 模块,来控制元素的显示与隐藏:

fx_methods   Animated showhidetoggle, and fade*() methods.

金沙网址 1
但总是出现一些莫名奇妙的问题,如元素不能正常显示,元素的定位发生变化等,非常不好定位,最终前端同学发现是
Zepto 的 show/hide 造成的。 对此,我们可以找到 2012 年的一个 issue
佐证:

fx_methods show() and hide() add unnecessary CSS properties on non-animated DOM nodes
When you add fx_methods to your Zepto, the show() and hide() methods are overriden with methods that also call animate.  Even in the case of undefined speed (normal show), animate still adds many CSS properties to the shown/hidden nodes. These unexpected CSS rules can interfere with the page CSS (in my case, it has changed the positioning of my child fixed DIVs).

即,她认为,即使是简单的显示,fx_methods.js 的 show/hide
也会加入一些额外的
CSS,以至于影响整个页面样式,而且还会乱弹琴地改变透明度,重置为
1.0。samwu 在 2013 年也讲过类似问题。 所以,我们有两种选择:  
0x02,Android 下的跨域问题 在 Hyrbid App 里,郑昀要求采用
Template+Data=HTML 模式在手机客户端本地渲染出所需的页面。
Template(HTML5 模板文件+JS+CSS+Images)既可以提前打包到 App
安装包里,也可以从
CDN(如无,则溯源到静态文件服务器)拉到客户端里并存储在本地。 Data
则是通过模板文件里的 JavaScript 脚本,从远端拉取 JSON 格式的数据包。
那么,这里存在一个跨域问题:

Android 的 WebView 通过 file:// 协议加载本地的 HTML5
模板文件。本地文件的 JS 向远端发送 AJAX
请求,受到同源策略的限制,譬如你可能会看到“XMLHttpRequest cannot load
file://…… Origin null is not allowed by
Access-Control-Allow-Origin.”的错误提示,即当你的 URI 是 file://
时,源域名(origin)为空。

  • 借用 difcareer 的评论:Web 应用程序能且只能使用 XMLHttpRequest
    对象向其加载的源域名发起请求,而不能向任何其他域名发起请求,但 HTML5
    允许 AJAX 跨域向其他域名发起请求,但是不能获取服务器端响应。

iOS 下无此跨域问题。

  对此,大致有四种应对措施:

  • 如果是 GET 请求:
  • 如果是 POST 请求:

  我们是既会在 Native API 里封装了一个接口 sendpostmsg,让 JS
调用(但也因此导致『**
除了 POST 请求,其他都可以在 PC
浏览器调试』),也会使用 setAllowUniversalAccessFromFileURLs 方法。  0x03,pushState 调用失败也属于跨域问题 我们需要使用 HTML5 的特性
history.pushState,手动插入历史记录和修改地址栏,这样虽然地址栏被修改了,但并不触发网页跳转。
同上节,本地文件的 JS 调用 history.pushState
也会遇到跨域问题,报错如下图所示:
金沙网址 2
金沙网址 3
原因仍是当你的 URI 是 file:// 时,源域名(origin)为空。
由于我们使用了 SUI,绕不开这个问题。所以,最终还是得调用
webView.getSettings().setAllowUniversalAccessFromFileURLs(true);
彻底解决各种跨域问题。
  参考资源:* 1,2014,300 毫秒点击延迟的来龙去脉;
2,2015,freebuf,鸢尾,同源策略详解及绕过(Part1);
3,2015,知乎,纯数据 API 服务,设置 Access-Control-Allow-Origin: \

是否会有安全性隐患? 4,2012,csdn,CORS(跨域资源共享)简介;
5,2014,smdcn,使用HTML5 CORS特性进行Ajax跨域POST请求;
6,2011,sof,WebView Javascript cross domain from a local HTML file;
7,2014,龚广,WebView跨源攻击分析;
欢迎订阅我的微信订阅号『老兵笔记』,请扫描二维码关注:
金沙网址 4
转载时请注明“转载自旁观者-博客园”或者给出本文的原始链接。 -EOF-

App经验解读,hybridapp经验解读
郑昀编纂
关键词:Hybrid,Zepto,Fastclick,Backbone,sui,SPA,pushState,跨域,CORS
内部做 Hybrid App 开发…

相关文章