我试图在缓慢的 UI 中修复一些性能缓慢的 javascript,我已经将主要原因缩小到 jQuery .width()
用于查看 width: 100%
的实际像素大小的调用响应式布局中的元素,在一个需要经常响应用户操作的过程中。
我添加了基于时间戳的测量,它们表明仅它就占了大约 33% 的延迟时间,这使得 UI 感觉清晰和 UI 感觉迟钝之间存在差异。删除这一行,用户界面感觉很快 - 但是,它把东西放在了错误的地方......
好像well established that .width()
is relatively slow in jQuery > 1.8主要有两个原因:
[ reflow happens when ] you retrieve a measurement that must be calculated, such as accessing offsetWidth, clientHeight, or any computed CSS value (via getComputedStyle() in DOM-compliant browsers or currentStyle in IE)
...事实上,对于像 IE 和 Firefox 这样的浏览器,它们会将 DOM 更改延迟到最后一刻以避免发生矛盾的更改(例如,在同一函数调用中隐藏和显示),people sometimes add unnecessary state getters in order to force reflow to occur .
jQuery 1.8 now needs to check the box-sizing property whenever you use .width() so that it can decide whether it needs to subtract out the padding and border width. That can be expensive—up to 100 times more expensive on Chrome!
我的代码的用途
width()
电话是查看响应式设计是否以及缩小了多少。它需要查看一个小部件的包装元素,它有 width: 100%;
(但可能在列或其他容器中,具体取决于托管它的站点/页面),并且需要查看它实际显示的包装器最大宽度的百分比。基于不同坐标系的其他代码为我提供了标签的位置(以像素为单位),然后我需要使用缩放因子(基本上是
= $wrapper.width() / maxWidth;
)来缩小位置,例如,如果页面在狭窄的窗口/设备中查看并且包装器是其最大尺寸的 50%,标签的顶部和左侧偏移是其默认值的 50%。有什么方法可以访问这些数据,了解 %-width 元素缩小了多少,而不会导致回流以及其他导致
.width()
的事情。通话慢?我尝试或排除的事情:
.outerWidth()
与 .width()
完全一样慢.get(0).clientWidth
(纯 Javascript/非 Jquery 选项)也几乎和 .width()
一样慢(据推测,因此回流是罪魁祸首).get(0).clientWidth
后跟 .outerHeight()
),则调用速度非常快(约快 20 倍)。大概因为回流刚刚完成并且元素属性刚刚被访问,它们以某种方式被缓存。但效果不适用于重复调用该函数,仅在一次函数调用中有效。 .css("width")
显然没有用,因为它只会给我 100%
在所有情况下 [ 更新 ] 我想我已经找到了一种方法来绕过解决问题的需要,并在不访问元素缩放的情况下定位我的标签:因为我已经有了
maxWidth
以像素为单位的变量和以像素为单位的偏移量,我有足够的数据来计算我的标签的百分比偏移量 leftOffset_px / maxWidth_px
和 topOffset_px / maxHeight_px
,然后 + '%'
并将其应用为每个标签的 CSS top
和 left
抵消。这速度快得离谱——现在不到 1 毫秒,如此之快,我的基于时间戳的函数无法测量它!不幸的是,我还有另一个函数来检查具有固定宽度的标签是否不会溢出响应容器,为此,我确实需要考虑容器的当前像素宽度或其比例因子.
最佳答案
不确定这会有多大的改进,但您可以尝试向小部件的根添加一个绝对定位的元素,不包含子元素,其唯一目的是读取其宽度。我认为绝对定位的元素只会重排它的 child :
.root {
position: relative;
}
.ruler {
position: absolute;
width: 100%;
}
_
<div class="root>
...
<div class="ruler"></div>
</div>
——
var updatedWidth = $('.ruler').width()
(虽然我同意评论说你应该尝试用 CSS 解决)
关于javascript - 是否可以通过 Javascript 访问 %-width 元素的当前缩放因子而不会导致回流?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/39393141/