谋智社区

火狐浏览器在中国

Archive for '颠覆网络35天' Category

Next Page »

颠覆网络35天 ─ TraceMonkey

20 August 2009

这个系列的翻译停了好久,:( 其实是心有余力不足,呵呵。这几天看到Hacks不断出来非常棒的文章,所以还是尽量翻译一些,坚持这个系列。不过就不保证顺序了,呵呵──主要也是这篇讲述TraceMonkey的文章太棒,想先翻这一篇 原文地址:an overview of TraceMonkey 系列地址:颠覆网络35天 ==================================== 本文作者为David Mandelin,──Mozilla JavaScript团队工作人员。 Firefox 3.5拥有一个全新的JavaScript引擎,叫做TraceMonkey,在该引擎上跑JS应用要比Firefox 3快到3-4倍,从而为现有的网络应用加速。这篇文章大致的描述一下在TraceMonkey中包括的重要部件,以及他们是如何加速JavaScript 的。同样,在了解这些之后,你也就能知道什么样的网络应用通过TraceMonkey能够获得最大的提速,以及怎么样来写您的程序获得更大的性能提高。 为什么提速JS很难:动态类型 类似于JavaScript和Python这样的高级动态语言通常使得编程效率非常高,但是同类似Java或者C这样的静态语言相比,他们要慢一些。按照经验来说,一个JS程序通常要比同等的Java程序慢10倍。 像JS这样的动态语言比像Java或者C这样的静态语言慢主要有两个原因。第一个原因是在动态语言中,通常不太容易在执行之前知道值的类型信息。因此,语言本身必须使用一个通用的格式存储所有的值并且使用通用的操作来处理他们。 相反,在Java中,程序员声明变量和方法的类型,编译器可以在运行之前就知道这些值的类型。编译器可以使用特定的格式和操作来处理这些值,而这个过程要比通用的格式和操作快很多。下面,我会把这类操作叫做类型特定处理。 动态语言运行慢的第二个原因是,动态脚本语言通常实现为解释器,也就是由解释器执行;而静态语言通常被编译为原生代码。解释器可以很容易的构造,但 是他们需要额外的运行时间来处理跟踪他们的内部状态。像Java这样的语言会被编译成机器语言,基本上是不需要内部运行状态跟踪的。 让我们用一张图片来描述的更具体。这里有一个简单的加法的分解动作示意图,我们来计算一下:a + b,这里a和b均为整数。首先,我们忽略最右边的柱状图,集中在Firefox 3的JavaScript解释器和Java JIT执行效率的比较上。每个纵列都表示在某种语言上这个加法运算要做的分解动作。时间从上到下进行,每个不同颜色的盒子高度基本表示进行该分解动作需要的时间。 在中间,Java简单的运行一条机器指令:“加”命令,运行时间为T(一个处理器周期)。因为Java编译器预先知道运算值为标准的机器整数类型,她可以直接使用标准的整数加法机器指令。完了。 在左边,SpiderMonkey(FF3中的JS解释器)需要大概40个T。棕色部分的盒子部分为整个解释器的开销:解释器需要读取加操作,然后跳到解释器的通用加操作代码部分。橘色的盒子部分表示由于解释器不知道运算值的类型造成的额外工作。解释器需要解开a和b的通用描述格式,判断出他们的类型,选择特定的加法运算,把值转换为正确的类型,加法进行完之后,还需要把结果转换为通用的描述格式。 上面的图表显示,使用解释执行要比编译器慢一些,而使用不带任何类型信息的解释执行要慢很多。如果我们希望JS能够被运行的快一些,根据Amdahl定律,我们需要做点关于类型的事情。 通过跟踪获得类型 在TraceMonkey中,我们的目标是没有蛀牙,不对,我们的目标是编译出类型特定的代码。为了实现这个目标,TraceMonkey需要知道 变量的类型。但是JavaScript本身是没有类型的,而我们前面也说过JS引擎基本上是无法在运行前知道类型的,但是我们还要在运行之前编译出本地代 码,貌似无路可走了。 让我们换个角度来看这个问题。如果我们让程序在解释器中先跑一段,那么引擎就可以直接觉察到数值的类型了不是。然后,引擎可以使用这些类型来编译产生更快的类型特定的代码。最后,引擎就可以开始运行这些类型特定的代码,于是就运行的更快了~ 这个想法还有几个关键的细节。首先,当程序运行时,即便有很多的if语句和其他的程序分支,他始终在其中一个分支上。所以,引擎不太有机会觉察到方法中所有数值的类型──引擎通过路径来观察数值,我们称之为轨迹 Traces。因此,标准的编译器是对整个方法或者过程进行编译,而TraceMonkey是针对轨迹进行编译。运行期轨迹编译有个好处是在轨迹上的函数调用是内联inline的,这使得轨迹上的函数调用非常的快。 第二,编译类型特定的代码是占用运行时间的。如果一块代码仅仅会运行一次或少量的几次──这在网页代码中比较常见──他可能会占用更多的时间来编译和运行反而可能还不如直接在解释器里面运行来的快了。所以,他应该只去编译热代码(被运行很多次的代码)。在TraceMonkey中,我们通过跟踪循环来安排热代码。TraceMonkey开始在解释器中运行所有代码,并开始为循环记录轨迹中的热代码。 仅跟踪热循环代码结果之一就是:只运行几次的代码并不会在TraceMonkey中得到提速。而这通常不会影响实际运行效果,因为仅运行几次的代码通常很快就完事了,你可能都不会注意到他。另一个结果是那些不热的循环代码基本上不被运行,也不会被编译,从而节省编译时间。 最后,上面我们提到TraceMonkey是通过观察执行过程来判断数值类型,基本上算是事后诸葛亮的做法,可能并不能保证将来的结果──更准缺点 说算是事中诸葛亮:下次这部分代码被运行时,数值类型可能变了,或者第500次的时候开始变了也说不定。当我们已经产生好针对数字类型编译的代码之后,值 变成字符串类型了,那就糟糕了。所以,TraceMonkey必须在编译代码中加入类型检查。如果没有通过检查,TraceMonkey必须离开当前轨 迹,使用新类型重新编译这个轨迹上的代码。这就意味着拥有很多分支或者类型经常改变的代码在TraceMonkey中不一定能得到多少性能上的提高,因为 他需要花费运行时间来编译多出来的轨迹或者从这个轨迹跳到那个等等。 TraceMonkey操作起来~ 现在,我们通过一些示例来看一下TraceMonkey的实际操作情况:我们这里要完成的工作是把从1到N的整数都加到一个起始值上: function addTo(a, n) { for (var i = 0; i [...]

No Comments »

颠覆网络35天 ─ 文字阴影聚光灯

19 August 2009

原文地址:the text-shadow spotlight 系列地址:颠覆网络35天 ==================================== Zachary Johnson制作了另一个很炫的演示 has put together another fun demo。他使用JavaScript和text-shadow属性制作了一个聚光灯效果。已经被嵌入到下面了。如果看不到的话,查看他的博客文章。 使用Firefox 3.5观看演示

No Comments »

颠覆网络35天 ─ 使用localStorage保存数据

14 August 2009

原文地址:saving data with localStorage 系列地址:颠覆网络35天 ==================================== 本文作者为Jeff Balogh。Jeff就职于Mozilla的互联网开发团队。 localStorage是Web Storage互联网存储规范中的一部分,现在在Firefox 3.5中得到支持。localStorage提供了简单的 provides a simple Javascript API,用来在浏览器中持久化key-value键值对。应该注意的是不要同SQL数据库存储提案混淆,后者是另外单独的(同时也是有争议的) 互联网存储规范的一部分。键值对可以存储在cookie中,不过你一定不想这么做。Cookie在每次请求中都会被发送到服务器端,如果使用大数据集合的 话会有性能问题,同样也在传输中会有安全问题,而且也许你不得不为了处理这些数据特别写大量代码,例如把cookie像数据库那么使唤。 这里有一个简单演示,可以把textarea中的内容存储到localStorage。你可以改变文字,打开新标签页,可以看到更新过的内容。或者重启浏览器,你的文字还会在那里。 // 使用localStorage最简单的方式就是像一个正常对象那样的使唤他: >>> localStorage.foo = ‘bar’ >>> localStorage.foo “bar” >>> localStorage.length 1 >>> localStorage[0] “foo” >>> localStorage[‘foo’] “bar” >>> delete localStorage[‘foo’] >>> localStorage.length 0 >>> localStorage.not_set null 如果喜欢使用函数的话,我们也有类似的API: >>> localStorage.clear() >>> localStorage.setItem(‘foo’, ‘bar’) >>> localStorage.getItem(‘foo’) “bar” [...]

1 Comment »

颠覆网络35天 ─ 使用SVG和APNG制作动画纹理映射

13 August 2009

原文地址:using SVG and APNG to create an animated texture map 系列地址:颠覆网络35天 ==================================== 昨天我们介绍了使用SVG来映射3D数据的演示。今天我们再介绍一个Hans的演示:在浏览器中动态为动画添加纹理效果。 他使用了同之前文章中一样的技术,但是这次加载了一个动画PNG图片然后在图片上映射一个随机的图片纹理,这里使用了他的SVG 投影技术。结果非常赞!查看演示: 在Firefox 3.5中查看演示

No Comments »

颠覆网络35天 ─ nth-* Firefox 3.5中全新的CSS属性

12 August 2009

原文地址:new CSS3 properties in Firefox 3.5 – nth-* 系列地址:颠覆网络35天 ==================================== Firefox 3.5支持一些全新的CSS3选取器。在这篇文章中,我们会介绍其中的四个::nth-child,:nth-last-child,:nth-of-type 和 :nth-last-of-type。 这些选取器也被称作伪类,可以为已有的选取器增加风格。我们来看一些实际的例子。 :nth-child 这个伪类允许为一组元素添加风格。最常见的例子就是在表格中隔行高亮数据单元格: tr:nth-child(even) { background-color: #E8E8E8; } 实际的例子(需要Firefox 3.5): Row 1 Row 2 Row 3 Row 4 还可以使用特殊的标记来为超过两组元素添加风格。文档中对规则的描述不太准确,但是在例子中的“3”把元素分为三组,“+1”则是在组中的偏移量。在规范中还有很多例子。 tr:nth-child(3n+1) { background-color: red; } tr:nth-child(3n+2) { background-color: green; } tr:nth-child(3n+3) { background-color: blue; } 实际的例子(需要Firefox 3.5): Row 1 Row 2 Row [...]

No Comments »

颠覆网络35天 ─ 使用svg过滤器显示3D数据

11 August 2009

原文地址:using svg filters to display 3D data 系列地址:颠覆网络35天 ==================================== 本演示作者为Hans Schmucker,他为Firefox 3.5制作了大量有趣的演示。明天我们还会介绍另外一个他制作的演示。 Hans使用CSS的filter属性和SVG过滤器实现了很多有趣的演示──使用Voxel数据渲染3D透视效果。Han在演示结尾的评论凸显Firefox 3.5的各项特性: 老实说,开始没有认为这个演示会成功,主要是因为这个过滤器非常非常的长。为了产生一帧的效果需要处理大概30个运算操作 (要为5个图层每个图层做4个操作+纹理处理5个操作+纹理变换的3个操作等),然后处理的一帧要覆盖768×512大小的表面。总而言之,需要大量的处 理工作,同时还要在速度上满足需要,但是这些工作在Firefox上都被完成的太出色了。 如果您对背景知识非常感兴趣,也请查看Hans的文章:使用6行SVG代码渲染透视纹理──文中他解释了如何使用过滤器来制作这些效果。我们来看看这个演示,非常的有趣。 在Firefox 3.5中查看演示

No Comments »

Next Page »