use*_*ca8 7 javascript css jquery reflow
我正试图在缓慢的UI中修复一些性能缓慢的javascript,并且我将主要原因缩小到.width()用于width: 100%在响应式布局中查看元素的实际像素大小的jQuery 调用,在需要的过程中经常发生在响应用户操作时.
我已经添加了基于时间戳的测量结果,并且它们显示它仅占滞后时间的33%左右,这使得UI感觉清晰且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()调用的目的是查看响应式设计是否以及缩小了多少.它需要查看一个小部件的包装元素,它具有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毫秒,所以我的基于时间戳的功能很快就无法测量它!
不幸的是,我也有检查的标签,其中有一个固定的宽度,不溢出容器响应另一个函数,而对于这一点,我也需要考虑到无论是容器的当前像素宽度或规模因素.
不确定这会有多大的改进,但您可以尝试向小部件的根添加一个绝对定位的元素(不包含子元素),其唯一目的是读取其宽度。我认为绝对定位的元素只会回流其子元素:
.root {
position: relative;
}
.ruler {
position: absolute;
width: 100%;
}
Run Code Online (Sandbox Code Playgroud)
_
<div class="root>
...
<div class="ruler"></div>
</div>
Run Code Online (Sandbox Code Playgroud)
-
var updatedWidth = $('.ruler').width()
Run Code Online (Sandbox Code Playgroud)
(虽然我同意评论说你应该尝试用 CSS 解决)