是否可以通过Javascript访问%-width元素的当前缩放因子而不会导致重排?
我试图在缓慢的UI中修复一些性能缓慢的javascript,并且我将主要原因缩小到jQuery .width()
调用,用于查看width: 100%
的实际像素大小width: 100%
响应中的width: 100%
元素布局,在需要经常响应用户操作的过程中。
我添加了基于时间戳的测量结果,他们发现它仅占滞后时间的33%左右,这使得用户界面感觉清晰,用户界面感觉缓慢。 删除这一行,UI感觉很快 – 但是,它把东西放在错误的地方……
似乎已经很好地建立了.width()
在jQuery> 1.8中相对较慢,主要有两个原因:
-
它会在计算元素大小时强制重排 。 来自引用的文章什么时候在DOM环境中发生重排? :
[当您检索必须计算的度量时发生回流,例如访问offsetWidth,clientHeight或任何计算的CSS值(通过DOM兼容的浏览器中的getComputedStyle()或IE中的currentStyle)
…事实上,对于像IE和Firefox这样的浏览器,为了避免相互矛盾的变化(例如在同一个函数调用中隐藏和显示), 将 DOM更改延迟到最后一刻, 人们有时会添加不必要的状态getter以强制重排发生 。
-
它还需要检查元素的边框状态。 来自他们的博客 :
jQuery 1.8现在需要在使用.width()时检查box-sizing属性,以便它可以决定是否需要减去填充和边框宽度。 这可能是昂贵的 – 在Chrome上高达100倍!
我的代码的width()
调用的目的是查看响应式设计是否以及缩小了多少。 它需要查看widget的包装元素,其width: 100%;
(但可能在列或其他容器中,具体取决于它所在的站点/页面),并且需要查看它实际显示的包装器最大宽度的百分比。
基于不同坐标系统的其他代码为我提供了标签的位置(以像素为单位),然后我需要使用缩放因子(本质上= $wrapper.width() / maxWidth;
)来缩小位置,以便例如,如果在狭窄的窗口/设备中查看页面并且包装器是其最大大小的50%,则标签的顶部和左侧偏移量是其默认值的50%。
有没有什么办法可以访问这个数据,关于%-width元素在没有引起重排的情况下缩小了多少以及使.width()
调用变慢的其他因素?
我试过或排除的事情:
-
.outerWidth()
和.width()
一样慢 -
.get(0).clientWidth
(纯Javascript /非Jquery选项)也几乎与.width()
一样慢(大概是因为它是.width()
的罪魁祸首) - 我注意到在大多数浏览器中,如果我执行其中任何一个后跟其他维度中的任何一个(例如
.get(0).clientWidth
后跟.outerHeight()
)第一个之后调用非常快(~20次)快点)。 大概是因为刚刚完成了重排并且刚刚访问了元素属性,所以它们以某种方式被缓存。 但是效果不适用于重复调用函数,仅在一个函数调用中。 -
.css("width")
显然没用,因为它在所有情况下都只给我100%
- 我考虑获取窗口的宽度,但事情变得复杂,具体取决于托管此元素的页面的列布局。 例如,如果我的包装器采用双列布局,并且窗口比折叠两列的断点稍宽,则窗口将比包装元素的最大大小宽,但包装元素不会在100%的最大宽度。
[ 更新 ]我以为我想出了一种绕过我解决问题的方法的方法,并且在不访问元素缩放的情况下定位我的标签:因为我已经有了像素的maxWidth
变量和像素的偏移量,我已经够了使用leftOffset_px / maxWidth_px
和topOffset_px / maxHeight_px
计算我的标签的百分比偏移量的数据,然后是+ '%'
并将其应用为每个标签的CSS top
和left
偏移量。 这是非常快的 – 现在不到1毫秒,所以我的基于时间戳的function很快就无法测量它!
不幸的是,我还有另一个function,它检查具有固定宽度的标签不会溢出响应容器,为此,我需要考虑容器的当前像素宽度或其比例因子。
不确定改进有多大,但你可以尝试在窗口小部件的根目录中添加一个绝对定位的元素,不包含子元素,唯一的目的就是读取它的宽度。 我认为绝对定位的元素只会让孩子们重温:
.root { position: relative; } .ruler { position: absolute; width: 100%; }
_
–
var updatedWidth = $('.ruler').width()
(虽然我同意评论说你应该尝试用CSS解决)