为什么 Android 上js判断qq内置浏览器器的性能很差

来自子话题:
谷歌为了每个用户都能用上高配电脑而一直努力,可谓用心良苦&br&&br&--------------------------&br&更新下:我突然想到,以后我们可以通过秀Tab的数量来秀配置了。。。
谷歌为了每个用户都能用上高配电脑而一直努力,可谓用心良苦--------------------------更新下:我突然想到,以后我们可以通过秀Tab的数量来秀配置了。。。
人们说的是,IE6不仅不支持在发布之后几年才有的新标准,而且还没有利用不存在的后门强制没有打开Windows Update的盗版用户升级到12年后的最新IE版本,所以是垃圾。
人们说的是,IE6不仅不支持在发布之后几年才有的新标准,而且还没有利用不存在的后门强制没有打开Windows Update的盗版用户升级到12年后的最新IE版本,所以是垃圾。
来自子话题:
都用在了哪些项目上不清楚,不过可以说说node适合用在什么场景下。&br&&br&首先,node新开一个http连接的开销,相当于一个大函数调用,相比php的新开线程动辄花费2MB内存和上下文切换的漫长时间,已经很小很小了。所以,node天生就是为高并发的应用而诞生,在设计之初就承载着巨大的使命。而这种极度追求代码效率和美感的设计,是以提升学习理解的难度,和考验编程能力为代价。如果你像我一样,有代码洁癖,追求极致,那么node将是不二选择。如果你仅仅是为了完成工作,或者快速搭建项目上线运营,那么还是用php或其它什么看似方便却一点也不“美”的语言吧。&br&&br&再者,由于js的异步特征,始终有用户代码在执行,省去了等待查询数据库和文件系统的时间,相比CPU的时钟频率,去读一次数据库太久太久,久到让CPU等得花儿都谢了。node让CPU不在等待,node让妈妈不用担心我的内存。但是这种高效运用CPU的异步回调,将会带来逻辑上的混乱,一不小心就会一团乱麻理都理不清,下文有叙。&br&&br&以上两点,导致node适合在具有大量细小的http请求环境下工作,典型的就是一个web即时聊天程序,或者一个支撑上万人同时在线的游戏服务器。你甚至不用考虑http请求数太多的问题。&br&&br&如果用node开发网站,你可以把数据请求分的很细,也就是说不必像php那样把所有数据一次性加载到客户端,而是加载一部分,让浏览器渲染页面的同时,再去加载另一部分。Facebook的页面优化技术(叫big...什么的,我忘了),就是这种分块加载的模式。可以让页面的加载速度在用户体验上提升5到10倍。&br&&br&node无论从代码执行速度,还是开销,都是最完美的选择。但是缺点在于js异步特征的难以理解和控制,如果没有相当过硬的js开发经验和特征理解,项目稍微大一点,代码结构就会一片混乱。node是在考验一个人的代码设计和掌控能力,如同九阴真经,练的好就一身绝学独霸武林,练的不好就走火入魔精神崩溃。动不动就长达8层的回调嵌套,可不是闹着玩的。除了采用step同步方案解决控制流倒置和深层回调嵌套问题,把数据请求分得很细,再分多次加载,不仅在代码流程上更美观,也更符合node的特性。&br&&br&有人说,异步代码是反人类的。其实同步执行才是反人类。想象一下,你需要打印一叠材料:打印机开始工作后,你站在那里等着,5分钟后打印完毕,你取走材料回到办公室。这似乎没什么。但是如果有100份需要打印?10000份呢?你也站在那里干等着?还是趁这个时间喝杯咖啡,或者多写几个 if else 吧。&br&&br&- - - - - - - - - - - -
更新 - - - - - - - - - - - - &br&列几个我知道的国内项目吧&br&1.雪球 - &a href=&///?target=http%3A///& class=& wrap external& target=&_blank& rel=&nofollow noreferrer&&雪球&i class=&icon-external&&&/i&&/a&&br&2.花瓣 - &a href=&///?target=http%3A///& class=& wrap external& target=&_blank& rel=&nofollow noreferrer&&花瓣网_发现、采集你喜欢的一切(家居,美食,时尚,穿搭,设计,商品,美图等)&i class=&icon-external&&&/i&&/a&&br&3.淘宝指数 - &a href=&///?target=http%3A///& class=& wrap external& target=&_blank& rel=&nofollow noreferrer&&淘宝指数 - 淘宝消费者数据研究平台&i class=&icon-external&&&/i&&/a&&br&4.CSDN Share - &a href=&///?target=http%3A//share.csdn.net/%23/& class=& wrap external& target=&_blank& rel=&nofollow noreferrer&&Share频道 - CSDN.NET&i class=&icon-external&&&/i&&/a&&br&5.酷厨 - &a href=&///?target=http%3A///& class=& wrap external& target=&_blank& rel=&nofollow noreferrer&&酷厨网 - 天下美食 尽在酷厨 | &i class=&icon-external&&&/i&&/a&&br&6.Worktile - &a href=&///?target=https%3A///& class=& wrap external& target=&_blank& rel=&nofollow noreferrer&&Worktile 让工作更简单&i class=&icon-external&&&/i&&/a&&br&7.兔耳日记 - &a href=&///?target=http%3A//www.tuer.me/& class=& wrap external& target=&_blank& rel=&nofollow noreferrer&&兔耳日记 | 首页&i class=&icon-external&&&/i&&/a&&br&8.牧客 - &a href=&///?target=http%3A///& class=& external& target=&_blank& rel=&nofollow noreferrer&&&span class=&invisible&&http://www.&/span&&span class=&visible&&/&/span&&span class=&invisible&&&/span&&i class=&icon-external&&&/i&&/a&&br&9.君鉴 - &a href=&///?target=http%3A///& class=& wrap external& target=&_blank& rel=&nofollow noreferrer&&君鉴&i class=&icon-external&&&/i&&/a&&br&另外附上一个Node.js框架:&br&Codekart - &a href=&///?target=http%3A///& class=& wrap external& target=&_blank& rel=&nofollow noreferrer&&CodeTank
欢迎使用Node.js前后端一体化开发框架 !&i class=&icon-external&&&/i&&/a&&br&Github地址:&a href=&///?target=https%3A///myworld4059/codekart& class=& wrap external& target=&_blank& rel=&nofollow noreferrer&&myworld4059/Codekart · GitHub&i class=&icon-external&&&/i&&/a&
都用在了哪些项目上不清楚,不过可以说说node适合用在什么场景下。首先,node新开一个http连接的开销,相当于一个大函数调用,相比php的新开线程动辄花费2MB内存和上下文切换的漫长时间,已经很小很小了。所以,node天生就是为高并发的应用而诞生,在设计之…
来自子话题:
首先,题主说的学习成本低上手快,我认为是相对正确的,比如:&br&&ol&&li&去github找了个demo,哇塞,都是app.js啊,大量会用jquery绑定事件以及发送异步请求的前端同学瞬间找到了爆棚的亲和感,还是原来的语法,还是原来的味道,你不让我试一把我都想跟你拼命了。&/li&&li&然后,去官网下了一个node.exe,随便找个端口listen一下,不再需要配置,不再需要其它知识,run起来了。就算你是最好的语言,你也要搞一个虚拟机吧,搞好了虚拟机再装个了一个hhvm或者php,然后发现还得装个nginx,nginx还得去了解基本配置,至少用php还是hhvm,cgi是什么,worker_processes等等都得有个基本概念吧。一想很简单啊,可是再想到自己原来只会用jquery绑定事件然后就捉襟见肘见好就收了。&/li&&li&最后,在cmd下,用最快的手速写下node app.js,然后用最大的力量敲击了回车,切换到浏览器,打开了127.0.0.1:xxxx,看到了烟花般绚烂的hello world,这一刻忽然发现自己“上手了”,感叹“学习成本低”,后端也不难啊。&/li&&/ol&请各位玻璃心的同学,尤其是我大前端同学们,不要看到这里,不要已经准备好若干吨的脏话准备在留言板挥洒。因为,这也是我曾经学习的路线和想当然,直到很长时间后,我发现我太幼稚了。&br&说说我看到的一些现象吧,说明大量前端同学在缺乏一些基本的计算机理论知识的情况下,去做node开发的问题,包括但不限于:&br&&ol&&li&拿内存当缓存。到处是var obj = {},就开始用obj存数据,哪天内存就爆炸了。&/li&&li&基本的多进程,不懂;基本的线上进程维护,没有意识。多核利用都没有,更不用说分布式了,一个error出一个进程挂,一个进程挂一个服务挂。&/li&&li&代码质量没有精益求精。以异步为例,习惯了browser的开发,习惯了绑定事件,缺少对promise等优秀模式的使用。&/li&&li&没有打log的意识。&/li&&li&对并行没有任何概念。从来没有用过async.js等控制流程。&/li&&li&对基本概念不懂。stream是什么,buffer是什么,cluster又是什么等等。&/li&&li&对ES新规范跟进不够。node不像浏览器,我们要顾及兼容性太多,es5、es6为我们提供了那么多优秀的api、语法、数据结构。去重数组用Set吧,Map应该是Map不要再用{}了,Array.prototype上那么多优秀的方法,你为什么还是for循环遍地开发。&/li&&li&还有好多,不敢再说。。。&/li&&/ol&所以,我认为楼主说自己是菜逼(我也觉得自己是菜逼),我想原因多半是因为看到了自己已有的前端知识直接转做node开发的不足,发现有大量理论知识和实战知识的缺失导致无法支撑自己的后端之路吧。&br&最近答主自己也是内心颇为起伏,赠送两个建议给题主和读者,也顺便自勉:&br&&ol&&li&提高自身的计算机基本素养,比如最基本的理论知识。&/li&&li&不管外界对技术的评价,一定要持之以恒地追求极致。相信终有一天能看出差别。&/li&&/ol&以上,共勉。
首先,题主说的学习成本低上手快,我认为是相对正确的,比如:去github找了个demo,哇塞,都是app.js啊,大量会用jquery绑定事件以及发送异步请求的前端同学瞬间找到了爆棚的亲和感,还是原来的语法,还是原来的味道,你不让我试一把我都想跟你拼命了。然后…
来自子话题:
对明明问题很大又不愿意承认的 google 的脑残粉无力吐槽。 &br&在今天这个时间点上, Android 上的移动浏览器的确是落后的。(未来的画饼那是另外一回事)&br&问题有些复杂,下面简单分析一下:&b&&br&&br&1 Android 内置浏览器&/b&&br&落后在两个方面&br&&br&&b&1.1 效能&/b&&br&Webkit 的优化不够,再加上Google 的 V8 引擎并没有用在内置浏览器上(或有变化,确认中),所以很多在 iOS 跑的很流畅的页面, Android 上就特别悲剧。&br&这方面的问题,是手机厂家可以弥补的。因为内置浏览器是开源的。魅族的确为这个浏览器做了很多优化,比较重大的是利用 GPU 加速。他能戏剧性的改善浏览的体验( 长页面浏览的效果是超越 iPhone5 的)。但是,也说明原生的浏览器上, Google 做的有多么不到位。&br&&br&&b&1.2 HTML5 支持&/b&&br&这方面内置浏览器一直落后于 iOS ,而且 Google 似乎现在已经没有追赶的意思,差距离 iOS 越来越大。&br&&img src=&/8d7aa8b6f41f5_b.jpg& data-rawwidth=&800& data-rawheight=&472& class=&origin_image zh-lightbox-thumb& width=&800& data-original=&/8d7aa8b6f41f5_r.jpg&&&br&&b&2 为什么 chrome for android 不是答案&/b&&br&Chrome for Android 做为 Android 平台的 HTML5 浏览器,同样存在两个问题。&br&&br&&b&2.1 非开源&/b&&br&本来, Chrome for Android 如果开源,第三方厂家可以对她提供更多的支持。比如现在魅族做的 GPU 加速。&br&但是,即使 Android 4.2 , &b&Chrome 仍然没有开源。&/b&这事情不知道要拖到猴年马月了。&br&闭源的 Chrome for Android 本身写的再出色,有 V8 引擎的支持,也无法让厂家针对硬件做优化。所以效能上仍然存在遗憾 - 硬件能力无法被浏览器充分挖掘。&br&&br&Chromium for android 则让人进退两难 - 其实他也不应该在这里被讨论,他不够完善,也不是 google 的东西。&br&&b&Chrome 根本没有开源,你说他的表现和 Chrome for Android 一致不是扯淡嘛。Google 拉出一个分支做了什么,谁都说不准。&/b&&br&&b&别的答案中,下面这种看法错的离谱竟然还有那么多人赞同,我也只好再次无力吐槽(那个答案的评论里已经有人指出):&/b&&br&&blockquote&Chromium 和 Chrome 的区别只是在于是否集成了Google的一些同步服务&/blockquote&所以, anyway ,对厂家而言,上 chromium ,如果 Chrome for Android 最终开源,你还要换回来吗?&br&&br&&b&2.2 无法支持 webview&/b&&br&内置 Apps 使用 webview 是今后 Apps/HTML5 进化的趋势之一。&br&好处很多,比如可以直接支持 GA ,更方便的 AB Test,更少 App Updates,甚至 responsive design 。&br&iOS 这方面的技术已经相当成熟。Apps 内 webview 的界面&b&可以乱真&/b& : &b&有多少人注意到 iOS App Store 是用 webview 实现的?&/b&&br&而今天使用这种 Apps + HTML5 的 hyper 做开发的 team 往往会发现, iOS 上跑得好好的页面,拿到 Android 上就各种悲剧 - 这不是 Android Team 的耻辱,那是什么?&br&而 Chrome for Android 虽然在 4.2 内置到了 Android 之中,&b&却不能被 webview 调用!&/b&&br&&br&&b&3 最后的话&/b&&br&个人懒得分析 Google 在 Android 浏览器上为什么搞成这样 - 动机其实也不重要。&br&但是,毫无疑问,目前的这种结果,是脑残的。&br&&br&Google 如果可以&br&&ul&&li&用 Chrome for Android 替换掉目前的内置浏览器&br&&/li&&li&开源允许第三方厂家结合硬件优势做优化&br&&/li&&/ul&那么在 Android 系统上的浏览器,才能和 iOS 相提并论。&br&&br&否则?目前最好的浏览体验是分裂的。 MX2 上流畅度最高。而 Chrome for Android 上 HTML5 支持更好。&br&&br&&b&用户总是不能同时得到两者。&/b&&br&&br&ps&br&利益相关:笔者在魅族工作。&br&另外这问题是我问的。并非我不会匿名提问,包括写利益相关,是因为我欢迎各种"阴谋论":他们只能影射你自己。
对明明问题很大又不愿意承认的 google 的脑残粉无力吐槽。 在今天这个时间点上, Android 上的移动浏览器的确是落后的。(未来的画饼那是另外一回事)问题有些复杂,下面简单分析一下:1 Android 内置浏览器落后在两个方面1.1 效能Webkit 的优化不够,再加…
我喜欢cnbeta的一个评论:IE是轿车,chrome是跑车,firefox是变形金刚。
我喜欢cnbeta的一个评论:IE是轿车,chrome是跑车,firefox是变形金刚。
来自子话题:
发展前途什么的不了解,但框架(framework)和库 (library)是截然不同的两个概念,下面简单区分一下。&br&&br&什么是&b&库&/b&呢?比如,你觉得用原生的 AJAX 太麻烦,不仅需要写 XMLHttpRequest, onreadystatechange 这种冗长的名称,为了兼容旧版 IE 甚至还要考虑先判断 window.XMLHttpRequest 是否定义。这样即便是完成最简单的功能也需要十多行代码。于是有人把这些麻烦的代码预先帮你写好,提供了一套方便的接口&b&供你调用&/b&(比如 jQuery 中一个 ajax
函数就能完成几乎所有日常功能),就出现了一个库。总之,库包含一些能够完成特定或特定类型的明确任务的可供重用的代码。你告库做你想做的事,库就会帮你做好,你不在乎库是怎么做的,库不知道你做这件事的意图。&br&&br&&b&框架&/b&和库的最重要区别是其&b&控制反转&/b&(inversion of control)的特点。简单地说,整个程序的&b&控制流程&/b&不是你,而是框架。引用 Stack Overflow 上的精辟的&a href=&///?target=http%3A///a/233765& class=& wrap external& target=&_blank& rel=&nofollow noreferrer&&一个答案&i class=&icon-external&&&/i&&/a&:&br&&blockquote&&p&You call Library.&/p&&p&Framework calls you.&/p&&/blockquote&&p&框架就像整个程序的骨架,拥有&b&默认&/b&的&b&有意义&/b&的行为,或者说知道在特定的情况下应该做什么&b&样&/b&的事情。你可以通过特定的方式(比如类的继承)&b&替代&/b&这些默认行为,从而以这个框架为基础进行&b&扩展&/b&。在适当的时候,框架则会调用你的代码。这样整个程序就实现了你想实现的功能。&/p&
发展前途什么的不了解,但框架(framework)和库 (library)是截然不同的两个概念,下面简单区分一下。什么是库呢?比如,你觉得用原生的 AJAX 太麻烦,不仅需要写 XMLHttpRequest, onreadystatechange 这种冗长的名称,为了兼容旧版 IE 甚至还要考虑先判…
来自子话题:
每天8个必刷的网站...供参考&br&1. &a href=&///?target=http%3A///member.aspx& class=& wrap external& target=&_blank& rel=&nofollow noreferrer&&Online video tutorials & training&i class=&icon-external&&&/i&&/a&&br&2. &a href=&///?target=https%3A//www.coursera.org& class=& wrap external& target=&_blank& rel=&nofollow noreferrer&&Coursera - Free Online Courses From Top Universities&i class=&icon-external&&&/i&&/a&&br&3. &a href=&///?target=https%3A//scotch.io& class=& wrap external& target=&_blank& rel=&nofollow noreferrer&&Scotch ? Developers bringing fire to the people.&i class=&icon-external&&&/i&&/a&&br&4. &a href=&///?target=http%3A//& class=& wrap external& target=&_blank& rel=&nofollow noreferrer&&JavaScript Weekly: A Free, Weekly Email Newsletter&i class=&icon-external&&&/i&&/a&&br&5. &a href=&///?target=http%3A//& class=& wrap external& target=&_blank& rel=&nofollow noreferrer&&HTML5 Weekly: A Free, Weekly Email Newsletter&i class=&icon-external&&&/i&&/a&&br&6. &a href=&///?target=https%3A//& class=& wrap external& target=&_blank& rel=&nofollow noreferrer&&Medium&i class=&icon-external&&&/i&&/a&&br&7. &a href=&///?target=http%3A//& class=& wrap external& target=&_blank& rel=&nofollow noreferrer&&Smashing Magazine&i class=&icon-external&&&/i&&/a&&br&8. &a href=&///?target=https%3A//& class=& wrap external& target=&_blank& rel=&nofollow noreferrer&&CSS-Tricks&i class=&icon-external&&&/i&&/a&
每天8个必刷的网站...供参考1. 2. 3. 4. 5.
来自子话题:
今天心血来潮,回答一波技术问题。总体来说,我看到这个消息是非常兴奋!一颗赛艇!缘由是之前好歹也用过 wordpress 去搭过一段时间自己的blog,对它有感情。同时也试过其他一些blog,比如 jekyll 和 hugo,一直觉得 Wordpress 的技术结构已经很老了,UI也看起来比较像80年代产物,早就应该到了改版的时候。这次 Calypso 就是对于wordpress的dashboard进行一次全面的升级,整个dashboard是用 single page app 来和server的restful API通信。&br&&br&首先看它的codename:Calypso:是古代一个神的名字。国外的公司在做一个项目的时候,经常喜欢用拉丁神话里的名字来命名,比如 Iris,Zeus,Hermes(包包)等:具体可以看这个页面 &a href=&///?target=https%3A//en.wikipedia.org/wiki/Twelve_Olympians& class=& wrap external& target=&_blank& rel=&nofollow noreferrer&&Twelve Olympians&i class=&icon-external&&&/i&&/a&
Facebook里我知道的项目使用过 宙斯,Iris,普罗米修斯,Titan等名字。&br&&br&具体来说 Calypso 的技术栈。除了这个问题描述里所说的之外, 我们再具体看看它的github上面的详情:&br&&br&&blockquote&&p&Calypso is the new &a href=&///?target=http%3A//& class=& external& target=&_blank& rel=&nofollow noreferrer&&&span class=&invisible&&http://&/span&&span class=&visible&&&/span&&span class=&invisible&&&/span&&i class=&icon-external&&&/i&&/a& front-end – a beautiful redesign of the WordPress dashboard using a single-page web application, powered by the &a href=&///?target=http%3A//& class=& external& target=&_blank& rel=&nofollow noreferrer&&&span class=&invisible&&http://&/span&&span class=&visible&&&/span&&span class=&invisible&&&/span&&i class=&icon-external&&&/i&&/a& REST API. Calypso is built for reading, writing, and managing all of your WordPress sites in one place.&br&&/p&&br&&p&It’s built with JavaScript – a very light &a href=&///?target=https%3A//nodejs.org/& class=& wrap external& target=&_blank& rel=&nofollow noreferrer&&node&i class=&icon-external&&&/i&&/a& plus &a href=&///?target=http%3A///& class=& wrap external& target=&_blank& rel=&nofollow noreferrer&&express&i class=&icon-external&&&/i&&/a& server, &a href=&///?target=https%3A//facebook.github.io/react/& class=& wrap external& target=&_blank& rel=&nofollow noreferrer&&React.js&i class=&icon-external&&&/i&&/a&, &a href=&///?target=https%3A//facebook.github.io/flux/& class=& wrap external& target=&_blank& rel=&nofollow noreferrer&&Flux&i class=&icon-external&&&/i&&/a&, &a href=&///?target=http%3A///& class=& wrap external& target=&_blank& rel=&nofollow noreferrer&&wpcom.js&i class=&icon-external&&&/i&&/a&, and many other wonderful libraries on the front-end.&/p&&/blockquote&&br&精简起来: server: node + front-end: react.js + flux + wordpress自己的js。这里使用的技术栈的确是当今最先进同时稳定的。从客观结果来看,感觉他们也是比较喜欢JS,所以整个技术架构都是基于 javascript 来布局的。整体框架的选择以轻量级为主,比如 express server:&a href=&///?target=http%3A///en/index.html& class=& wrap external& target=&_blank& rel=&nofollow noreferrer&&Express - Node.js web application framework&i class=&icon-external&&&/i&&/a& ,比如 react.js 也是。如果真的要提出一些建议的话,就是用 redux 去换掉 flux,具体理由见:&a href=&///?target=http%3A//redux.js.org/& class=& wrap external& target=&_blank& rel=&nofollow noreferrer&&Read Me | Redux&i class=&icon-external&&&/i&&/a& 上面收集了来自我们Facebook内部对于redux的看法,而且Facebook内部也在积极地使用 redux。Redux和Flux在总体架构上区别不大,具体比较看来自redux作者的答案:&a href=&///?target=http%3A///questions//why-use-redux-over-facebook-flux& class=& wrap external& target=&_blank& rel=&nofollow noreferrer&&javascript - Why use Redux over Facebook Flux?&i class=&icon-external&&&/i&&/a&&br&&br&另外UI方面的改进也不错(用过wordpress的admin页面的人都有感wordpress的UI都像上个时代的网页)。新版的UI:&br&&img src=&/a77ca0ed5c2585bdb438f3e820afe1fc_b.png& data-rawwidth=&654& data-rawheight=&493& class=&origin_image zh-lightbox-thumb& width=&654& data-original=&/a77ca0ed5c2585bdb438f3e820afe1fc_r.png&&&br&另外看github上的文件列表:&br&&img src=&/a1e27ae000ca5880d8eaf2_b.png& data-rawwidth=&987& data-rawheight=&1041& class=&origin_image zh-lightbox-thumb& width=&987& data-original=&/a1e27ae000ca5880d8eaf2_r.png&&还可以窥视一点有趣的工具:&br&1. Webpack用来打包和混淆等;(替代了grunt)&br&2. Vagrant 用来配置;&br&3. Dockerfile:说明使用了docker,而且docker肯定是未来的方向所在;现在在docker方向的创业我们觉得是很好的选择;&br&4. npm:依赖管理&br&5. 各种linter。&br&6. 在 &a href=&///?target=https%3A///Automattic/wp-calypso/tree/master/server& class=& wrap external& target=&_blank& rel=&nofollow noreferrer&&wp-calypso/server at master · Automattic/wp-calypso · GitHub&i class=&icon-external&&&/i&&/a&
还有对于server side rendering 的列表,另外可以看到使用node和jade。&br&&br&我最喜欢这次Calypso的几处改动:&br&1. Single page app + restful API&br&Single page app(单页app)在2010年开始流行(Backbone.js时代),主要好处就是反应快,所有的UI变化都在本地浏览器上完成,不需要重新去server请求一个页面,也不会有明显的页面跳转延时。和server的通信基于网页API(一般是 restful API),而传输的内容只是数据而已,没有了冗长的 html、css和javascript 的传输,所以速度要比原来快不少,即使 on-wire data format 用得是 raw json(如果换成 thrift 里的
TCompact 或者 google的protobuf,或者 iOS 上比较流行的 messagepack,可以让网络上传输的数据量更小)。另外更大的好处是可以复用这一套 restful API,用来给 iOS 和 Android 端使用,也可以后续开放给 3rd party developers,做成一个开放平台。本质上也就是说:将前端逻辑和渲染做成独立的mvc结构,使其和其他移动端并列,用统一的restful API来提供服务。&br&&br&2. React.js 和 Flux(Redux)的使用&br&喜欢这个并不是我之前是Facebook的人,只是单纯从技术上觉得这个的确是以后前端的方向。因为什么?因为简单和清晰的逻辑。在Facebook的时候,我们工程师被 tech lead 们(再次强调,是 tech lead, team lead, engineering lead,而不是 tech &b&leader&/b&!!!不要再说 chinglish 了!) 反复强调: complexity is the source of all evils. 降低复杂度是关键的关键。而我在国内这一年,发行很多创业公司的技术栈是怎么老怎么来,或者怎么fancy怎么复杂怎么来。可能技术人员在这样情况下会特别有成就感(虚拟的),而且可以出来一些炫耀的东西。这是一个公司的CTO或者tech partner要极力禁止的。在Facebook奉行的是:”Move fast & break things”,中文翻译过来就是“糙快猛”。而react + flux/reduct 正是在这种场景下诞生的。react主要解决view(UI)上的问题,让UI的书写可以像逻辑代码一样有复用和聚合,同时 flux/redux 的单向数据流可以将你前端的程序逻辑梳理地极为简单和清晰,不仅让bug发生的概率变小,而且代码的后续可维护性特别高:也就是说整体的开发速度和工程维护度都提高巨大!&br&&br&最后解答大家的一些疑惑:&br&React技术够成熟吗? ---- React.js 已经非常成熟,而且在Facebook内部各种项目都在使用。比如Facebook首页的整个search功能的UI都是react来完成的,还有里面很多详情页的展示也是react。新项目 -- 比如之前的一个在线教育的项目,也是全部依赖于 react 写就。所以 react.js 可以放心大胆地去使用。另外和其他一些常用的开源框架(比如 backbone)不太一样的地方是:react后面是有Facebook这样一个干爹的,所以不会没人管。整个facebook现在工程团队和公司现金流都是杠杠的,所以更新速度和bug修复速度都会有保证。React会比起一些业余时间完成的开源项目有保障很多。&br&&br&唯一要提醒的一点的事情是: react native (特别是 android 上)由于最近刚刚完成,可能坑很多;而且Facebook内部对于 react native 几乎没有怎么使用。所以使用 react native 要谨慎。(特别是 Android)
今天心血来潮,回答一波技术问题。总体来说,我看到这个消息是非常兴奋!一颗赛艇!缘由是之前好歹也用过 wordpress 去搭过一段时间自己的blog,对它有感情。同时也试过其他一些blog,比如 jekyll 和 hugo,一直觉得 Wordpress 的技术结构已经很老了,UI也…
来自子话题:
首先 chrome 几乎是全平台制霸的:MacOSX, Ubuntu, Windows, iOS(iPad/iPhone), Android(平板或者手机)。这意味着当你有多个设备的时候很方便设备之间同步,不但是书签,还有搜索记录,还有浏览的记录,等等。&br&&br&其次 chrome 的网站兼容性远远远远好于 safari,许多(真的是许多)用 safari 无法正常浏览的网站用 chrome 都能够正常浏览。&br&&br&在这两个优势面前,性能什么的根本就不重要,至少我从来没有感觉到 safari 跟 chrome 有可以察觉的性能差距。
首先 chrome 几乎是全平台制霸的:MacOSX, Ubuntu, Windows, iOS(iPad/iPhone), Android(平板或者手机)。这意味着当你有多个设备的时候很方便设备之间同步,不但是书签,还有搜索记录,还有浏览的记录,等等。其次 chrome 的网站兼容性远远远远好于 safari…
来自子话题:
&b&Disclaimer: 以下对比可能有强烈的个人色彩&/b&&br&&br&Node.js & Python 的地方&br&&ol&&li&快:这个快有两方面,第一是V8引擎快,在V8引擎背后操刀的是&b&Lars Bak&/b&大神,他创造过高性能SmallTalk引擎和Java Hotspot引擎(现在Java的默认VM),他带领下的V8引擎让Javascript速度达到了一个新的阶段。第二是异步执行,Node.js功能上是一个基于V8引擎的异步网络和IO Library,和Python的Twisted很像,不同的是Node.js的event loop是很底层的深入在语言中的,可以想象成整个文件在执行的时候就在一个很大的event loop里。&/li&&li&npm:npm可以说是用起来最顺手的package management了,npm作为Node.js的官方package management,汇集了整个社区最集中的资源。不像Python经历过easy_install和pip,还有2to3的问题。&/li&&li&Windows支持:Node.js有微软的加持,Windows基本被视为一等公民来支持,libuv已经可以很好的做到统一跨平台的API;而Python虽然也对Windows有官方的支持,但是总感觉是二等公民,时不时出些问题。&/li&&/ol&Python & Node.js 的地方&br&&ol&&li&语言:就单纯从语言的角度来说,Python写起来要比Javascript舒服很多。Javascript设计本身有许多缺陷,毕竟当时设计的时候只是作为在浏览器中做一些简单任务的script,所以代码一旦庞大,维护还是有困难(不过Node.js的module很大的改善了这个问题)。不过用Coffeescript可以很大的改善Javascript,几乎可以和Python等同。&/li&&li&成熟:成熟包括语言本身已经成熟,还有Framework和ecosystem也很庞大。Node.js的绝大多数framework都很新,有的API一直在变,有的感觉已经不在维护,总之没有一个像Django那种百足之虫感觉的framework。Python的主流ORM SQLalchemy也很成熟。&/li&&/ol&Python 和 Node.js 很难分高下的地方&br&&ol&&li&异步Style:Node.js的异步Style是CPS,也就是层层callback,基于event,和浏览器中的Javascript很像。CPS好处是让熟悉浏览器Javascript的人能很快上手,学习难度也不大。缺点是逻辑一复杂,就变得很难维护,基本上需要通过async.js这种library,或者用promise。Python的异步除了和Node.js很像的Twisted之外,也有基于coroutine的gevent,coroutine让异步代码维护起来更容易,不过学习曲线陡。&/li&&li&应用场景:如果是一个CRUD的app,那么想都不想直接是Python,Node.js本身不擅长CRUD的app(绝大多数Node.js都是直接裸在外面的,而不是有一个Nginx在前面,否则websocket就不能用了,不过新版nginx开始支持websocket),代码又不好维护,而Python的WSGI很适合,成熟的stack也有很多。如果更偏向于real-time,比如一个chat room,那么Node.js实现更容易。这两个应用场景还是有差别的。&/li&&/ol&
Disclaimer: 以下对比可能有强烈的个人色彩Node.js & Python 的地方快:这个快有两方面,第一是V8引擎快,在V8引擎背后操刀的是Lars Bak大神,他创造过高性能SmallTalk引擎和Java Hotspot引擎(现在Java的默认VM),他带领下的V8引擎让Javascript速度达到了一…
来自子话题:
占坑。这水非常非常深。题主可能从来没有怀疑过,但是:&blockquote&对于Array类型,其在内存中本来就是一个连续的系列,只需要根据index找到指定位置就行了,很容易找到需要的元素。&br&&br&但是对于Object类型,它里面的元素是无序的&/blockquote&这两句话从规范的角度看,以及在现代JavaScript引擎的实现里都可以是错的。&br&&br&&b&ECMAScript规范&/b&&br&&br&&a href=&///?target=https%3A//es5.github.io/%23x11.2.1& class=& wrap external& target=&_blank& rel=&nofollow noreferrer&&ECMAScript 5.1 - 11.2.1 Property Accessors&i class=&icon-external&&&/i&&/a&&br&&blockquote&&p&The production &i&MemberExpression&/i&&b&:&/b&&i&MemberExpression&/i&&b&[&/b&&i&Expression&/i&&b&]&/b& is evaluated as follows:&/p&&ol&&li&&p&Let &i&baseReference&/i& be the result of evaluating &i&MemberExpression&/i&.&/p&&/li&&li&&p&Let &i&baseValue&/i& be &a href=&///?target=https%3A//es5.github.io/%23x8.7.1& class=& wrap external& target=&_blank& rel=&nofollow noreferrer&&GetValue&i class=&icon-external&&&/i&&/a&(&i&baseReference&/i&).&/p&&/li&&li&&p&Let &i&propertyNameReference&/i& be the result of evaluating &i&Expression&/i&.&/p&&/li&&li&&p&Let &i&propertyNameValue&/i& be &a href=&///?target=https%3A//es5.github.io/%23x8.7.1& class=& wrap external& target=&_blank& rel=&nofollow noreferrer&&GetValue&i class=&icon-external&&&/i&&/a&(&i&propertyNameReference&/i&).&/p&&/li&&li&&p&Call &a href=&///?target=https%3A//es5.github.io/%23x9.10& class=& wrap external& target=&_blank& rel=&nofollow noreferrer&&CheckObjectCoercible&i class=&icon-external&&&/i&&/a&(&i&baseValue&/i&).&/p&&/li&&li&&p&Let &i&propertyNameString&/i& be &a href=&///?target=https%3A//es5.github.io/%23x9.8& class=& wrap external& target=&_blank& rel=&nofollow noreferrer&&ToString&i class=&icon-external&&&/i&&/a&(&i&propertyNameValue&/i&).&/p&&/li&&li&&p&If the syntactic production that is being evaluated is contained in &a href=&///?target=https%3A//es5.github.io/%23x10.1.1& class=& wrap external& target=&_blank& rel=&nofollow noreferrer&&strict mode code&i class=&icon-external&&&/i&&/a&, let &i&strict&/i& be &b&true&/b&, else let &i&strict&/i& be &b&false&/b&.&/p&&/li&&li&&p&Return a value of type &a href=&///?target=https%3A//es5.github.io/%23x8.7& class=& wrap external& target=&_blank& rel=&nofollow noreferrer&&Reference&i class=&icon-external&&&/i&&/a& whose base value is &i&baseValue&/i& and whose referenced name is &i&propertyNameString&/i&, and whose strict mode flag is &i&strict&/i&.&/p&&/li&&/ol&&/blockquote&注意第6步。规范在此描述的抽象的求值过程说方括号里的表达式要先通过ToString转换为String,然后以这个String去查找对象/数组中的成员。也就是说,无论这个表达式原本是Number还是String还是啥的,抽象的语义都是把它先转换为String再去查。&br&&br&然后规范对数组有进一步描述:&br&&a href=&///?target=https%3A//es5.github.io/%23x15.4& class=& wrap external& target=&_blank& rel=&nofollow noreferrer&&ECMAScript 5.1 - 15.4 Array Objects&i class=&icon-external&&&/i&&/a&&br&&blockquote&15.4 Array Objects &a href=&///?target=https%3A//es5.github.io/%23x15.4& class=& wrap external& target=&_blank& rel=&nofollow noreferrer&&#&i class=&icon-external&&&/i&&/a&&a href=&///?target=https%3A//es5.github.io/%23x15.4-toc& class=& wrap external& target=&_blank& rel=&nofollow noreferrer&&(T)&i class=&icon-external&&&/i&&/a&&a href=&///?target=https%3A//developer.mozilla.org/en/JavaScript/Reference/Global_Objects/Array& class=& wrap external& target=&_blank& rel=&nofollow noreferrer&&(R)&i class=&icon-external&&&/i&&/a&&a href=&///?target=https%3A//developer.mozilla.org/en/JavaScript/Guide/Predefined_Core_Objects%23Array_Object& class=& wrap external& target=&_blank& rel=&nofollow noreferrer&&(G)&i class=&icon-external&&&/i&&/a&&p&Array objects give special treatment to a certain class of property names. A property name &i&P&/i& (in the form of a String value) is an &i&array index&/i& if and only if &a href=&///?target=https%3A//es5.github.io/%23x9.8& class=& wrap external& target=&_blank& rel=&nofollow noreferrer&&ToString&i class=&icon-external&&&/i&&/a&(&a href=&///?target=https%3A//es5.github.io/%23x9.6& class=& wrap external& target=&_blank& rel=&nofollow noreferrer&&ToUint32&i class=&icon-external&&&/i&&/a&(&i&P&/i&)) is equal to &i&P&/i& and &a href=&///?target=https%3A//es5.github.io/%23x9.6& class=& wrap external& target=&_blank& rel=&nofollow noreferrer&&ToUint32&i class=&icon-external&&&/i&&/a&(&i&P&/i&) is not equal to 2^32-1. A property whose property name is an array index is also called an &i&element&/i&. Every Array object has a &b&length&/b& property whose value is always a nonnegative integer less than 2^32. The value of the &b&length&/b& property is numerically greater than the name of every property whose na whenever a property of an Array object is created or changed, other properties are adjusted as necessary to maintain this invariant. Specifically, whenever a property is added whose name is an array index, the &b&length &/b&property is changed, if necessary, to be one more than the numeric value and whenever the &b&length&/b& property is changed, every property whose name is an array index whose value is not smaller than the new length is automatically deleted. This constraint applies only to own properties of an Array object and is unaffected by &b&length&/b& or array index properties that may be inherited from its prototypes.&/p&&p&An object, &i&O&/i&, is said to be &i&sparse&/i& if the following algorithm returns &b&true&/b&:&/p&&ol&&li&&p&Let &i&len&/i& be the result of calling the [[Get]] internal method of &i&O&/i& with argument &b&&length&&/b&.&/p&&/li&&li&&p&For each integer &i&i&/i& in the range 0≤&i&i&/i&&&a href=&///?target=https%3A//es5.github.io/%23x9.6& class=& wrap external& target=&_blank& rel=&nofollow noreferrer&&ToUint32&i class=&icon-external&&&/i&&/a&(&i&len&/i&)&/p&&ol&&li&&p&Let &i&elem&/i& be the result of calling the [[GetOwnProperty]] internal method of &i&O&/i& with argument &a href=&///?target=https%3A//es5.github.io/%23x9.8& class=& wrap external& target=&_blank& rel=&nofollow noreferrer&&ToString&i class=&icon-external&&&/i&&/a&(&i&i&/i&).&/p&&/li&&li&&p&If &i&elem&/i& is &b&undefined&/b&, return &b&true&/b&.&/p&&/li&&/ol&&/li&&li&&p&Return &b&false&/b&.&/p&&/li&&/ol&&/blockquote&可见对数组来说,只有当一个属性名可以看作Uint32时,它才被看作一个&i&array index&/i&。&br&而且数组并不一定是“密集”(dense)的,而可能是“稀疏”(sparse)的。密集数组实现为连续的内存才有意义;稀疏数组实现为连续的内存则可能会既慢又浪费内存,取决于其稀疏程度。&br&&br&&b&JavaScript引擎的实现&/b&&br&&br&虽然不推荐但是JavaScript的对象可以当作数组用——使用Uint32的值为key,数组也可以当作一般对象用——使用非Uint32的值为key。&br&数组和普通对象最大的区别可能就是那个length属性了:JavaScript引擎只会为数组自动维护length属性,以及允许通过操作length属性来删除元素等。&br&&br&所以有些JavaScript引擎会选择在内部用完全一样的结构来实现对象和数组。这个结构能够同时高效的实现对象形式的普通属性访问以及数组形式的元素访问。这就跟Lua里的Table同时为哈希表场景和数组场景优化一样。&br&&br&具体的JavaScript引擎实现回头再来补充。题主有兴趣找资料读的话,可以从我的链接帖开始:&a href=&///?target=http%3A//hllvm./group/topic/37596& class=& wrap external& target=&_blank& rel=&nofollow noreferrer&&[链接帖] 各JavaScript引擎的简介,及相关资料/博客收集帖&i class=&icon-external&&&/i&&/a&&br&&br&有些早期JavaScript的实现颇糟糕。例如微软的JScript(版本 &= 5.8)。我在上面的链接帖讲JScript的部分写过:&br&&blockquote&JScript里对象里属性的存储基本上是靠Hashtable;数组性质的对象最初也是为稀疏数组优化,背后仍然是用Hashtable来存储。到IE8/JScript 5.8才加上了对密集数组的存储/访问优化。 &br&&/blockquote&在这种实现里,对象和数组的实现背后都是用Hashtable,访问属性/元素都是通过哈希查找。没啥性能不性能的可言…&br&&br&现代JavaScript引擎普遍使用hidden class方式实现基本的对象属性访问,同时也为把对象当作数组使用做好准备。&br&&br&以Nashorn为例,可以参考我之前做的一个讲义:&a href=&///?target=http%3A//www.slideshare.net/RednaxelaFX/implement-js-krystalmok& class=& wrap external& target=&_blank& rel=&nofollow noreferrer&&Implementing a JavaScript Engine&i class=&icon-external&&&/i&&/a&(打不开的话请自备工具)。第41页开始讲到对象模型,第44页开始讲到Nashorn所使用的对象模型,第49页演示了一个同时有对象属性和数组元素的对象的布局。&br&&img src=&/2b5ec9d18cd0db098ecbbe_b.jpg& data-rawwidth=&622& data-rawheight=&463& class=&origin_image zh-lightbox-thumb& width=&622& data-original=&/2b5ec9d18cd0db098ecbbe_r.jpg&&这个对象有x、y、z、a、b、0、1这些属性,其中前5个按前面的说法是对象形式的普通属性,而后2个是数组形式的元素。&br&&ul&&li&inline property(直接属性):x、y、z、a直接分配在了对象内,通过普通的Java对象字段实现。这样就让JavaScript对象更贴近原生Java对象,利于JVM优化其访问;&br&&/li&&li&spilled property(间接属性):b属性分配在了对象外的可扩容部分,默认通过Object[]实现;&/li&&li&array data(数组元素):所有能转换为Uint32的属性名都看作数组元素,存在外部的可扩容数组部分。当数组元素是密集的时候,Nashorn会使用真的Java数组作为存储空间(ContinuousArrayData的子类);而当数组元素是稀疏的,或者数组下标非常大的时候,Nashorn会转为使用TreeMap作为数组元素的存储空间(SparseArrayData)。&/li&&/ul&当Nashorn发现属性访问的key是可以看作Uint32的值时,它会把这个key看作array index,直接去array data查找元素(indexed property lookup);&br&而当key不是Uint32时,Nashorn会通过hidden class(在Nashorn里叫做Map)记录该属性的getter/setter动作应该如何实现。例如说对inline property它会记录下是哪个Java字段,对spilled property它会记录下属性在spill数组里的下标。&br&&br&Nashorn里JavaScript对象和数组都使用这个布局,从这个角度看没有任何区别。&br&在早期版JDK8 Nashorn里用下面的代码就可以构造出图中的对象布局:&br&&div class=&highlight&&&pre&&code class=&language-js&&&span class=&c1&&// Creates a JavaScript object. 4 inline properties are available by default&/span&
&span class=&kd&&var&/span& &span class=&nx&&o&/span& &span class=&o&&=&/span& &span class=&p&&{&/span& &span class=&nx&&x&/span&&span class=&o&&:&/span& &span class=&mi&&1&/span&&span class=&p&&,&/span& &span class=&nx&&y&/span&&span class=&o&&:&/span& &span class=&mi&&2&/span& &span class=&p&&}&/span& &span class=&c1&&// using 2 inlined property slots&/span&
&span class=&nx&&o&/span&&span class=&p&&.&/span&&span class=&nx&&z&/span& &span class=&o&&=&/span& &span class=&mi&&3&/span&
&span class=&c1&&// using the 3rd inlined slot&/span&
&span class=&nx&&o&/span&&span class=&p&&.&/span&&span class=&nx&&a&/span& &span class=&o&&=&/span& &span class=&mi&&4&/span&
&span class=&c1&&// using the 4th inlined slot&/span&
&span class=&nx&&o&/span&&span class=&p&&.&/span&&span class=&nx&&b&/span& &span class=&o&&=&/span& &span class=&mi&&5&/span&
&span class=&c1&&// oops, all in spill&/span&
&span class=&nx&&o&/span&&span class=&p&&[&/span&&span class=&mi&&0&/span&&span class=&p&&]&/span& &span class=&o&&=&/span& &span class=&mi&&6&/span&
&span class=&c1&&// array index property goes to ArrayData&/span&
&span class=&nx&&o&/span&&span class=&p&&[&/span&&span class=&mi&&1&/span&&span class=&p&&]&/span& &span class=&o&&=&/span& &span class=&mi&&7&/span&
&span class=&c1&&// ditto&/span&
&/code&&/pre&&/div&在另一个讲义里我演示过另一份代码,也可以构造出图中的对象布局:&a href=&///?target=http%3A//www.slideshare.net/RednaxelaFX/nashorn-on-jdk-8-adc2013& class=& wrap external& target=&_blank& rel=&nofollow noreferrer&&Nashorn on JDK 8 (ADC2013)&i class=&icon-external&&&/i&&/a&(同样,打不开的话请自备工具…)&br&&br&V8的实现方式也是类似。当然咯,Nashorn比V8后出现,前者的设计大量参考了后者。&br&V8里JavaScript对象的基类是JSObject,其中有两个字段:properties和elements,分别指向存储对象属性和数组元素的存储空间(backing storage);V8同样可以在对象内有直接属性(inlined property或者叫in-object property)。&br&properties就对应Nashorn的spilled properties,elements就对应Nashorn的array data。&br&V8的properties和elements都有“快速”和“慢速”模式。快速模式用密集的存储方式(FixedArray),慢速模式用哈希表(Dictionary)。对数组而言,稀疏数组一定是用慢速模式。&br&&br&&a data-hash=&cfdec6226ece879d2571fbcf& href=&///people/cfdec6226ece879d2571fbcf& class=&member_mention& data-editable=&true& data-title=&@尤雨溪& data-tip=&p$b$cfdec6226ece879d2571fbcf&&@尤雨溪&/a& 的回答里引用的文章从现在的角度看还是正确的,跟我上面举的例子也一致:&a href=&///?target=http%3A///posts/52/a-tour-of-v8-object-representation& class=& wrap external& target=&_blank& rel=&nofollow noreferrer&&A tour of V8: object representation&i class=&icon-external&&&/i&&/a&
占坑。这水非常非常深。题主可能从来没有怀疑过,但是:对于Array类型,其在内存中本来就是一个连续的系列,只需要根据index找到指定位置就行了,很容易找到需要的元素。但是对于Object类型,它里面的元素是无序的这两句话从规范的角度看,以及在现代JavaSc…
&p&引用我的博文 《&a href=&///?target=http%3A///view/UserExperience/74.html& class=& wrap external& target=&_blank& rel=&nofollow noreferrer&&新窗口打开链接的博弈&i class=&icon-external&&&/i&&/a&》&/p&&p&新窗口还是当前窗口打开,一直以来颇具争议。诚然,任何不分场景的强制使用某一种方式都是耍流氓。这里我就不一一分析场景了,这也需要用户研究同学提供的数据作为参考。在对用户使用场景做出了合理分析之后,我觉得还可以把细节做的更好。&/p&&p&举个栗子:&/p&&p&比如论坛这样的大面积列表页面,曾经 Discuz! 产品部门就为了是当前页面打开还是新窗口打开进行了激烈的讨论。然后某人灵机一动,何不在一个醒目的位置做出是否新窗口打开的选项呢?把选择权交给用户。&/p&&p&&a href=&///?target=http%3A//www.discuz.net/forum-86-1.html& class=& wrap external& target=&_blank& rel=&nofollow noreferrer&&Like this:&i class=&icon-external&&&/i&&/a&&/p&&img src=&/4cfe144d8db75e12e7fd751d_b.jpg& data-rawwidth=&616& data-rawheight=&258& class=&origin_image zh-lightbox-thumb& width=&616& data-original=&/4cfe144d8db75e12e7fd751d_r.jpg&&&br&&p&勾选「新窗」后,所有的链接都会新窗口打开了。&/p&&p&那么除了给 a 标签增加 「target=”_blank”」的强制方式让链接在新窗口打开,我们还有哪些方法呢?&/p&&ol&&li&单击鼠标中键可以新窗口打开&/li&&li&在链接上单击右键,然后选择「在新窗口打开链接」或者「在新标签打开链接」&/li&&li&按住键盘上的 Ctrl/Command 单击链接,&strong&新标签&/strong&打开链接&/li&&li&按住 Shift 单击链接新,&strong&新窗口&/strong&打开链接&br&&img src=&/ad5ae90ed8fc_b.jpg& data-rawwidth=&270& data-rawheight=&344& class=&content_image& width=&270&&&br&&/li&&/ol&&p&OK,总结完毕,想要知道怎么样才是比较好的方式,必须做到知己知彼。知道了这些方式之后,我们可以尝试做一些细节优化了。&/p&&p&比如可以尝试通过 JS 判断用户 点击鼠标中键,Ctrl/Command+单击,右键菜单+新标签打开几种方式的次数,然后弱提示用户:亲,可以试试勾选「新标签打开链接」哦,这样单击就可以新标签打开了哦!(然后可以提供两个选项:1.我试试,2.不再提示我)&/p&&p&怎么样让这样的提示不会影响用户的正常浏览,同时又能引导用户使用这些浏览器自带的功能,在文案和引导方式上需要下点功夫了。&/p&&p&例如 QQ空间 当用户放大了页面的时候会有这样的提醒(还记得那个老板找谈话问为什么页面错位的问题吗?):&/p&&img src=&/a5f00cc5d56e216aa5e16b59a817ab91_b.jpg& data-rawwidth=&737& data-rawheight=&95& class=&origin_image zh-lightbox-thumb& width=&737& data-original=&/a5f00cc5d56e216aa5e16b59a817ab91_r.jpg&&&br&&p&人文关怀与产品的博弈无处不在,不是吗?&/p&&p&举个切身实际的栗子:&/p&&p&我们每个人每天都会和搜索引擎接触,我用 Google 的过程是这样的:&/p&&p&输入搜索关键词→中键点击所有感兴趣的链接(注意此时依然是在当前页面,中键点击的链接是在后台打开的)→然后再分别阅读之前打开的页面→关闭不需要的或者看过的页面&/p&&p&这里有个关键是「后台打开链接」的功能,搜狗等国内浏览器默认也提供的这样的功能:&/p&&img src=&/46cefd06488eabbd4c2e6f77f1cdaf2e_b.jpg& data-rawwidth=&326& data-rawheight=&67& class=&content_image& width=&326&&&br&&p&注意如果不是后台打开新标签,我们就需要不停的在搜索结果页面和新打开的页面之间切换,这是一个很头疼的问题,所以搜狗等浏览器才有了这样的功能,这是很有爱的。&/p&&p&一些是否关于新窗口打开链接的讨论:&/p&&ol&&li&&a href=&/question/& class=&internal&&乎上你点开一个问题时,常是直接左键打开,还是右键打开新窗口?&/a&&/li&&li&&a href=&///?target=http%3A///%3Fp%3D6063& class=& wrap external& target=&_blank& rel=&nofollow noreferrer&&减少新开窗口提升可访问性&i class=&icon-external&&&/i&&/a&&/li&&li&&a href=&/question/& class=&internal&&知乎里面提问或回答中的 url 链接加一个 target=”_blank” 是不是会更好?每次后退好麻烦。&/a&&/li&&li&&a href=&///?target=http%3A//goodboy5264./blog/static//& class=& wrap external& target=&_blank& rel=&nofollow noreferrer&&链接应该在新窗口打开吗?&i class=&icon-external&&&/i&&/a&&/li&&li&&a href=&/question/& class=&internal&&一个网页如何决定是当前页打开还是新窗口打开?&/a&&/li&&li&&a href=&/question/& class=&internal&&有多少人习惯用鼠标中键点击,在什么情况会用?&/a&&/li&&li&&a href=&///?target=http%3A///note//& class=& wrap external& target=&_blank& rel=&nofollow noreferrer&&新窗口打开 VS 当前窗口打开 — 浅谈页面链接打开方式&i class=&icon-external&&&/i&&/a&&/li&&/ol&&p&以上&br&一丝&/p&
引用我的博文 《》新窗口还是当前窗口打开,一直以来颇具争议。诚然,任何不分场景的强制使用某一种方式都是耍流氓。这里我就不一一分析场景了,这也需要用户研究同学提供的数据作为参考。在对用户使用场景做出了合理分析之后,我觉得…
来自子话题:
前面的回答合理的理由已经说了很多,这里补充一点作为浏览器开发者的看法 (我现在是 Opera 的员工,但我的意见不代表我的雇主的看法,我也不会讨论 Opera 开发情况的细节。)&ol&&li&Google Chrome 的开发者 Alex Russel 在 Quora 回答过这个问题: &a href=&///?target=http%3A///Google/How-large-is-the-Google-Chrome-team& class=& wrap external& target=&_blank& rel=&nofollow noreferrer&&Google: How large is the Google Chrome team?&i class=&icon-external&&&/i&&/a& 由于现今 Web 标准的庞杂,任何一个公司想建立一个有竞争力的浏览器开发团队都需要维护一个很大而且很有经验的引擎开发团队。而没有足够的投资和良好的公司文化是很难吸引到这样的团队的。换来的好处是这个公司对自己的引擎和自己要支持的技术有最终的决定权,对 W3C 和其他 Web 标准组织的标准制定有足够的发言权,如果不维护自己的浏览器引擎,这两点是无法得到保证的。从现在的竞争看,一个专门的浏览器公司的生存空间已经很小,大部分浏览器都是一个大公司为了扩展自己的竞争力而附属开发的 (Apple, Google, Microsoft, 腾讯, 360, 阿里, Yandex 等等)。&/li&&li&但是同时独立的浏览器公司往往能够比较灵活地确定开发目标,更多地做一些和短期增长没有直接联系的创新,Mozilla 和 Opera 都是如此。Mozilla Labs 长期进行很多不一定会进入 Firefox 发布的试验性功能,甚至 Rust 和 Servo 这种堪称宏伟的试验性项目,以及一系列的“猴子”项目 (从 SpiderMonkey 到 IonMonkey) 推动了 JavaScript 技术的进展。从 Trident 的 JScript 引擎到 Mozilla 的 SpiderMonkey,到 Apple 的 JavaScriptCore,到 Google 的 V8,再到 Mozilla 的最新进展 (&a href=&///?target=http%3A//& class=& wrap external& target=&_blank& rel=&nofollow noreferrer&&ARE WE FAST YET?&i class=&icon-external&&&/i&&/a&),这种迭代的创新是很难由单一公司推动的,只有可能在多引擎竞争下才可能实现。&/li&&li&具体到 WebKit 的单一文化,从浏览器开发者的角度我在 &a href=&///?target=http%3A///b/standardizing-on-webkit& class=& wrap external& target=&_blank& rel=&nofollow noreferrer&&Standardizing on WebKit&i class=&icon-external&&&/i&&/a& 解释过一点,Apple 和 Google 的主宰性控制、和这个项目的一些陈旧的历史 (多编译系统、使用 Subversion) 实际上已经妨碍了很多革命性创新的出现,&a href=&///?target=https%3A///item%3Fid%3D5213200& class=& wrap external& target=&_blank& rel=&nofollow noreferrer&&Doing this would mean being forever stuck in single-threaded land for rendering ...&i class=&icon-external&&&/i&&/a& 也是个补充,WebKit 的并行化发展迟滞,但是回过来想,假如没有 Google 支付给 Mozilla 钱,Mozilla 又从哪里来投资 Servo 这样的项目呢?假如 Mozilla 被 WebKit 单一文化边缘化,Google 很有可能不再支付捆绑搜索引擎的费用,所以 Mozilla 要保持这种创新而不更多关注短期增长是很需要勇气的 (所以你可以理解为什么 Robert O'Callahan 和其他 Mozilla 的朋友这么失望)。&/li&&/ol&
前面的回答合理的理由已经说了很多,这里补充一点作为浏览器开发者的看法 (我现在是 Opera 的员工,但我的意见不代表我的雇主的看法,我也不会讨论 Opera 开发情况的细节。)Google Chrome 的开发者 Alex Russel 在 Quora 回答过这个问题:
完全不用安装最新版的 Chrome,只需要将 Flash 组件安装一下最新版即可。&br&并且这里需要的不是网上随处可见的 NPAPI 版本,而是冷门的 PPAPI 版本。&br&&br&请收藏好这个链接,是某位大牛从 Flash 的在线安装包中提取出来的,每一次访问,下载的都是最新版的 PPAPI 版 Flash:&br&&a href=&///?target=http%3A///pub/flashplayer/latest/help/install_flash_player_ppapi.exe& class=& wrap external& target=&_blank& rel=&nofollow noreferrer&& 的页面&i class=&icon-external&&&/i&&/a&&br&&br&下载好后安装一下,再进入 chrome://plugins/,点击右上角的详情按钮,停用旧版本,启用新版本 Flash,即可。
完全不用安装最新版的 Chrome,只需要将 Flash 组件安装一下最新版即可。并且这里需要的不是网上随处可见的 NPAPI 版本,而是冷门的 PPAPI 版本。请收藏好这个链接,是某位大牛从 Flash 的在线安装包中提取出来的,每一次访问,下载的都是最新版的 PPAPI 版…
首先必须强调:&b&WebKit不是Chromium&/b&,而且它是苹果的,不是Google的。Bill Cheng的回答太具有误导性了。&br&&br&WebKit只是一个HTML解析器。底层你用什么来解析HTML?这跟你做开发的时候,选什么库来解析XML、json啥啥的,是一样的问题。这早就不是浏览器的技术核心了。那么既然如此,有开源项目可以用,而且还做得不错,干嘛要自己开发呢?这跟做电脑不用自己生产CPU,做手机不用自己搞通讯芯片,是一个道理。&br&&br&Chromium的成功恰恰在于,它一开始就很有勇气地放弃了所谓的“自主开发内核”,即使采用对手苹果的内核,都在所不惜。Chromium做了很多东西:多进程异步UI、沙箱、skia界面库、自有http协议实现,另外还有大名鼎鼎的V8 JavaScript引擎,这些都是WebKit所不具备的。至于浏览器的界面、功能、插件体系,更是和WebKit八竿子打不到一块。如果你看过Chromium的源代码,你会发现WebKit只占其中很小的一部分。&b&Chromium不是靠采用WebKit赢的,是靠它在WebKit基础上做出了自己的特色而赢的。&/b&&br&&br&Opera采用WebKit是好事,放下包袱后,希望它也能像Chromium一样做出自己的特色。浏览器厂商们都应该把精力放在真正有价值的事情上去,而不是把“HTML文档 -& 可视化”这一个简单的转换,做一套又一套不同的实现。往大里说,社会分工越来越细致,总是一种进步。
首先必须强调:WebKit不是Chromium,而且它是苹果的,不是Google的。Bill Cheng的回答太具有误导性了。WebKit只是一个HTML解析器。底层你用什么来解析HTML?这跟你做开发的时候,选什么库来解析XML、json啥啥的,是一样的问题。这早就不是浏览器的技术核心…
来自子话题:
早上看到贺老出马,也忍不住写了一篇来谈一下苏宁这样的公司对这方面的考虑。&br&&br&
近两年来,我一直在思考如何改进前端体系的开发模式,这里面最基础的一点就是前后端的分离。谈到前后端分离,也有一个误区,认为仅仅是以浏览器作分界,把这两部分的代码分离出来。但其实是,做这件事情的本意,是要解决开发模式的问题,也就是要分离前后端开发人员的职责。&br&&br&
针对不同类型的Web产品,这个分离方式是有所不同的。对于Web应用,因为它跟服务端的交互基本就是AJAX或者WebSocket接口,所以这个分离是天然的,整个前端基本都是静态HTML模板,JavaScript模块,以及CSS和相关静态资源,但是对于网购产品这样的形态,它的做法就不一样。&br&&br&## 展示占主要部分的产品&br&&br&
网购产品的展示需求很重要,图片等资源载入非常多,但相对的操作却很少,基本只有搜索商品,加购物车,结算这样的环节。传统这样的产品,多半是这么个工作流程:&br&&br&
交互出高保真图,前端去切图,生成静态HTML加展示效果,然后,注意,他不是自己接着往下做,而是交给另外一群开发人员,把它转换成服务端模板,比如freemarker或者velocity之类,或者是smarty,为什么要这么做呢?因为这类产品讲究一个首屏优化,是首屏而不是首页,这就意味着对于首屏来说,经过的环节应当尽可能少,比如说,就不能先载入客户端模板,再AJAX一个数据,然后去渲染一下。这么做的性能肯定是不如服务端把HTML生成好,然后一次请求加载的。&br&&br&
这个过程肯定是有一些问题的,比如说,如果开发人员B在套模板的过程中,发现原先的静态HTML部分有问题,应该怎么办?大家知道,一个对HTML和CSS都很熟悉,同时又可以写业务逻辑的前端开发人员是很稀缺的,所以,多数情况下,这两边的技能是不同的,如果是简单的页面问题,这个开发人员可能自己也就解决了,如果他解决不了,怎么办?&br&&br&
如果B自己不改,把他已经搞成服务端模板的代码返回给前端人员A,A也没法下手,因为已经是服务端模板,A手里没有环境,改了之后不知道对不对,不能预览。那么,B把问题告诉A,A修改他的原始版本,然后再拿给B又怎样呢?这时候B又麻烦了,他要对比两次修改的部分,把自己前一阵的修改合并进去。&br&&br&
所以,不管怎么搞,这里面都很折腾。&br&&br&
Midway这个产品,他想要解决什么问题呢?既然说前端人员没法预览模板的原因是,后端在使用服务端模板,那么,我能不能找一种两边都可用的模板,你能在服务端渲染,我也能在客户端预览?服务端跟浏览器端同时都能运行的语言是什么?只有JavaScript。&br&&br&
所以,大家就往nodejs里面去发掘了,一个普通的JavaScript模板库,它在浏览器端也可以渲染,在nodejs端也可以输出成HTML,这时候,那些原来负责整合模板和逻辑的人员改用nodejs,是不是就解决这问题了?&br&&br&
想象一下这个场景多么美好:前端来决定某个模板是服务端渲染还是客户端渲染,当首屏的时候,就在nodejs里面生成HTML,不是首屏的时候,就AJAX过来在浏览器端渲染展示。&br&&br&
从技术方案上看,这么做很好了,工程上又带来另外一些问题,那就是对熟练JavaScript开发人员的需求量大增。对阿里这样的公司来说,前端有大几百人,别的公司只能仰望,所以他当然可以放手一搞,但对我们苏宁这样,前端人数不大的,就麻烦了。如果我们也引入这样的方案,就面临把很大一部分Java开发人员转化成JavaScript开发人员这么一个问题,这个事情短期内肯定是无法解决的,所以反过来会增加前端这边的压力。所以暂时还用不了阿里这样的方案,只能努力先提高人员水平再看情况。&br&&br&
服务端引入nodejs还有别的优势,比如说请求合并等等,这个也可以用其他方式变通解决,比如加一个专门的跟现有后端同构的Web服务器,在那边干这些事。&br&&br&## 展示和业务逻辑较均衡的产品&br&&br&
对于另外一些场景,也有类似的问题,比如支付产品,展示相对没那么重,但是又算不上Web应用,它面临另外一种情况的前后端分离。这种场景下,前端的出静态HTML和DOM操作类的JavaScript,业务开发人员负责写后端,还有另外一部分业务逻辑的JS。&br&&br&
这里的问题是什么呢?是jQuery式代码造成的协作问题。比如说:&br&&br&&div class=&highlight&&&pre&&code class=&language-text&&$(&.okBtn&).click(function() {
$.ajax(url, data)
.success(function(result) {
$(&someArea&).html(_.template(&tpl&, result));
&/code&&/pre&&/div&&br&
因为前端人员的稀缺,所以他不可能帮你把业务逻辑写出来,所以说,这里面$.ajax往里的部分,要业务人员自己写。然后,数据得到之后,又要去处理界面部分。&br&&br&
很多场景下,处理界面远不是这么搞个模板放上去就完事的,所以业务开发人员感到很烦闷,为了这么一点小问题,反复去找前端的人来搞,很麻烦,自己搞又特别花时间,所以都很苦闷。&br&&br&
这同样是一种前后端的分离,只是这个分界线不在浏览器,而在于:是否写业务逻辑。对付这种场景,解决办法就是加强JavaScript代码的规划。现在流行那么多在前端做MV*的框架,不考虑Angular这类太重量级的,来看看Backbone这样的,它到底解决了什么问题?&br&&br&
很多人说,Backbone虽然小,但根本不解决问题。这句话有一定道理,但前提条件是你自己的JavaScript代码分层已经做得很好了。如果做得不好,它就可以协助你解决分层的问题。&br&&br&
刚才那段代码,它的问题在哪里呢,在于职责不清晰。一个函数只能做一件事,这是共识,但由于回调等方式,所以不经意就破坏了函数的单一性、完整性。我们试试来拆开它。&br&&br&
对于一个后端开发人员来说,他为什么常常害怕写前端代码?是因为JavaScript语言吗?其实不是,我们用来写业务逻辑的时候,只会使用JavaScript一个很小的子集,对于这个子集来说,它并不存在多大的学习困难,最麻烦的地方在于DOM、BOM等东西,对于一个后端开发人员来说,如果要求他在掌握服务端代码编写的同时,还要去学这些,那真是有些不容易,所以,我们来给他省点事。&br&&br&
现在我们的出发点是,把这段代码拆给两个不同的人写,一个人操作DOM,另外一个人只写逻辑,绝对不操作DOM。前面这个代码拆给前端维护,后面这个拆给业务开发人员。&br&&br&
最老圡的方式:&br&&br&
a.js&br&&div class=&highlight&&&pre&&code class=&language-text&&$(&.okBtn&).click(function() {
function a1(result) {
$(&someArea&).html(_.template(&tpl&, result));
&/code&&/pre&&/div&&br&
b.js&br&&div class=&highlight&&&pre&&code class=&language-text&&function b1(data) {
$.ajax(url, data)
.success(a1);
&/code&&/pre&&/div&&br&
现在大家是不是相安无事了?&br&&br&
如果这么做的话,AB双方要做很多约定,也就是说,这个过程仍然是一个螺旋链。比如说,A先写点击事件的绑定,然后想起来这里要调用一个请求,就去找B写b1方法。B在写b1的时候,又想到他要调用一个界面展示方法a1,然后又来找A写,来回也挺折腾。&br&&br&
况且,有这么一天,A在另外一个地方也想调用b1了,但是由于b1的回调已经写死了,比较蠢的办法就是在a1里面再判断,这是什么东西点击造成的,然后分别调用不同的回调。如果情况复杂,那这个代码写出来真是没法看。&br&&br&
如下:&br&&br&
a.js&br&&div class=&highlight&&&pre&&code class=&language-text&&var type = 0;
$(&.okBtn&).click(function() {
$(&.okBtn1&).click(function() {
function a1(result) {
if (type1) {
$(&someArea&).html(_.template(&tpl&, result));
else if (type2) {
&/code&&/pre&&/div&&br&
b.js&br&&div class=&highlight&&&pre&&code class=&language-text&&function b1(data) {
$.ajax(url, data)
.success(a1);
&/code&&/pre&&/div&&br&
稍微好一些的办法是,在b1中,直接返回这个请求的promise,这样可以由调用方决定到底该干什么。&br&&br&
如下:&br&
a.js&br&&div class=&highlight&&&pre&&code class=&language-text&&$(&.okBtn&).click(function() {
b1(data).success(function(result) {
$(&someArea&).html(_.template(&tpl&, result));
$(&.okBtn1&).click(function() {
b1(data).success(function(result) {
&/code&&/pre&&/div&&br&
b.js&br&&div class=&highlight&&&pre&&code class=&language-text&&function b1(data) {
$.ajax(url, data);
&/code&&/pre&&/div&&br&
如果要对返回数据作统一处理,也可以很容易地在b1中,用promise重新封装了返回出来,只不过这样在a.js里面,直接调用的就不是success,而是then了。&br&&br&
注意到这样的代码还有问题,比如说大量的全局函数,不模块化,容易冲突。此外,没有一个地方可以缓存一些共享数据,比如说这么一个场景:&br&&br&
界面上两个块M和N,其中,M初始载入并加载数据,N在初始的时候不载入,而是在某个按钮点击的时候载入,而M和N中各有一个列表,数据来源于同一个服务端请求。&br&&br&
现在就有个问题,当N载入的时候,它的数据怎么来?比较老土的方式,肯定是载入N的时候,同时也再去请求一下数据,然后渲染到N上。&br&&br&
从一个角度看,如果说不重新请求,N的这个数据应当从哪里来?从另外一个角度看,如果重新请求了,发现数据跟之前的产生了变更,是否要同步给M,怎么同步给它?&br&&br&
我们看看类似Backbone这样的框架,它能提供怎样的机制呢?或者如果我们不用它,怎么自己把这个分层封装得更好一些?&br&&br&
首先,是建立一个数据模型,在它上面添加数据的缓存:&br&&div class=&highlight&&&pre&&code class=&language-text&&define(&model&, [], function() {
var Model = {
data: null,
queryData : function(param, fromCache) {
var defer = q.defer();
if (fromCache || this.data) {
defer.resolve(this.data);
var self =
this.ajax(url, param).success(function(result){
self.data =
defer.resolve(result);
return defer.
&/code&&/pre&&/div&&br&
这么一来,我们在模型上作了数据的缓存,如果调用的时候加fromCache参数,就从缓存读取,否则就请求新的。为了在两种情况下,调用方接口能保持一致,把整个函数封装成promise,以便接着调用。这里的模型定义成单例了,假定是全局唯一的,可以根据需要调整成可实例化的。&br&&br&
这个时候,视图层就要封装DOM和事件的关联关系:&br&&br&&div class=&highlight&&&pre&&code class=&language-text&&define(&view&, [&model&], function(Model) {
function View(element) {
this.element =
this.element.selector(&.okBtn&).click(function() {
var self =
var fromCache =
Model.queryData({}, false).then(function(result) {
self.renderData(result);
View.prototype = {
renderData: function(data) {
this.element.selector(&someArea&).html(_.template(&tpl&, result));
&/code&&/pre&&/div&&br&&br&
这个时候,多个视图实例的情况下,数据也能够较好地利用。&br&&br&这样,前端写这个View,后端写Model,可以作这么个分工。&br&&br&
这个只是很简陋的方式,在复杂场景下还有很多不足,在这里先不展开了。更复杂的场景也就是类似Web应用那种方式,稍后专门写一篇来展开。&br&&br&## 小结&br&&br&
我们再来回顾前后端分离所要解决的问题,是分离前端和业务开发人员的职责,这个方案怎么定,是应当随着团队状况来确定的。比如阿里前端厉害,人多势众,他的前端就要往后推,去占领中间层。我们苏宁这样的公司,前端比较薄弱,只能在很多场景下,让出中间层,否则战线铺太广只能处处被动。&br&&br&
同一个中途岛,在不同的形势下,占还是不占,是很考验前端架构师的一个问题。&br&&br&对阿里的这种实践,我们会持续围观,寻找并创造合适的出手时机。
早上看到贺老出马,也忍不住写了一篇来谈一下苏宁这样的公司对这方面的考虑。
近两年来,我一直在思考如何改进前端体系的开发模式,这里面最基础的一点就是前后端的分离。谈到前后端分离,也有一个误区,认为仅仅是以浏览器作分界,把这两部分的代码分离出…
浏览器安全其实是一个非常复杂的问题。 很大程度上是由浏览器自身的定位决定的, 试想一下,一个拥有几乎所有系统访问权限的APP ( 拜device API所赐, 浏览器需要访问诸如摄像头,麦克风等很多敏感才能支持这组API),
居然需要从鱼龙混杂的互联网下载不知道谁写的页面+脚本然后本地执行,并且要保证执行的脚本不该看的不看,不该拿的不拿。
&br&&img src=&/6ab6cc5a9aeed8231bdd5ab68f01daa9_b.jpg& data-rawwidth=&865& data-rawheight=&395& class=&origin_image zh-lightbox-thumb& width=&865& data-original=&/6ab6cc5a9aeed8231bdd5ab68f01daa9_r.jpg&&&br&&b&浏览器自身设计&/b&&br&&br&事实上,第一批浏览器, 比如 Internet Explorer,
Firefox (Netscape), 在最初的设计的时候,都没有能预见到互联网会以如此爆发性的速度发展, 同时也受制于硬件条件的限制, 无一例外的采用单块结构(monolithic architecture). 所谓的单块结构,就是浏览器的每个模块,都塞在一起,而没有明确的隔离。 这种做法代码执行高效,写起来也很方便,不过现在看起来, 如果从安全的角度来讲,则是很有问题的。
&br&&img src=&/efc85165f31bfaadb33ec3e_b.jpg& data-rawwidth=&865& data-rawheight=&303& class=&origin_image zh-lightbox-thumb& width=&865& data-original=&/efc85165f31bfaadb33ec3e_r.jpg&&&br&要知道浏览器里面有非常多的模块, 有一些模块专门处理从网络上下载下来的内容, 比如文档解析器, 文档布局器,或者是Javascript的执行。 又有一些只和本地系统接口, 比如文件访问,密码的存储, 剪贴板一类的。 如果全都放在一起, 那简直就是给网上下载下来的恶意脚本开了一扇便利之门。 一个更好的架构是把这两组模块分别隔开。然后把第一组专门处理网络下载内容的模块用沙箱一类的技术装起来。
&br&&br&现代的浏览器, 比如谷歌的Chromium, 或者使用Chromium框架的浏览器, Opera 桌面(版本12以后) 和 Opera mobile 一类的, 都是采用的这种结构,基本上可以把很多潜在的安全风险扼杀在摇篮之中。
&br&&br&想了解详情的同学可以参考 &a href=&///?target=http%3A//seclab.stanford.edu/websec/chromium/chromium-security-architecture.pdf& class=& external& target=&_blank& rel=&nofollow noreferrer&&&span class=&invisible&&http://&/span&&span class=&visible&&seclab.stanford.edu/web&/span&&span class=&invisible&&sec/chromium/chromium-security-architecture.pdf&/span&&span class=&ellipsis&&&/span&&i class=&icon-external&&&/i&&/a&&br&&br&在这种比较干净的架构出来之前,各家浏览器基本上都是修修补补, 或者直接就是拿产品特性说事儿,比如Firefox说明自己比较安全的原因基本上是 : 我的独立(没有和操作系统集成), 也不像IE一样往死里做(不支持Active X 插件一类的奇葩东西)参见
&br&&br&&a href=&///?target=http%3A//website-archive.mozilla.org/www.mozilla.org/security/security/security-announcement.html& class=& wrap external& target=&_blank& rel=&nofollow noreferrer&&Security Announcement&i class=&icon-external&&&/i&&/a&&br&&br&而Opera 在Presto 时代, 则在内部的代码规范里面明确规定任何情况下不能是用栈上缓存,从而杜绝当年极其流行的栈上缓存溢出攻击。
&br&&a href=&///?target=http%3A//en.wikipedia.org/wiki/Stack_buffer_overflow& class=& external& target=&_blank& rel=&nofollow noreferrer&&&span class=&invisible&&http://&/span&&span class=&visible&&en.wikipedia.org/wiki/S&/span&&span class=&invisible&&tack_buffer_overflow&/span&&span class=&ellipsis&&&/span&&i class=&icon-external&&&/i&&/a&&br&&br&到了手机浏览器时代,硬件和操作系统本身的安全性都加强了。 硬件方面从x86转到arm, 天生就对栈上缓存溢出免疫。 基于*nix 结构的iOS 和Android 自带沙箱结构,于是浏览器本身也被沙箱装了起来. 所以技术上来讲,由于多了两层壁垒,手机浏览器普遍要比桌面浏览器安全,
桌面浏览器上的那种首页书签搜索引擎各种被乱七八糟改的情况在手机浏览器上面基本看不到。 当然,国内大部分的手机浏览器还是单块结构,单块结构能有的问题一个也都没有少。 Chrome/Opera mobile/ 欧朋X+ 这种基于Chromium 架构的浏览器安全性相对来讲会好一些 .
&br&&br&所以选择一个安全的手机浏览器其实没有那么复杂,国际一般比国内的在安全方面的意识要强一些。大牌一点的浏览器在遇到通用性安全漏洞时 (比如上次著名的heart bleed漏洞)反应时间比小的浏览器厂商会快一些。
&br&&br&&b&浏览器和网站之间的数据传输&/b&&br&&br&上面说谈的其实讲的都是浏览器如何面对网站上面的恶意代码保证自己不被黑掉。浏览器还有一块非常大的安全区域是在于数据传输. 比如大家都不希望自己的银行密码被除了网上银行之外的其他人看到。
&br&&br&3.15晚会里面的wifi钓鱼演示其实就是展示数据传输中数据被第三方窃取的可能性,这个可能是陈老湿们最不愿意看到的事情。浏览器的世界里面对于数据传输有两种主要的方式
&br&HTTP (超文本传输协议) 和 HTTPS (安全传输协议).
&br&&br&其中 HTTP 与其说是不安全,不如说是令人发指的不安全。因为 HTTP 不仅仅是明文传输,而且是用文本来传输的,就是说,传输的报文,直接人就可以读得懂。
&br&&br&Authorization: Basic QWxhZGRpbjpvcGVuIHNlc2FtZQ==&br&&br&这个是在HTTP里面发送给服务器用户名+密码的报文( 来自于wikipedia ) . 基本就是明晃晃的告诉别人,你看, 我的密码在这里哦,然后拿base64编了一下码,就发将在广袤的互联网上了。注意哦, 这个是编码不是加密,没有任何安全性可言的。
&br&&img src=&/1f65f545ceca046eb0eb14e9b5ef0577_b.jpg& data-rawwidth=&865& data-rawheight=&637& class=&origin_image zh-lightbox-thumb& width=&865& data-original=&/1f65f545ceca046eb0eb14e9b5ef0577_r.jpg&&&br&HTTPS 会好非常多, HTTPS 的数据是加密传输,加密的强度也不小,很多银行都在使用,对于一般的攻击是免疫,。&br&&br&当然 BOSS 级别的 NSA 不在此列, 因为HTTPS 虽然理论上不能破解,但是NSA丧心病狂的在HTTPS用的硬件随机发生器中植入了后门
&br&&br&详情参见 &a href=&///?target=http%3A//en.wikipedia.org/wiki/Bullrun_%28decryption_program%29& class=& wrap external& target=&_blank& rel=&nofollow noreferrer&&Bullrun (decryption program)&i class=&icon-external&&&/i&&/a&&br&&br&有一些浏览器。 比如 Opera Mini 或者带有 Opera turbo 技术的浏览器 提供端到端的私有加密。这一类的浏览器在安全性方面会有加分。
&br&&br&PS: 关于国内浏览器采集用户隐私数据问题(IMEI, IMSI)等。
&br&&br&多说两句这个, 作为国内App的从业人员,App(包括浏览器)采集IMEI, IMSI已经是一个非常普遍的现象,事实上,你其实很难找到不采集的APP,
想要知道一个APP是否采集IMEI, IMSI,只需要打开应用的权限管理,看看有没有这一项就可以了。
&br&&br&&img src=&/36b93c0e8e3bc75f56045_b.jpg& data-rawwidth=&900& data-rawheight=&255& class=&origin_image zh-lightbox-thumb& width=&900& data-original=&/36b93c0e8e3bc75f56045_r.jpg&&&br&而这种行为,其实更多的是由国内的App推广市场的情况决定的,大部分APP(包含浏览器)对你的IMEI并没有多大兴趣,如果真的想要,混淆以后也能用。只是在国内的推广渠道里面,统计,对账的数据都是基于IMEI的。这个决定了大部分App如果想被推广,一定是需要采集IMEI的。并非是想采集用户隐私。
&br&&br&当然地理位置数据采集就更普遍了,浏览器采集这个其实很大程度上是为了支持HTML5 中的Geolocation 组件。Chrome 也会采集。
&br&&img src=&/21f03459bdcc3ecca8079790_b.jpg& data-rawwidth=&900& data-rawheight=&940& class=&origin_image zh-lightbox-thumb& width=&900& data-original=&/21f03459bdcc3ecca8079790_r.jpg&&&br&这个行为其实和你去银行开个信用卡, 银行会要你的身份证复印件是一个道理, 这里面的安全问题不在于银行是否采集你的身份证复印件,而是采集完了以后,有没有能力/意识把你的信息放在一个安全的地方。 而国内大部分App如果出了问题,都是出在数据保存上。选择的原则还是一样,尽量选者大的,安全记录好的公司。
&br&&br&利益相关:Opera 软件开发工程师。
浏览器安全其实是一个非常复杂的问题。 很大程度上是由浏览器自身的定位决定的, 试想一下,一个拥有几乎所有系统访问权限的APP ( 拜device API所赐, 浏览器需要访问诸如摄像头,麦克风等很多敏感才能支持这组API), 居然需要从鱼龙混杂的互联网下载不知…
来自子话题:
绝对&b&没有&/b&必要。&br&&b&【更新:&/b&楼下那些说有必要的,麻烦你们切题清楚点,你们自己要兼容IE6你公司可能是为此付钱给你,但是提问者还是在校生,有人付钱让他&b&学习&/b&兼容IE6吗?&b&】&br&&/b&&br&目前(2012年10月)IE6、IE7的市场占有率即使在最小白的市场,份额也下降到了25%以下。考虑你还是在校生,意味着你进入可以承担较为独立的工作岗位时,至少还有2年以上时间,届时IE6、7的占有率估计至少将跌至10%以下,甚至可能小于5%。这意味着届时只有很少的互联网产品才会考虑兼容,比如那些最最基础的互联网应用和网站,而这类网站、应用往往都是已经非常成熟的codebase,没你什么事。&br&&br&另外,作为在校生,我不建议你现在就确定前端开发方向。前端开发的职业前景并不乐观。如果你想从事编程类工作,最好是把计算机基础打好,例如数据结构、算法、编译原理等。甚至好好学习下互联网基础协议,比如HTTP(1.1和未来2.0草案),绝对比花时间在IE6、7上有价值。
绝对没有必要。【更新:楼下那些说有必要的,麻烦你们切题清楚点,你们自己要兼容IE6你公司可能是为此付钱给你,但是提问者还是在校生,有人付钱让他学习兼容IE6吗?】目前(2012年10月)IE6、IE7的市场占有率即使在最小白的市场,份额也下降到了25%以下。…
断网后那个恐龙可以当游戏玩
断网后那个恐龙可以当游戏玩

我要回帖

更多关于 微信内置浏览器 的文章

 

随机推荐