拔赤 & 完颜F2E of Taobao & eTao2012-07-07移动Web开发最佳实践
完颜F2E of eTaohttp://weibo.com/mario拔赤F2E of Taobaohttp://jayli.github.comWeb Developer & Translator
移动设备的演化2005 20081999
纠结的去学习 Objective-C
万维网www
万维网www
响应式设计小组• 平台选择• MediaQuery• 文字排版• 流体布局• 图片载入• Dom操作性能优化• 触屏事件•…http://wiki.ued.taobao.net/doku.php?id=ued.bj:f2e:rd
http://www.alistapart.com/articles/responsive-web-design
• 一套项目代码• 一套开发环境• 一个URL• 内容所见即所得• 不会因为终端升级而导致不可用• …响应式设计独特之处
3204807681024
偷懒的做法…一种偷懒的做法是:等比缩放但等比缩放后的页面文字像蚂蚁一样看不清楚
百分比宽度+ 浮动布局 容器.wrapper {width:100%;}.wrapper .item {float:left;}
960px520px 200px 200px20px 20px定宽布局
90%50% 20% 20%5% 5%流体布局
http://wiki.ued.taobao.net
http://taobao.7m.cn/
复杂的页面怎么办?
功能减法Fewer Features
样式2 样式3样式1更高分辨率的样式
http://wt.taobao.com
ViewPort Meta查看源码<meta name="viewport"content="width=device-width,initial-scale=1">
• width=device-width• user-scalable=1• initial-scale=1• maximum-scale=1• minimum-scale=1ViewPort Meta 参数
Visual viewport= Layout viewportLayoutviewport
ViewPort 参数最佳组合<meta name="viewport"content="width=device-width,initial-scale=1,maximum-scale=1"><meta name="viewport"cont...
ViewPort 参数最佳组合<meta name="viewport"content="width=device-width,initial-scale=1,maximum-scale=1"><meta name="viewport"cont...
/* PC宽屏样式 *//* iPad 及以下,所有小于(不等于)960宽度的平板电脑 */@media only screen and (max-width: 959px) {}/* 仅iPad 竖版,所有小于(不等于)960宽度的平板电脑的...
• 先写高分辨率样式• 先写低分辨率样式MediaQuery书写思路
• 先写高分辨率样式• 先写低分辨率样式MediaQuery书写思路哪种写法更适合?
• 先写高分辨率样式• 先写低分辨率样式MediaQuery书写思路
1,设计师设计原型往往首先基于宽屏甚至不会给出适配设计稿2,宽屏视觉元素更多,减法比加法容易原因?
http://www.getskeleton.comSkeleton CSSGrid System
字体样式定义body {font-family:tahoma,arial,5b8b4f53,sans-serif;}reset.csshtml {-webkit-text-size-adjust: 100%;}
iOS:华文细黑 + HelveticaAndroid:文泉驿微米黑 + Droid Sans
响应式图片有两种基本的图片类型需要考虑1,需要缩放的图片2,不能缩放的图片1. 2.
http://www.flickr.com/photos/zhangsj/6126931247/
HighRes.png
HighRes.pngLowRes.png
<style>.selector-to-img{width:100px;height:100px;background:url(img-pc.png„) no-repeat center;}@media only screen and /*ta...
这样做需要2个条件1,服务器上提供多尺寸图片淘宝传图工具可以自动生成多尺寸图片2,要有心理准备污染html代码Pic_sum.jpgPic_m.jpgPic_b.jpgPic_80x40.jpgPic_120x120.jpgPic_160x16...
图片的剪裁http://jayli.github.com/gallery/rd/responsive.html
同一张图,不同的定位http://jayli.github.com/gallery/rd/responsive.html
.pic {background-image:url("url.png");width:30px;height:30px;}@media only screen and /*tablet or mobile*/ {.pic {width:20p...
设备适配只能在前端完成?
RESSResponsive Design + Server Side Componentshttp://www.slideshare.net/4nd3rsen/ress-responsive-design-server-side-compon...
ServerSideClientSide@media only screen and /*设备1条件*/ {/* 设备1样式*/}@media only screen and /*设备2条件*/ {/* 设备2样式*/}@media only ...
ServerSideClientSideif($Device1){//设备1样式echo $style1;}else if($Device2){//设备2样式echo $style2;}else if($Device3){//设备3样式echo...
如果抛开“兼容性”?针对单一设备做更极致的用户体验
http://caipiao.m.taobao.com
<!doctype html><html manifest="http://www.../pad-sport-cache.php"><head><!—ViewPortMeta设置,禁止手动缩放--><meta name="viewport" c...
<!doctype html><html manifest="http://www.../pad-sport-cache.php"><head><!—ViewPortMeta设置,禁止手动缩放--><meta name="viewport" c...
<!doctype html><html manifest="http://www.../pad-sport-cache.php"><head><!—ViewPortMeta设置,禁止手动缩放--><meta name="viewport" c...
<!doctype html><html manifest="http://www.../pad-sport-cache.php"><head><!—ViewPortMeta设置,禁止手动缩放--><meta name="viewport" c...
<!doctype html><html manifest="http://www.../pad-sport-cache.php"><head><!—ViewPortMeta设置,禁止手动缩放--><meta name="viewport" c...
<!doctype html><html manifest="http://www.../pad-sport-cache.php"><head><!—ViewPortMeta设置,禁止手动缩放--><meta name="viewport" c...
http://www.taobao.com/go/chn/minfo/index.html
多了几个新属性查看源码<meta name="apple-mobile-web-app-capable"content="yes"><meta name="apple-mobile-web-app-status-bar-style"conten...
多了几个新属性查看源码<meta name="apple-mobile-web-app-capable"content="yes"><meta name="apple-mobile-web-app-status-bar-style"conten...
多了几个新属性查看源码<meta name="apple-mobile-web-app-capable"content="yes"><meta name="apple-mobile-web-app-status-bar-style"conten...
多了几个新属性查看源码<meta name="apple-mobile-web-app-capable"content="yes"><meta name="apple-mobile-web-app-status-bar-style"conten...
多了几个新属性查看源码<meta name="apple-mobile-web-app-capable"content="yes"><meta name="apple-mobile-web-app-status-bar-style"conten...
将网页添加至主屏可以将网页App添加至桌面,通过桌面图标打开Apphttp://caipiao.m.taobao.com
添加到主屏的iconapple-touch-icon-precomposedapple-touch-iconicon原图添加到桌面时有圆角/高光修饰只处理圆角,没有高光修饰
各自的显示效果apple-touch-icon-precomposedapple-touch-icon
终端事件的渐进增强淘宝使用最多的Slide/Switchable让他们支持touch事件触屏事件不要用’click’代替
http://jayli.github.com/gallery/yuislide/YUI Slide
if (ontouchstart in document.documentElement) {node.delegate(touchstart„, function(e){var x = e.changedTouches[0].clientX;...
if (ontouchstart in document.documentElement) {node.delegate(touchstart„, function(e){var x = e.changedTouches[0].clientX;...
if (ontouchstart in document.documentElement) {node.delegate(touchstart„, function(e){var x = e.changedTouches[0].clientX;...
空间位移事件if(window.DeviceMotionEvent) {window.addEventListener(devicemotion,function(e){var acceleration = e.accelerationIncl...
HTML5 和 Native App 如何对接?
HTML5 和 Native App 如何对接?1,Web App 服务可以适时更新Native App软件更新需要重新安装 ?2,Web App 开发周期相对较短Native App和Web App之间的分工?
PhoneGap 提供了一些思路http://phonegap.com/将HTML5 App打成安装包,但包升级时无法自动更新
HTML5 App + NativeAppHTML5快速开发原型+打包至NativeApp框架中
HTML5 App + NativeAppFar More than PhoneGap…Native AppHTML5 App
移动Web中的性能问题!
型号 CPU RAMiOSiPhone 4S 双核A5 800MHZ 512MiPhone 4 A4 800MHZ 512MiPhone 3GS S5PC100 600MHZ 256MAndroidGlaxy Note Exynos 双核 1....
iPhone4S29%iPhone466%iPhone3GS5%1GHZ以上45%800MHZ24%600MHZ19%其他12%iPhone硬件分布手机淘宝2012-4月数据Andoid硬件分布(CPU)
版本 渲染引擎 JS引擎iOSiOS 4.3+ Web Core Nitro *Older iOS Web Core JavaScript CoreAndroidAndroid 2.2+ Web Core V8Older Android Web...
iOS 5.1iOS 5.0iOS 4.3iOS 4.2iOS 4.1Android 4.0Android 2.3Android 2.2Android 3.0手机淘宝2012-4月数据iOS版本分布 Android版本分布
1,低端设备众多2,系统分配给浏览器的资源有限http://is.gd/hApzIp3,简化的浏览器实现4,不少老旧引擎5,需要高性能支持的HTML5 OPOASo,问题是…
1,性能问题会被放大数倍2,很容易造成体验瓶颈然而,事实却更加严峻…和PC平台相比
Web App 的性能优化1. 处理性能(CPU & RAM)• Reflow & Repaint• CSS3的性能问题• 动画• JS中的内存控制和技巧• 关于电量2. 网络性能 (Network)
需要优化的两个核心1. 减少内存中存储的内容2. 减少CPU的实时运算消耗
http://www.stubbornella.org/content/2009/03/27/reflows-repaints-css-performance-making-your-javascript-slowhttp://www-arch...
减少Reflow & Repaint1. off-document 避免直接操作DOM2. 一次性修改样式3. 让Dom脱离文档流4. 减少Dom数量和深度5. Dom复用
减少Reflow & Repaint1. off-document 避免直接操作DOM2. 一次性修改样式3. 让Dom脱离文档流4. 减少Dom数量和深度5. Dom复用
减少Reflow & Repaint1. off-document 避免直接操作DOM2. 一次性修改样式3. 让Dom脱离文档流4. 减少Dom数量和深度5. Dom复用
var fragment = document.createDocumentFragment(),list = [„foo‟,‟bar‟,‟baz‟],elem,contents;for (var i = 0; i<list.length; i...
var fragment = document.createDocumentFragment(),list = [„foo‟,‟bar‟,‟baz‟],elem,contents;for (var i = 0; i<list.length; i...
1.off-document:节点克隆var tmpnode = document.getElementById(„container‟),clone = tmpnode.cloneNode(true),list = [„foo‟,‟bar‟,...
1.off-document:节点克隆var tmpnode = document.getElementById(„container‟),clone = tmpnode.cloneNode(true),list = [„foo‟,‟bar‟,...
off-document:block-none-blockvar subElem = document.create(„div‟),elem = document.getElementById(„animated‟);elem.style.di...
off-document:block-none-blockvar subElem = document.create(„div‟),elem = document.getElementById(„animated‟);elem.style.di...
2.一次性修改样式<style type=“text/css”>div { background:white; color:black; }div.active { background:blue; color:white; }</style>...
3.让元素脱离文档流.selector1 {position:absolute;}.selector2 {position:fixed;}
4.减少Dom数量和深度瓶颈1:节点reflow,子元素/后续元素都会reflow瓶颈2:DOM尺寸会减慢所有操作
5.DOM复用建立Dom复用池,避免频繁创建和销毁;使用前端模板
CSS3 性能问题!http://simonjonsson.com/dev/css3-performance-testhttp://www.pubnub.com/blog/css3-performance-optimizations
• 大字体• Box shadow• Text indent• Gradients• Background-size• Translate3D & GPU硬件加速性能杀手过度的使用会增加CPU负载加上reflow和repaint,性能负担加倍h...
1. 为什么移动浏览器滚动时动画会停止?!2. 为什么我的iScroll这么卡?!综合以上,思考一下:
http://fav.m.taobao.com/h5proxy-fav.htm
iScroll的性能瓶颈iScroll滚动与原生滚动的性能比较render(reflow+repaint)和script损耗激增http://fav.m.taobao.com/h5proxy-fav.htm
iScroll的性能瓶颈空闲时iScroll的CPU损耗不高http://fav.m.taobao.com/h5proxy-fav.htm
iScroll的性能瓶颈Scroll发生时,CPU急剧飙高http://fav.m.taobao.com/h5proxy-fav.htm
http://cubiq.org/iscroll-4iScroll.js
CSS3 动画性能
动画实现的原理:1, left/top 传统绝对定位计算2, CSS3 Transform 2d3, CSS3 Transform 3d动画的组织方式:1, JavaScript (setInterval) 传统组织2, CSS3 Transi...
传统的动画实现<div id=“Test”>矩形动画,位移300px</div><script>var el = $(„#Test‟), i = 0;var s = setTimeout(function(){i += 1;el.css(‘to...
传统的动画实现<div id=“Test”>矩形动画,位移300px</div><script>var el = $(„#Test‟), i = 0;var s = setTimeout(function(){i += 1;el.css(-we...
传统的动画实现<div id=“Test”>矩形动画,位移300px</div><script>var el = $(„#Test‟), i = 0;var s = setTimeout(function(){i += 1;el.css(‘-w...
CSS3 Anim 关键帧组织.run {-webkit-transform:translate3d(0,300px,0);-webkit-animation-duration: .4s;-webkit-animation-iteration-...
CSS3 Anim 关键帧组织.run {-webkit-transform:translate3d(0,300px,0);-webkit-animation-duration: .4s;-webkit-animation-iteration-...
CSS3 Anim 关键帧组织.run {-webkit-transform:translate3d(0,300px,0);-webkit-animation-duration: .4s;-webkit-animation-iteration-...
CSS3 Transition 动态补间.test {top:0;-webkit-transition-property:top;-webkit-transition-duration:.4s;-webkit-transition-timing...
CSS3 Transition 动态补间.test {top:0;-webkit-transition-property:top;-webkit-transition-duration:.4s;-webkit-transition-timing...
CSS3 Transition 动态补间.test {top:0;-webkit-transition-property:top;-webkit-transition-duration:.4s;-webkit-transition-timing...
iOS AndroidTime(ms) smooth Time(ms) smoothJavaScriptabsolute 1400+ N 1000+ NtranslateY 1400+ N 1000+ Ytranslate3D 690 Y 10...
iOS AndroidTime(ms) smooth Time(ms) smoothJavaScriptabsolute 1400+ N 1000+ NtranslateY 1400+ N 1000+ Ytranslate3D 690 Y 10...
iOS AndroidTime(ms) smooth Time(ms) smoothJavaScriptabsolute 1400+ N 1000+ NtranslateY 1400+ N 1000+ Ytranslate3D 690 Y 10...
iOS AndroidTime(ms) smooth Time(ms) smoothJavaScriptabsolute 1400+ N 1000+ NtranslateY 1400+ N 1000+ Ytranslate3D 690 Y 10...
Why?Transform-Translate3dGPU硬件加速性能强劲,金枪不倒http://www.slideshare.net/lijing00333/graphic-programming-in-js
JS code…JS解释器(JS引擎)浏览器内核(渲染引擎)X windowOS kernel硬件CPU消耗在层层调用中setInterval(anim,10);CPUGPUGPU空闲
JS code…JS解释器(JS引擎)浏览器内核(渲染引擎)X windowOS kernel硬件CSS3 TransitionWebGL APICSS3 transition普通样式动画CSS3 transitiontransform动画
JS code…JS解释器(JS引擎)浏览器内核(渲染引擎)X windowOS kernel硬件CPU计算纹理 GPU渲染纹理CSS3 TransitionWebGL APICSS3 transition普通样式动画CSS3 transiti...
BrowserCPUGPUMemory发送指令结果返回给浏览器http://zh.wikipedia.org/wiki/纹理映射GPU 加速过程http://www.khronos.org/webgl/
http://m.taobao.com/
1.创建纹理并发送数据的过程很慢但GPU处理3D动画很快2.Mobile Safari默认创建1个纹理大小不超过1024x10243.创建的纹理生命周期仅在动画过程中存在,动画结束即刻销毁4.创建或销毁纹理过程中,可能会出现闪屏(BUG)需要留...
解决方案http://ued.taobao.com/blog/2012/01/06/Chrome渲染Transition时页面闪动Bughttp://jsfiddle.net/besteric/NrAYy/embedded/result%2Cc...
JavaScript中的内存控制• 闭包导致循环引用• 闭包导致过长的调用链• 使用事件代理• 低效的Dom选择器• 减少Dom遍历范围和次数• 事件节流• …http://www.nczonline.net/blog/2009/01/13/s...
• JPEG最省电(JPEG > PNG > GIF)• 图片数量越大,尺寸越大,越耗电• Ajax等动态JS增加电量消耗• 加载不必要的资源导致电量浪费(JS库)• Reflow和repaint耗电• WebGL(Translate3D)耗电...
• 处理性能优化的核心是CPU和内存• 尽力去减少Reflow和repaint吧• 合理使用GPU加速动画渲染• 不要过分信任和滥用CSS3• 更高效的JavaScript小技巧• 性能越好,耗电越少• 你有更好更聪明的方案• 影响和驱动设计•...
古老的编程技术 vs 新式设备
扩展阅读http://blog.cloudfour.com/css-media-query-for-mobile-is-fools-gold/
• Chrome Developer Tools• Mobile Perf bookmarklet• Firebug Lite / Page Resources / DOM Monster / SpriteMe / CSSess /Zoompf...
另辟蹊径从策略的角度,另一些解决方案
服务端白名单过滤前端辅助检测生成HEM标识Module AModuleBModule DModuleCV8检测 特性检测Web App模块化版本控制方案http://stackoverflow.com/questions/6768474/how...
http://engineering.linkedin.com/linkedin-ipad-5-techniques-smooth-infinite-scrolling-html5Current Viewplaceholderfake-src ...
前端API层前端传统嗅探网络适配库navigator.connection Window.performance补充方案高清图切换 等Offline/2G/3G/WIFI高/中/低“网络状况嗅探”方案Android 2.2+ Android 4...
《手机淘宝HTML5 Web App项目最佳实践》更多实践详情请关注7月8日 TaoMobile 无线技术专场玄寂/左使/不台
《淘宝彩票移动项目开发实践》更多移动Web OPOA 项目实践请关注7月28日 D2沙龙(北京场)函谷
Thanks栋寒/完真/地极/虎牙/灵玉/流火/函谷人马/夏之玄寂/曹纯/渚薰/张军/师影/弈天/神勋
http://www.flickr.com/photos/wintan29/3641254652/http://www.flickr.com/photos/samuel-leo/3550983108/sizes/s/in/photostream...
完颜F2E of eTaohttp://weibo.com/mario拔赤F2E of Taobaohttp://jayli.github.comWeb Developer & Translator
淘宝移动端Web开发实践
淘宝移动端Web开发实践
淘宝移动端Web开发实践
淘宝移动端Web开发实践
淘宝移动端Web开发实践
淘宝移动端Web开发实践
淘宝移动端Web开发实践
Upcoming SlideShare
Loading in...5
×

淘宝移动端Web开发实践

1,220

Published on

Published in: Technology, Art & Photos
0 Comments
4 Likes
Statistics
Notes
  • Be the first to comment

No Downloads
Views
Total Views
1,220
On Slideshare
0
From Embeds
0
Number of Embeds
0
Actions
Shares
0
Downloads
34
Comments
0
Likes
4
Embeds 0
No embeds

No notes for slide

淘宝移动端Web开发实践

  1. 1. 拔赤 & 完颜F2E of Taobao & eTao2012-07-07移动Web开发最佳实践
  2. 2. 完颜F2E of eTaohttp://weibo.com/mario拔赤F2E of Taobaohttp://jayli.github.comWeb Developer & Translator
  3. 3. 移动设备的演化2005 20081999
  4. 4. 纠结的去学习 Objective-C
  5. 5. 万维网www
  6. 6. 万维网www
  7. 7. 响应式设计小组• 平台选择• MediaQuery• 文字排版• 流体布局• 图片载入• Dom操作性能优化• 触屏事件•…http://wiki.ued.taobao.net/doku.php?id=ued.bj:f2e:rd
  8. 8. http://www.alistapart.com/articles/responsive-web-design
  9. 9. • 一套项目代码• 一套开发环境• 一个URL• 内容所见即所得• 不会因为终端升级而导致不可用• …响应式设计独特之处
  10. 10. 3204807681024
  11. 11. 偷懒的做法…一种偷懒的做法是:等比缩放但等比缩放后的页面文字像蚂蚁一样看不清楚
  12. 12. 百分比宽度+ 浮动布局 容器.wrapper {width:100%;}.wrapper .item {float:left;}
  13. 13. 960px520px 200px 200px20px 20px定宽布局
  14. 14. 90%50% 20% 20%5% 5%流体布局
  15. 15. http://wiki.ued.taobao.net
  16. 16. http://taobao.7m.cn/
  17. 17. 复杂的页面怎么办?
  18. 18. 功能减法Fewer Features
  19. 19. 样式2 样式3样式1更高分辨率的样式
  20. 20. http://wt.taobao.com
  21. 21. ViewPort Meta查看源码<meta name="viewport"content="width=device-width,initial-scale=1">
  22. 22. • width=device-width• user-scalable=1• initial-scale=1• maximum-scale=1• minimum-scale=1ViewPort Meta 参数
  23. 23. Visual viewport= Layout viewportLayoutviewport
  24. 24. ViewPort 参数最佳组合<meta name="viewport"content="width=device-width,initial-scale=1,maximum-scale=1"><meta name="viewport"content="width=device-width,initial-scale=1">
  25. 25. ViewPort 参数最佳组合<meta name="viewport"content="width=device-width,initial-scale=1,maximum-scale=1"><meta name="viewport"content="width=device-width,initial-scale=1">
  26. 26. /* PC宽屏样式 *//* iPad 及以下,所有小于(不等于)960宽度的平板电脑 */@media only screen and (max-width: 959px) {}/* 仅iPad 竖版,所有小于(不等于)960宽度的平板电脑的竖版 */@media only screen and (min-width: 768px) and (max-width: 959px) {}/* iPhone 及以下 */@media only screen and (max-width: 767px) {}/* 仅iPhone 横版,包括某些平板电脑的竖版 */@media only screen and (min-width: 480px) and (max-width: 767px) {}/* 仅iphone4 竖版 */@media only screen and (max-width: 479px) {}Media Query CSS
  27. 27. • 先写高分辨率样式• 先写低分辨率样式MediaQuery书写思路
  28. 28. • 先写高分辨率样式• 先写低分辨率样式MediaQuery书写思路哪种写法更适合?
  29. 29. • 先写高分辨率样式• 先写低分辨率样式MediaQuery书写思路
  30. 30. 1,设计师设计原型往往首先基于宽屏甚至不会给出适配设计稿2,宽屏视觉元素更多,减法比加法容易原因?
  31. 31. http://www.getskeleton.comSkeleton CSSGrid System
  32. 32. 字体样式定义body {font-family:tahoma,arial,5b8b4f53,sans-serif;}reset.csshtml {-webkit-text-size-adjust: 100%;}
  33. 33. iOS:华文细黑 + HelveticaAndroid:文泉驿微米黑 + Droid Sans
  34. 34. 响应式图片有两种基本的图片类型需要考虑1,需要缩放的图片2,不能缩放的图片1. 2.
  35. 35. http://www.flickr.com/photos/zhangsj/6126931247/
  36. 36. HighRes.png
  37. 37. HighRes.pngLowRes.png
  38. 38. <style>.selector-to-img{width:100px;height:100px;background:url(img-pc.png„) no-repeat center;}@media only screen and /*tablet*/ {background:url(img-tablet.png) no-repeat center;}@media only screen and /*mobile*/ {background:url(img-mobile.png) no-repeat center;}</style><img src="space.gif" class="selector-to-img" />
  39. 39. 这样做需要2个条件1,服务器上提供多尺寸图片淘宝传图工具可以自动生成多尺寸图片2,要有心理准备污染html代码Pic_sum.jpgPic_m.jpgPic_b.jpgPic_80x40.jpgPic_120x120.jpgPic_160x160.jpg…} 服务器自动生成25种尺寸
  40. 40. 图片的剪裁http://jayli.github.com/gallery/rd/responsive.html
  41. 41. 同一张图,不同的定位http://jayli.github.com/gallery/rd/responsive.html
  42. 42. .pic {background-image:url("url.png");width:30px;height:30px;}@media only screen and /*tablet or mobile*/ {.pic {width:20px;height:20px;background-position:x y;}}<img src="space.gif" class="pic" />
  43. 43. 设备适配只能在前端完成?
  44. 44. RESSResponsive Design + Server Side Componentshttp://www.slideshare.net/4nd3rsen/ress-responsive-design-server-side-components-10084972服务器端实现的“响应式”
  45. 45. ServerSideClientSide@media only screen and /*设备1条件*/ {/* 设备1样式*/}@media only screen and /*设备2条件*/ {/* 设备2样式*/}@media only screen and /*设备3条件*/ {/* 设备3样式*/}
  46. 46. ServerSideClientSideif($Device1){//设备1样式echo $style1;}else if($Device2){//设备2样式echo $style2;}else if($Device3){//设备3样式echo $style3;}
  47. 47. 如果抛开“兼容性”?针对单一设备做更极致的用户体验
  48. 48. http://caipiao.m.taobao.com
  49. 49. <!doctype html><html manifest="http://www.../pad-sport-cache.php"><head><!—ViewPortMeta设置,禁止手动缩放--><meta name="viewport" content="width=device-width,initial-scale=1,maximum-scale=1"><!--屏蔽拨号链接--><meta name="format-detection" content="telephone=no" /><!--隐藏浏览器导航栏--><meta name="apple-mobile-web-app-capable" content="yes" /><link rel="apple-touch-icon"sizes="72x72"href="http://cdn/img-72-72.png" /></head>…
  50. 50. <!doctype html><html manifest="http://www.../pad-sport-cache.php"><head><!—ViewPortMeta设置,禁止手动缩放--><meta name="viewport" content="width=device-width,initial-scale=1,maximum-scale=1"><!--屏蔽拨号链接--><meta name="format-detection" content="telephone=no" /><!--隐藏浏览器导航栏--><meta name="apple-mobile-web-app-capable" content="yes" /><link rel="apple-touch-icon"sizes="72x72"href="http://cdn/img-72-72.png" /></head>…
  51. 51. <!doctype html><html manifest="http://www.../pad-sport-cache.php"><head><!—ViewPortMeta设置,禁止手动缩放--><meta name="viewport" content="width=device-width,initial-scale=1,maximum-scale=1"><!--屏蔽拨号链接--><meta name="format-detection" content="telephone=no" /><!--隐藏浏览器导航栏--><meta name="apple-mobile-web-app-capable" content="yes" /><link rel="apple-touch-icon"sizes="72x72"href="http://cdn/img-72-72.png" /></head>…
  52. 52. <!doctype html><html manifest="http://www.../pad-sport-cache.php"><head><!—ViewPortMeta设置,禁止手动缩放--><meta name="viewport" content="width=device-width,initial-scale=1,maximum-scale=1"><!--屏蔽拨号链接--><meta name="format-detection" content="telephone=no" /><!--隐藏浏览器导航栏--><meta name="apple-mobile-web-app-capable" content="yes" /><link rel="apple-touch-icon"sizes="72x72"href="http://cdn/img-72-72.png" /></head>…
  53. 53. <!doctype html><html manifest="http://www.../pad-sport-cache.php"><head><!—ViewPortMeta设置,禁止手动缩放--><meta name="viewport" content="width=device-width,initial-scale=1,maximum-scale=1"><!--屏蔽拨号链接--><meta name="format-detection" content="telephone=no" /><!--隐藏浏览器导航栏--><meta name="apple-mobile-web-app-capable" content="yes" /><link rel="apple-touch-icon"sizes="72x72"href="http://cdn/img-72-72.png" /></head>…
  54. 54. <!doctype html><html manifest="http://www.../pad-sport-cache.php"><head><!—ViewPortMeta设置,禁止手动缩放--><meta name="viewport" content="width=device-width,initial-scale=1,maximum-scale=1"><!--屏蔽拨号链接--><meta name="format-detection" content="telephone=no" /><!--隐藏浏览器导航栏--><meta name="apple-mobile-web-app-capable" content="yes" /><link rel="apple-touch-icon"sizes="72x72"href="http://cdn/img-72-72.png" /></head>…
  55. 55. http://www.taobao.com/go/chn/minfo/index.html
  56. 56. 多了几个新属性查看源码<meta name="apple-mobile-web-app-capable"content="yes"><meta name="apple-mobile-web-app-status-bar-style"content="black" /><!--不自动将地址和email转为链接--><meta name="format-detection"content="address=no;email=no" /><!--添加到主屏时的图标--><link rel="apple-touch-icon-precomposed"href="http://cdn/img-114-114.png"><link rel="apple-touch-startup-image"href="http://cdn/img-320-460.png">
  57. 57. 多了几个新属性查看源码<meta name="apple-mobile-web-app-capable"content="yes"><meta name="apple-mobile-web-app-status-bar-style"content="black" /><!--不自动将地址和email转为链接--><meta name="format-detection"content="address=no;email=no" /><!--添加到主屏时的图标--><link rel="apple-touch-icon-precomposed"href="http://cdn/img-114-114.png"><link rel="apple-touch-startup-image"href="http://cdn/img-320-460.png">
  58. 58. 多了几个新属性查看源码<meta name="apple-mobile-web-app-capable"content="yes"><meta name="apple-mobile-web-app-status-bar-style"content="black" /><!--不自动将地址和email转为链接--><meta name="format-detection"content="address=no;email=no" /><!--添加到主屏时的图标--><link rel="apple-touch-icon-precomposed"href="http://cdn/img-114-114.png"><link rel="apple-touch-startup-image"href="http://cdn/img-320-460.png">
  59. 59. 多了几个新属性查看源码<meta name="apple-mobile-web-app-capable"content="yes"><meta name="apple-mobile-web-app-status-bar-style"content="black" /><!--不自动将地址和email转为链接--><meta name="format-detection"content="address=no;email=no" /><!--添加到主屏时的图标--><link rel="apple-touch-icon-precomposed"href="http://cdn/img-114-114.png"><link rel="apple-touch-startup-image"href="http://cdn/img-320-460.png">
  60. 60. 多了几个新属性查看源码<meta name="apple-mobile-web-app-capable"content="yes"><meta name="apple-mobile-web-app-status-bar-style"content="black" /><!--不自动将地址和email转为链接--><meta name="format-detection"content="address=no;email=no" /><!--添加到主屏时的图标--><link rel="apple-touch-icon-precomposed"href="http://cdn/img-114-114.png"><link rel="apple-touch-startup-image"href="http://cdn/img-320-460.png">
  61. 61. 将网页添加至主屏可以将网页App添加至桌面,通过桌面图标打开Apphttp://caipiao.m.taobao.com
  62. 62. 添加到主屏的iconapple-touch-icon-precomposedapple-touch-iconicon原图添加到桌面时有圆角/高光修饰只处理圆角,没有高光修饰
  63. 63. 各自的显示效果apple-touch-icon-precomposedapple-touch-icon
  64. 64. 终端事件的渐进增强淘宝使用最多的Slide/Switchable让他们支持touch事件触屏事件不要用’click’代替
  65. 65. http://jayli.github.com/gallery/yuislide/YUI Slide
  66. 66. if (ontouchstart in document.documentElement) {node.delegate(touchstart„, function(e){var x = e.changedTouches[0].clientX;//…});node.delegate(touchend„, function(e){var x = e.changedTouches[0].clientX;//…});node.delegate("touchmove",function(e){var current_x = e.touches[0].pageX;});//…}触屏touch事件
  67. 67. if (ontouchstart in document.documentElement) {node.delegate(touchstart„, function(e){var x = e.changedTouches[0].clientX;//…});node.delegate(touchend„, function(e){var x = e.changedTouches[0].clientX;//…});node.delegate("touchmove",function(e){var current_x = e.touches[0].pageX;});//…}触屏touch事件
  68. 68. if (ontouchstart in document.documentElement) {node.delegate(touchstart„, function(e){var x = e.changedTouches[0].clientX;//…});node.delegate(touchend„, function(e){var x = e.changedTouches[0].clientX;//…});node.delegate("touchmove",function(e){var current_x = e.touches[0].pageX;});//…}触屏touch事件
  69. 69. 空间位移事件if(window.DeviceMotionEvent) {window.addEventListener(devicemotion,function(e){var acceleration = e.accelerationIncludingGravity;var x = acceleration.x,y = acceleration.y,z = acceleration.z;//…},false);}
  70. 70. HTML5 和 Native App 如何对接?
  71. 71. HTML5 和 Native App 如何对接?1,Web App 服务可以适时更新Native App软件更新需要重新安装 ?2,Web App 开发周期相对较短Native App和Web App之间的分工?
  72. 72. PhoneGap 提供了一些思路http://phonegap.com/将HTML5 App打成安装包,但包升级时无法自动更新
  73. 73. HTML5 App + NativeAppHTML5快速开发原型+打包至NativeApp框架中
  74. 74. HTML5 App + NativeAppFar More than PhoneGap…Native AppHTML5 App
  75. 75. 移动Web中的性能问题!
  76. 76. 型号 CPU RAMiOSiPhone 4S 双核A5 800MHZ 512MiPhone 4 A4 800MHZ 512MiPhone 3GS S5PC100 600MHZ 256MAndroidGlaxy Note Exynos 双核 1.4GHZ 1GNexus One 高通 1GHZ 512MMOTO XT615 高通 800MHZ 512MHTC Legend 高通 600MHZ 384M移动设备和浏览器性能常见移动设备硬件情况概况
  77. 77. iPhone4S29%iPhone466%iPhone3GS5%1GHZ以上45%800MHZ24%600MHZ19%其他12%iPhone硬件分布手机淘宝2012-4月数据Andoid硬件分布(CPU)
  78. 78. 版本 渲染引擎 JS引擎iOSiOS 4.3+ Web Core Nitro *Older iOS Web Core JavaScript CoreAndroidAndroid 2.2+ Web Core V8Older Android Web Core JavaScript CoreiOS和Android版本
  79. 79. iOS 5.1iOS 5.0iOS 4.3iOS 4.2iOS 4.1Android 4.0Android 2.3Android 2.2Android 3.0手机淘宝2012-4月数据iOS版本分布 Android版本分布
  80. 80. 1,低端设备众多2,系统分配给浏览器的资源有限http://is.gd/hApzIp3,简化的浏览器实现4,不少老旧引擎5,需要高性能支持的HTML5 OPOASo,问题是…
  81. 81. 1,性能问题会被放大数倍2,很容易造成体验瓶颈然而,事实却更加严峻…和PC平台相比
  82. 82. Web App 的性能优化1. 处理性能(CPU & RAM)• Reflow & Repaint• CSS3的性能问题• 动画• JS中的内存控制和技巧• 关于电量2. 网络性能 (Network)
  83. 83. 需要优化的两个核心1. 减少内存中存储的内容2. 减少CPU的实时运算消耗
  84. 84. http://www.stubbornella.org/content/2009/03/27/reflows-repaints-css-performance-making-your-javascript-slowhttp://www-archive.mozilla.org/newlayout/doc/reflow.htmlReflow & Repaint(Layout & Paint)Parse FlowFetchCache TreeDisplayListURLPaintPixels
  85. 85. 减少Reflow & Repaint1. off-document 避免直接操作DOM2. 一次性修改样式3. 让Dom脱离文档流4. 减少Dom数量和深度5. Dom复用
  86. 86. 减少Reflow & Repaint1. off-document 避免直接操作DOM2. 一次性修改样式3. 让Dom脱离文档流4. 减少Dom数量和深度5. Dom复用
  87. 87. 减少Reflow & Repaint1. off-document 避免直接操作DOM2. 一次性修改样式3. 让Dom脱离文档流4. 减少Dom数量和深度5. Dom复用
  88. 88. var fragment = document.createDocumentFragment(),list = [„foo‟,‟bar‟,‟baz‟],elem,contents;for (var i = 0; i<list.length; i++){elem = document.createElement(„div‟);content = document.createTextNode(list[i]);fragment.appendChild(content);}document.body.appendChild(fragment);1.off-document:文档片段
  89. 89. var fragment = document.createDocumentFragment(),list = [„foo‟,‟bar‟,‟baz‟],elem,contents;for (var i = 0; i<list.length; i++){elem = document.createElement(„div‟);content = document.createTextNode(list[i]);fragment.appendChild(content);}document.body.appendChild(fragment);1.off-document:文档片段
  90. 90. 1.off-document:节点克隆var tmpnode = document.getElementById(„container‟),clone = tmpnode.cloneNode(true),list = [„foo‟,‟bar‟,‟baz‟],elem,contents;clone.setAttribute(„width‟,‟50%‟);for(var i = 0; i<list.length; i++){elem = document.createElement(„div‟);content = document.createTextNode(list[i]);clone.appendChild(elem);}original.parentNode.replaceChild(clone,original);
  91. 91. 1.off-document:节点克隆var tmpnode = document.getElementById(„container‟),clone = tmpnode.cloneNode(true),list = [„foo‟,‟bar‟,‟baz‟],elem,contents;clone.setAttribute(„width‟,‟50%‟);for(var i = 0; i<list.length; i++){elem = document.createElement(„div‟);content = document.createTextNode(list[i]);clone.appendChild(elem);}original.parentNode.replaceChild(clone,original);
  92. 92. off-document:block-none-blockvar subElem = document.create(„div‟),elem = document.getElementById(„animated‟);elem.style.display = ‘none’;elem.appendChild(subElem);elem.style.width = „320px‟;elem.style.height = „480px‟;….elem.style.display = ‘block’;
  93. 93. off-document:block-none-blockvar subElem = document.create(„div‟),elem = document.getElementById(„animated‟);elem.style.display = ‘none’;elem.appendChild(subElem);elem.style.width = „320px‟;elem.style.height = „480px‟;….elem.style.display = ‘block’;
  94. 94. 2.一次性修改样式<style type=“text/css”>div { background:white; color:black; }div.active { background:blue; color:white; }</style><script>$(„#styled‟).addClass(‘active’);</script>
  95. 95. 3.让元素脱离文档流.selector1 {position:absolute;}.selector2 {position:fixed;}
  96. 96. 4.减少Dom数量和深度瓶颈1:节点reflow,子元素/后续元素都会reflow瓶颈2:DOM尺寸会减慢所有操作
  97. 97. 5.DOM复用建立Dom复用池,避免频繁创建和销毁;使用前端模板
  98. 98. CSS3 性能问题!http://simonjonsson.com/dev/css3-performance-testhttp://www.pubnub.com/blog/css3-performance-optimizations
  99. 99. • 大字体• Box shadow• Text indent• Gradients• Background-size• Translate3D & GPU硬件加速性能杀手过度的使用会增加CPU负载加上reflow和repaint,性能负担加倍http://estelle.github.com/mobileperf/#slide37
  100. 100. 1. 为什么移动浏览器滚动时动画会停止?!2. 为什么我的iScroll这么卡?!综合以上,思考一下:
  101. 101. http://fav.m.taobao.com/h5proxy-fav.htm
  102. 102. iScroll的性能瓶颈iScroll滚动与原生滚动的性能比较render(reflow+repaint)和script损耗激增http://fav.m.taobao.com/h5proxy-fav.htm
  103. 103. iScroll的性能瓶颈空闲时iScroll的CPU损耗不高http://fav.m.taobao.com/h5proxy-fav.htm
  104. 104. iScroll的性能瓶颈Scroll发生时,CPU急剧飙高http://fav.m.taobao.com/h5proxy-fav.htm
  105. 105. http://cubiq.org/iscroll-4iScroll.js
  106. 106. CSS3 动画性能
  107. 107. 动画实现的原理:1, left/top 传统绝对定位计算2, CSS3 Transform 2d3, CSS3 Transform 3d动画的组织方式:1, JavaScript (setInterval) 传统组织2, CSS3 Transition 动态补间3, CSS3 Animation 关键帧组织动画实现的几种形式
  108. 108. 传统的动画实现<div id=“Test”>矩形动画,位移300px</div><script>var el = $(„#Test‟), i = 0;var s = setTimeout(function(){i += 1;el.css(‘top’,i+’px’);if(i >= 300){clearTimeout(s);return false;}setTimeout(arguments.callee,20);},20);</script>
  109. 109. 传统的动画实现<div id=“Test”>矩形动画,位移300px</div><script>var el = $(„#Test‟), i = 0;var s = setTimeout(function(){i += 1;el.css(-webkit-transform, translateY(+i+px));if(i >= 300){clearTimeout(s);return false;}setTimeout(arguments.callee,20);},20);</script>
  110. 110. 传统的动画实现<div id=“Test”>矩形动画,位移300px</div><script>var el = $(„#Test‟), i = 0;var s = setTimeout(function(){i += 1;el.css(‘-webkit-transform’,translate3d(0,+i+px,0));if(i >= 300){clearTimeout(s);return false;}setTimeout(arguments.callee,20);},20);</script>
  111. 111. CSS3 Anim 关键帧组织.run {-webkit-transform:translate3d(0,300px,0);-webkit-animation-duration: .4s;-webkit-animation-iteration-count: 1;-webkit-animation-name:anim-top;}@-webkit-keyframes anim-top {from {top:0;}to {top:300px;}}
  112. 112. CSS3 Anim 关键帧组织.run {-webkit-transform:translate3d(0,300px,0);-webkit-animation-duration: .4s;-webkit-animation-iteration-count: 1;-webkit-animation-name:anim-top;}@-webkit-keyframes anim-top {from {-webkit-transform:translateY(0px);}to {-webkit-transform:translateY(300px);}}
  113. 113. CSS3 Anim 关键帧组织.run {-webkit-transform:translate3d(0,300px,0);-webkit-animation-duration: .4s;-webkit-animation-iteration-count: 1;-webkit-animation-name:anim-top;}@-webkit-keyframes anim-top {from {-webkit-transform:translate3d(0,0,0);}to {-webkit-transform:translate3d(0,300px,0);}}
  114. 114. CSS3 Transition 动态补间.test {top:0;-webkit-transition-property:top;-webkit-transition-duration:.4s;-webkit-transition-timing-function: linear;}.test.run {top:300px;}<script>$(„.test‟).addClass(„run‟);</script>
  115. 115. CSS3 Transition 动态补间.test {top:0;-webkit-transition-property:top;-webkit-transition-duration:.4s;-webkit-transition-timing-function: linear;}.test.run {-webkit-transform:translateY(300px);}<script>$(„.test‟).addClass(„run‟);</script>
  116. 116. CSS3 Transition 动态补间.test {top:0;-webkit-transition-property:top;-webkit-transition-duration:.4s;-webkit-transition-timing-function: linear;}.test.run {-webkit-transform:translate3d(0,300px,0);}<script>$(„.test‟).addClass(„run‟);</script>
  117. 117. iOS AndroidTime(ms) smooth Time(ms) smoothJavaScriptabsolute 1400+ N 1000+ NtranslateY 1400+ N 1000+ Ytranslate3D 690 Y 1000+ YAnimationabsolute 500 N 430 NtranslateY 470 Y 433 Ytranslate3D 470 Y 433 YTransitionabsolute 430 N 408 NtranslateY 470 Y 417 Ytranslate3D 460 Y 413 Y几种方式的性能对比
  118. 118. iOS AndroidTime(ms) smooth Time(ms) smoothJavaScriptabsolute 1400+ N 1000+ NtranslateY 1400+ N 1000+ Ytranslate3D 690 Y 1000+ YAnimationabsolute 500 N 430 NtranslateY 470 Y 433 Ytranslate3D 470 Y 433 YTransitionabsolute 430 N 408 NtranslateY 470 Y 417 Ytranslate3D 460 Y 413 Y几种方式的性能对比
  119. 119. iOS AndroidTime(ms) smooth Time(ms) smoothJavaScriptabsolute 1400+ N 1000+ NtranslateY 1400+ N 1000+ Ytranslate3D 690 Y 1000+ YAnimationabsolute 500 N 430 NtranslateY 470 Y 433 Ytranslate3D 470 Y 433 YTransitionabsolute 430 N 408 NtranslateY 470 Y 417 Ytranslate3D 460 Y 413 Y几种方式的性能对比
  120. 120. iOS AndroidTime(ms) smooth Time(ms) smoothJavaScriptabsolute 1400+ N 1000+ NtranslateY 1400+ N 1000+ Ytranslate3D 690 Y 1000+ YAnimationabsolute 500 N 430 NtranslateY 470 Y 433 Ytranslate3D 470 Y 433 YTransitionabsolute 430 N 408 NtranslateY 470 Y 417 Ytranslate3D 460 Y 413 Y几种方式的性能对比
  121. 121. Why?Transform-Translate3dGPU硬件加速性能强劲,金枪不倒http://www.slideshare.net/lijing00333/graphic-programming-in-js
  122. 122. JS code…JS解释器(JS引擎)浏览器内核(渲染引擎)X windowOS kernel硬件CPU消耗在层层调用中setInterval(anim,10);CPUGPUGPU空闲
  123. 123. JS code…JS解释器(JS引擎)浏览器内核(渲染引擎)X windowOS kernel硬件CSS3 TransitionWebGL APICSS3 transition普通样式动画CSS3 transitiontransform动画
  124. 124. JS code…JS解释器(JS引擎)浏览器内核(渲染引擎)X windowOS kernel硬件CPU计算纹理 GPU渲染纹理CSS3 TransitionWebGL APICSS3 transition普通样式动画CSS3 transitiontransform动画
  125. 125. BrowserCPUGPUMemory发送指令结果返回给浏览器http://zh.wikipedia.org/wiki/纹理映射GPU 加速过程http://www.khronos.org/webgl/
  126. 126. http://m.taobao.com/
  127. 127. 1.创建纹理并发送数据的过程很慢但GPU处理3D动画很快2.Mobile Safari默认创建1个纹理大小不超过1024x10243.创建的纹理生命周期仅在动画过程中存在,动画结束即刻销毁4.创建或销毁纹理过程中,可能会出现闪屏(BUG)需要留意的问题
  128. 128. 解决方案http://ued.taobao.com/blog/2012/01/06/Chrome渲染Transition时页面闪动Bughttp://jsfiddle.net/besteric/NrAYy/embedded/result%2Ccss/• 在动画元素上设置max-width:1024px,限制纹理绘制范围• 避免大批量同时应用• 解决闪屏:-webkit-backface-visibility:hidden;-webkit-transform-style:preserve-3d;
  129. 129. JavaScript中的内存控制• 闭包导致循环引用• 闭包导致过长的调用链• 使用事件代理• 低效的Dom选择器• 减少Dom遍历范围和次数• 事件节流• …http://www.nczonline.net/blog/2009/01/13/speed-up-your-javascript-part-1http://www.developer.nokia.com/Community/Wiki/JavaScript_Performance_Best_Practiceshttp://www.html5rocks.com/en/tutorials/speed/quick/
  130. 130. • JPEG最省电(JPEG > PNG > GIF)• 图片数量越大,尺寸越大,越耗电• Ajax等动态JS增加电量消耗• 加载不必要的资源导致电量浪费(JS库)• Reflow和repaint耗电• WebGL(Translate3D)耗电• 内存占用越大越耗电• 性能越差,电量消耗越快关于电量http://www2012.wwwconference.org/proceedings/proceedings/p41.pdf
  131. 131. • 处理性能优化的核心是CPU和内存• 尽力去减少Reflow和repaint吧• 合理使用GPU加速动画渲染• 不要过分信任和滥用CSS3• 更高效的JavaScript小技巧• 性能越好,耗电越少• 你有更好更聪明的方案• 影响和驱动设计• 遵循前人的经验,站在巨人的肩上• 记住,移动浏览器在现阶段仍然是个屌丝性能原则!
  132. 132. 古老的编程技术 vs 新式设备
  133. 133. 扩展阅读http://blog.cloudfour.com/css-media-query-for-mobile-is-fools-gold/
  134. 134. • Chrome Developer Tools• Mobile Perf bookmarklet• Firebug Lite / Page Resources / DOM Monster / SpriteMe / CSSess /Zoompf• Yslow Mobile• PageSpeed Insights• ICY• iWebInspector• Android Webkit Console (Android 2.2+)• Remote Debugging for Mobile Safari• Weinre• Adobe Shadow• JSPerf• SunSpider• Mobile Browser Concurrency Test移动开发工具箱
  135. 135. 另辟蹊径从策略的角度,另一些解决方案
  136. 136. 服务端白名单过滤前端辅助检测生成HEM标识Module AModuleBModule DModuleCV8检测 特性检测Web App模块化版本控制方案http://stackoverflow.com/questions/6768474/how-can-i-detect-which-javascript-engine-v8-or-jsc-is-used-at-runtime-in-androModernizr
  137. 137. http://engineering.linkedin.com/linkedin-ipad-5-techniques-smooth-infinite-scrolling-html5Current Viewplaceholderfake-src IMGfake-src IMGscriptScrollClever View
  138. 138. 前端API层前端传统嗅探网络适配库navigator.connection Window.performance补充方案高清图切换 等Offline/2G/3G/WIFI高/中/低“网络状况嗅探”方案Android 2.2+ Android 4.0+固定IMG打点计算带宽http://lognormal.github.com/boomerang/doc/
  139. 139. 《手机淘宝HTML5 Web App项目最佳实践》更多实践详情请关注7月8日 TaoMobile 无线技术专场玄寂/左使/不台
  140. 140. 《淘宝彩票移动项目开发实践》更多移动Web OPOA 项目实践请关注7月28日 D2沙龙(北京场)函谷
  141. 141. Thanks栋寒/完真/地极/虎牙/灵玉/流火/函谷人马/夏之玄寂/曹纯/渚薰/张军/师影/弈天/神勋
  142. 142. http://www.flickr.com/photos/wintan29/3641254652/http://www.flickr.com/photos/samuel-leo/3550983108/sizes/s/in/photostreamhttp://www.flickr.com/photos/morinkovo_fotky/4168850871/sizes/z/in/photostreamhttp://www.flickr.com/photos/contactink/3062292337/http://www.flickr.com/photos/onemillion/3979984655http://www.flickr.com/photos/polvero/4232984120http://www.flickr.com/photos/bramus/5918434508/http://www.flickr.com/photos/wired_gr/5824553327/http://www.flickr.com/photos/macprime/3204702518/http://www.flickr.com/photos/gpayne85/3202258029/http://www.flickr.com/photos/27457302@N07/3487724038/http://www.flickr.com/photos/gorimon/3536710606/http://www.flickr.com/photos/massimiliana/1436809029/
  143. 143. 完颜F2E of eTaohttp://weibo.com/mario拔赤F2E of Taobaohttp://jayli.github.comWeb Developer & Translator
  1. A particular slide catching your eye?

    Clipping is a handy way to collect important slides you want to go back to later.

×