相对CSS定位比JS定位更快吗?

时间:2015-05-23 15:45:37

标签: javascript css performance

我想知道JS在确定某些值时是否比CSS更慢,因为它们都必须进行相同的计算。

换句话说,如果我在%中为元素设置一个边距,它将使用其父元素的宽度作为基础。例如,margin: 50% = margin: 0.5 * parent.width。那么,在内部,浏览器必须根据父亲的宽度计算正确的边距,对吧?那么,这与JS中的计算有何不同?为什么CSS更快?什么内部CSS渲染使这些计算过程比JS更快?

Here is a fiddle。两个子div都是相同的,但是一个div的边距用CSS(margin: 20%)计算,另一个用JS计算:

var $cont = $("#container");
$("#js").css("margin", $cont.width() * 0.2);

考虑调整大小:CSS引擎在调整大小时也必须重新计算边距,对吗?

考虑加载时间:我只讨论实际执行时间。换句话说:

var $cont = $("#container");
    $("#js").css("margin", $cont.width() * 0.2);

VS

#css {margin: 20%;}

排除任何额外(库)加载时间。 jQuery和vanilla JS之间的区别不应该包含在答案中。我知道两者之间的性能差异。

2 个答案:

答案 0 :(得分:4)

这个问题会有一些模糊的答案,因为它非常依赖于浏览器。但是,可以相当安全地说CSS在这里通常会更快。

首先要注意的是,我们并没有将CSS作为一种语言的速度与JavaScript本身进行比较。在这个意义上,CSS不一定是executed。它的重点是指定浏览器核心原生的属性。浏览器可以解析一次,然后根据该规范执行任何操作。事实上,如果反复检查/执行相同的不变的CSS代码,它通常会是一个相当差的浏览器。

所以看待这个问题的一种方法是我们并不真正问为什么CSS比JavaScript更快。 CSS不是在这里进行计算的人。我们一直在问为什么原生网页浏览器比它可以运行的客户端JavaScript更快。

如果你把自己放在浏览器开发人员的手中,你可以在最初解析CSS文件时看到一个规范,即一个元素的相对大小应该是其父级的50%。

现在,您可以通过重新绘制,滚动和与之交互的方式,使用规范执行任何操作。您可以将该尺寸规格存储在核心数据结构的核心,甚至可以根据需要使用金属刮削汇编代码。您可以在从父级到子级的层次结构中向下递减的单个传递中计算此类相对大小子级的新绝对大小。您可以使用SIMD一次计算4个孩子的绝对像素大小。您可以根据初始属性规范执行任何操作。

使用JavaScript,我们没有这样的控制权。客户端脚本可以在这里执行任何操作,因此我们必须触发resize事件,如果JS端调整resize事件中的内容,它可能会触发整个级联的此类事件,甚至可能重置/干扰常规进程计算客户端矩形。元素的大小,即使在百分比水平,也变成了一个空白,一个巨大的问号,必须反复查询'从某种意义上说。这都是推测性的,因为它非常依赖于浏览器。

但是,与浏览器无关的是CSS允许这些类型的浏览器本机优化,因为它具有静态,可预测,属性指定的特性。 JS有更多的自由,所以它必须运行在顶层,并且不具备允许浏览器开发人员随心所欲地做任何事情的特殊权限。

使用CSS,该球是在本机浏览器开发者中使用的。法庭。有了JS,球就在你的球场上,如果JS代码在浏览器上运行,那么击败浏览器开发者将会非常困难(如果可能的话)。

答案 1 :(得分:1)

1)最后,它是所有CSS定位。在JS中计算它,而不是让CSS +布局引擎计算它只是意味着一旦你有了数字,你需要将它分配给元素(或其他地方)并让CSS引擎从那里拿起它,并在它期间应用它下一次重画。

2)CSS可以在内部访问事物的实际像素宽度。有时你需要确定元素的计算样式,以便进行计算......

...这意味着你需要调用一个读取这些值的方法,将它们解析为可行的数字,进行计算,转换回代表单位值的相应字符串,然后将其发送回CSS / layout / rendering

这并不意味着JS不能快 同样,JS可以做的事情,CSS本身永远无法做到的事情(如高级动态动画混合)...... ......但诀窍是在适当的时候使用两者,并且出于上面描述的原因,要知道你写的东西每秒运行几十次,不能与只需要的东西进行比较每当你碰到一些使之前的计算失效的东西时,你就可以计算出来,这样可以知道你可以在JS版本中随心所欲地改变细节,也可以编写各种序列,这些序列可以动态分解和重构。在CSS中,你受到预定义动画的支配。