gpt4 book ai didi

jquery - CSS 转换过渡 - 使用“px”比 'percentage' 更平滑/性能更好

转载 作者:技术小花猫 更新时间:2023-10-29 10:23:30 26 4
gpt4 key购买 nike

我最近一直在研究改进我网站上的动画——更具体地说是移动设备上的导航下拉菜单。

在这方面,我偶然发现了以下案例,我希望对此有更深入的了解。

情况是在过渡/动画时transform: translate3d()似乎浏览器在使用 % 应用时需要更多的计算而不是 px .例如。在我的测试中,似乎从 transform: translate3d(0, 500px, 0) 过渡至 transform: translate3d(0,0,0)与从 transform: translate3d(0, 100%, 0) 过渡相比,需要更少的计算并且运行更流畅.

更新:经过进一步测试,我发现使用 100vh/100vw绕过/减轻使用百分比的问题。这在元素具有已知百分比宽度的窗口或全宽的情况下很有用,从而提高性能。实际上,似乎使用这个值的行为就像是用 px 分配的一样。 Chrome 中的值。

这是每个动画的时间线的几张图片。时间线是使用谷歌开发工具在“性能”下获得的。为了更好地显示差异,Chrome Dev Tools 中的性能被限制为“低端移动”(6 倍 CPU 速度降低)。

使用百分比转换:

Transform performance using percent (%)

使用像素 (px) 进行变换:

Transform performance using pixel (px)

从图像中可以看出,使用 % 时似乎进行了更多的渲染和绘画。而不是 px来确定转换。浏览器必须计算每一帧的百分比值(我猜?),这是很有意义的,但我很惊讶,与使用像素值相比,它需要更多。

还有请注意,显示百分比时间线的图片中的帧率从未达到约 60 fps,而是平均约为 40 fps。

以下是复制案例的片段。有一种使用百分比,一种使用 px。

$(document).on("click", function(){
$(".bb").toggleClass("active");
});
.aa{
height:50px;
background:blue;
position:fixed;
top:0;
width:100%;

}
.bb{
position:fixed;
top:0px;
background:none;
height:100%;
width:100%;
left:0;
transform:translateZ(0);
overflow:hidden;
pointer-events:none;
}
.cc{
height:100%;
transform:translate3d(0,500px,0);
width:100%;
transition:transform .5s ease-in;
background:red;
}
.bb.active .cc{
transform:none;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<p>Click the document to start animation<p>
<div class="bb">
<div class="cc">
<ul>
<li>Point one</li>
<li>Point two</li>
<li>Point three</li>
<li>Point four</li>
<li>Point five</li>
<li>Point six</li>
<li>Point seven</li>
</ul><ul>
<li>Point one</li>
<li>Point two</li>
<li>Point three</li>
<li>Point four</li>
<li>Point five</li>
<li>Point six</li>
<li>Point seven</li>
</ul>

</div>

</div>



$(document).on("click", function(){
$(".bb").toggleClass("active");
});
.aa{
height:50px;
background:blue;
position:fixed;
top:0;
width:100%;

}
.bb{
position:fixed;
top:0px;
background:none;
height:100%;
width:100%;
left:0;
transform:translateZ(0);
overflow:hidden;
pointer-events:none;
}
.cc{
height:100%;
transform:translate3d(0,100%,0);
width:100%;
transition:transform .5s ease-in;
background:red;
}
.bb.active .cc{
transform:none;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<p>Click the document to start animation<p>
<div class="bb">
<div class="cc">
<ul>
<li>Point one</li>
<li>Point two</li>
<li>Point three</li>
<li>Point four</li>
<li>Point five</li>
<li>Point six</li>
<li>Point seven</li>
</ul><ul>
<li>Point one</li>
<li>Point two</li>
<li>Point three</li>
<li>Point four</li>
<li>Point five</li>
<li>Point six</li>
<li>Point seven</li>
</ul>

</div>

</div>


解决这个“问题”,即在 transform 中使用百分比可能会导致动画性能变差,我提出了以下建议,这可能会提高性能。但是,我有兴趣听取其他意见,因为我不太确定这是否必要以及为什么(?)。

我正在做的基本上只是使用 jQuery 来应用 transform以像素而不是百分比为单位的值。对于生产情况,这自然需要在调整窗口大小时进行更新。

这种方法的最终时间表是:

enter image description here

$(document).ready(function(){
var bbWidth = $("#bb .cc").css('transform').split(',')[5].slice(0,-1);

$("#bb .cc").css("transform", "translate3d(0," + bbWidth + "px,0");
$(document).on("click", function(){
$("#bb").toggleClass("active");
});
});
.aa{
height:50px;
background:blue;
position:fixed;
top:0;
width:100%;

}
#bb{
position:fixed;
top:0px;
background:none;
height:100%;
width:100%;
left:0;
transform:translateZ(0);
overflow:hidden;
}
.cc{
height:100%;
transform:translate3d(0,100%,0);
width:100%;
transition:transform .5s ease-in;
background:red;
position:absolute;
top:0;
}
#bb.active .cc{
transform:none!important;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div id="bb">
<div class="cc">
<ul>
<li>Point one</li>
<li>Point two</li>
<li>Point three</li>
<li>Point four</li>
<li>Point five</li>
<li>Point six</li>
<li>Point seven</li>
</ul><ul>
<li>Point one</li>
<li>Point two</li>
<li>Point three</li>
<li>Point four</li>
<li>Point five</li>
<li>Point six</li>
<li>Point seven</li>
</ul>

</div>

</div>


问题:
  • 我遇到这种行为是否正确(在 px 中赋值比 % 表现更好),如果是这样,为什么会发生这种情况?正如前面提到的,它应该对我来说有点道理,但我真的缺乏一些技术/深入的解释。
  • 有没有比我的建议更好的绕过这个问题的方法?使用 transform: translate()例如如果您“不能”使用 %,在屏幕外隐藏导航是非常重要的如果您同时想要流畅的动画。
  • 最佳答案

    Is it correct that I'm experiencing this behaviour (assigning value in px performs better than %) and if so, why is this happening? As mentioned earlier it kinda makes sense to me that it should, but I'm really lacking some technological/in-depth explanation.



    确实是对的。像素是绝对值(即不依赖于任何东西并“按原样”表示)。百分比是相对值,这意味着它们必须依赖于其他一些值才能产生结果。因此,每次分配百分比值时,它都必须获得它的相对值才能执行计算。
    使用像素进行平移时,您只需更改平移值,但使用百分比时,您必须先获取元素的尺寸,然后再应用平移。并且必须对每个动画帧都这样做。

    为了缓解这个问题,你只需要在动画之前重新计算元素的尺寸一次。然后使用 !important覆盖样式属性中设置的内容。片段中的代码正是这样做的。

    另请注意,我添加了 resize听众。如果窗口被调整大小,这是必需的,因此您的元素将被隐藏。

    $(function(){
    var $el = $("#bb");
    $(document).on("click", function(){
    var height = $el.outerHeight();
    $el
    .css('transform', 'translateY(' + height + 'px)')
    .toggleClass("active");
    });
    $(window).on('resize', function() {
    $el.removeClass('active').removeAttr('style');
    });
    });
    #bb{
    position:fixed;
    top:0px;
    background-color: red;
    height:100%;
    width:100%;
    left:0;
    overflow:hidden;
    transform: translateY(100%);
    transition: transform .5s ease-in;
    }
    #bb.active
    {
    transform: translateY(0px) !important;
    }
    <script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
    <div id="bb">
    <div class="cc">
    <ul>
    <li>Point one</li>
    <li>Point two</li>
    <li>Point three</li>
    <li>Point four</li>
    <li>Point five</li>
    <li>Point six</li>
    <li>Point seven</li>
    </ul><ul>
    <li>Point one</li>
    <li>Point two</li>
    <li>Point three</li>
    <li>Point four</li>
    <li>Point five</li>
    <li>Point six</li>
    <li>Point seven</li>
    </ul>

    </div>

    </div>

    关于jquery - CSS 转换过渡 - 使用“px”比 'percentage' 更平滑/性能更好,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/50409008/

    26 4 0
    Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
    广告合作:1813099741@qq.com 6ren.com