原文链接: Smooth as Butter: Achieving 60 FPS Animations with CSS3

在移动端使用动画元素是很容易的.

如果你能遵循我们的这里的提示, 在移动端适当的使用动画元素, 可以变得更加容易.

在这些天里, 每个人都不会适当的使用CSS3动画. 有些最佳的实践方法, 一直被忽视. 被忽视的主要原因是人们不能真正的理解,这些实践存在的真正原因, 以及为何能得到大力支持.

现在设备的规格非常多, 如果你不能通过仔细思考优化你的代码, 使用顺畅的动画, 你会给大部分的人带来不好的体验.

记住: 尽管一些高端, 旗舰设备不断推动发展, 但这世界上大部分的设备, 和高端机相比差太多, 就像一个带着LCD的算盘.

我们会告诉你如何使用CSS3, 发挥它的最大功效. 为了达成这一点, 我们首先需要学习一点东西.

理解时间线(Timeline)

渲染和使用元素的时候, 浏览器会做些什么? 这是非常简单的一条时间线, 被称之为关键渲染路径(Critical Rendering Path)

我们应该专注于改变影响合成步骤的属性, 而不是增加上一次布局的压力.

1.样式

浏览器开始计算样式, 以便应用到元素上 - 重新计算样式

2.布局

下一个步骤中, 浏览器开始计算模型和各个元素的位置 - 布局. 这是浏览器设置在页面中设置例如属性的地方, 也包括了外边距, 或者是实例的左/高/右/下.

3.绘制

图片

浏览器开始将每一个元素在像素级别填充到图层中. 我们使用的这些属性包括: box-shadow, border-radius, color, background-color, 等等.

4.合成

这是你需要操作的地方, 因为这是浏览器开始在屏幕绘制所有的图层.

图片

现在浏览器能够产生动画的有四个属性, ,最好使用tansform, 和opacity属性.

  • 位置: transform: translateX(n) translateY(n) translateZ(n);
  • 扩大/缩放: transform: scale(n);
  • 旋转: transform: rotate(ndeg);
  • 透明: opacity: n;

如何获得每秒60帧的实现

通过上面这些思考, 让我们开始干吧.

我们通过一个HTML开始. 我们会创建一个非常简单的模型, 然后在.layout中放置一个app-menu.

<div class="layout">
<div class="app-menu"></div>
<div class="header">
<div class="menu-icon"></div>
</div>
</div>

开始使用一个错误的方式

Going About It the Wrong Way(下为原文翻译)

.app-menu {
transition: left 300ms linear;
left: -60%;
}
.open .app-menu {
left: 0;
}

看到被我们改变的属性了吗? 你应该避免使用transition上面的top/right/bottom/left属性. 那并不会产生一个流畅的动画. 因为他们让浏览器一直在创建layouts, 这会影响到他所有的子组件.

他的结果就像这样:

这个动画完全不顺畅. 我们通过使用DevTools Timeline来看看底层发生了什么, 这是他的结果:

这清楚的展现了FPS的不规则, 并且性能很差.

"绿条表示FPS. 他上面的条表示动画在60FPS如何渲染. 下面的条表示低于60FPS. 所以, 理想情况下, 你希望绿条能在整个时间线保持较高的水平. 红条也能表示出闪避jank(避开了渲染时间?), 所以, 还可以通过消除红条, 来表示你性能的进步." 感谢Kayce Basques指出.

第一部分实践纠正

关于Dev Tools

官方文档: Timeline已经不再使用, 下面是使用Performance

关于渲染顺序

官方文档:

这是一个疑问句? 现在我发现, 官方文档上所说的CRP和这篇文章说的不太一样, 有空翻译下官方文档.

使用 Transform

.app-menu {
transition: transform 300ms linear;
transform: translateX(-100%);
}
.open .app-menu{
transform: none;
}

transform属性作用到Composite合成阶段. 这里告诉我们, 只要动画开始, 浏览器所有的图层都渲染完成并准备好了, 所以动画渲染的时候, 间隔非常小.

在实际中的时间线中展示:

现在的结果变得好一些了, FPS能够进行更多渲染, 然后动画更加流畅.

个人第二部分测试

和上一次个人测试相比, 省去了layout阶段, 就是布局的时间.

在GPU中运行动画

那么, 让我把他提高一个等级. 为了保证动画运行的顺畅, 我们是用GPU开始渲染动画.

.app-menu {
transition: transform 300ms linear;
transform: translateX(-100%);
/* transform: translate3d(-100%, 0, 0); */
will-change: transform;
}
.open .app-menu{
transform: none;
}

尽管一些浏览器依旧需要使用translateZ()translate3d()作为备选方案, will-changeCSS will-change - how to use it, how it works才是以后的趋势. 这样做, 可以把元素提升到另一层上, 所以, 浏览器不需要考虑布局的渲染和绘制.

能够看出他的顺畅吗? 渲染路径会证实这一点.

动画的FPS是非常连续的, 并且动画的渲染是非常快速的. 但是依旧有一个红框在渲染的时候. 那只是在开始的时候, 一个小瓶颈.

记住刚开始时创建的HTML的结构. 让我们使用JavaScript在结构中控制一个app-menudiv.

function toggleClassMenu() {
var layout = document.querySelector('.layout')
if (!layout.classList.contains('app-menu-open')) {
layout.classList.add('app-menu-open')
} else {
layout.classList.remove('app-menu-open')
}
}

这个问题是: 我们给layout这个div添加了类名, 让浏览器再一次计算了样式, 影响了渲染性能.

个人关于第三部分测试

首先是, 使用translate3d的效果:

这是使用了will-change的效果:

同样, 我也是使用这种控制类名的方式实现的动画.

60FPS的顺畅动画

如果我们从视图层外边创建一个区域替代之前的做法呢? 一个隔离的区域, 可以确保影响到的元素, 就是想要进行动画的.

所以, 我们使用下面这种HTML结构.

<div class="menu">
<div class="app-menu"></div>
</div>
<div class="layout">
<div class="header">
<div class="menu-icon"></div>
</div>
<a href="www.baidu.com">baidu</a>
</div>

现在我们可以使用稍微不同的方式控制menu的状态了. 当动画结束的时候, 我们使用JavaScript中的transitionend函数, 删除还有动画的类名.

function toggleClassMenu() {
myMenu.classList.add("menu--animatable");
if (!myMenu.classList.contains("menu--visible")) {
myMenu.classList.add("menu--visible");
} else {
myMenu.classList.remove('menu--visible');
}
} function OnTransitionEnd() {
myMenu.classList.remove("menu--animatable");
} var myMenu = document.querySelector(".menu");
var oppMenu = document.querySelector(".menu-icon");
myMenu.addEventListener("transitionend", OnTransitionEnd, false); // 只在动画期间添加动画函数
oppMenu.addEventListener("click", toggleClassMenu, false);
myMenu.addEventListener("click", toggleClassMenu, false);

让我们全部结合起来, 然后检查结果.

下面是完整, 可以使用CSS3的例子, 每一处都使用了最正确的方式.

  body {
margin: 0;
padding: 0;
} .menu {
position: fixed;
left: 0;
top: 0;
width: 100%;
height: 100%;
overflow: hidden;
pointer-events: none; /* 这个属性表示, 即使是上面有一层, 也不影响, 下面元素的使用 */
z-index: 150;
} .menu--visible {
pointer-events: auto; /* 遮盖了, 也就不让用了 */
} .app-menu {
background-color: #fff;
color: #fff;
position: relative;
max-width: 400px;
width: 90%;
height: 100%;
box-shadow: 0 2px 6px rgba(0, 0, 0, 0.5);
-webkit-transform: translateX(-103%);
transform: translateX(-103%);
display: flex;
flex-direction: column;
will-change: transform;
z-index: 160;
pointer-events: auto; /* 这是我们的侧边栏, 打开的时候, 不让用下面的元素 */
} .menu--visible .app-menu {
-webkit-transform: none;
transform: none;
} .menu--animatable .app-menu { /* 消失的时候, 先慢后快 */
transition: all 130ms ease-in;
} .menu--visible.menu--animatable .app-menu { /* 出现的时候, 先快, 后慢 */
transition: all 330ms ease-out;
} .menu:after {
content: '';
display: block;
position: absolute;
left: 0;
top: 0;
width: 100%;
height: 100%;
background: rgba(0, 0, 0, 0.4);
opacity: 0;
will-change: opacity;
pointer-events: none;
transition: opacity 0.3s cubic-bezier(0, 0, 0.3, 1);
} .menu--visible.menu:after {
opacity: 1;
pointer-events: auto;
} /* aux */ body {
margin: 0;
} .layout {
width: 375px;
height: 667px;
background-color: #f5f5f5;
position: relative;
} .header {
background-color: #ccc;
} .menu-icon {
content: "Menu";
color: #fff;
background-color: #666;
width: 40px;
height: 40px;
} .app-menu {
width: 300px;
height: 667px;
box-shadow: none;
background-color: #ddd;
} .menu:after {
width: 375px;
height: 667px;
}

让我们看下Timeline展示给我们的?

看到了吗? 非常流畅.

最后一部分的测试

发现, 性能提升主要在Event中, 其他未能看出提升, 并进行了一个名为Fire Idle Callback.还需要深入了解下. 下图为实操图片:

总结

  • 再次深入学习了事件流.
  • 没有搞明白关键渲染路径到底是什么. 文章和官网说的不一样.
  • 知道了一个will-changepointer-events

丝滑顺畅:使用CSS3获取60FPS动画的更多相关文章

  1. 使用 CSS3 打造一组质感细腻丝滑的按钮

    CSS3 引入了众多供功能强大的新特性,让设计和开发人员能够轻松的创作出各种精美的界面效果.下面这些发出闪亮光泽的按钮,很漂亮吧?把鼠标悬停在按钮上,还有动感的光泽移动效果. 温馨提示:为保证最佳的效 ...

  2. jQuery和css3控制箭头丝滑旋转

    问题: 我们经常会遇见点击一个小三角使之丝滑的旋转180度上下旋转,怎么实现呢,需要css3搭配jq 来处理 如图:1.点击前 2.点击后(效果丝滑旋转)                 1.html ...

  3. 简单的CSS3鼠标滑过图片标题和遮罩层动画特效

    此文转自:http://www.cnblogs.com/w2bc/p/5735300.html,仅供本人学习参考,版权归原作者所有!   这是一款使用CSS3制作的简单的鼠标滑过图片标题和遮罩层动画特 ...

  4. 让你的app体验更丝滑的11种方法!冲击手机应用榜单Top3指日可待

    欢迎大家前往腾讯云+社区,获取更多腾讯海量技术实践干货哦~ 本文由WeTest质量开放平台团队发表于云+社区专栏 一款app除了要有令人惊叹的功能和令人发指交互之外,在性能上也应该追求丝滑的要求,这样 ...

  5. HMS Core Discovery第14期回顾长文|纵享丝滑剪辑,释放视频创作力

    HMS Core Discovery第14期直播<纵享丝滑剪辑,释放视频创作力>,已于4月21日圆满结束,本期直播我们同HMS Core视频编辑服务(Video Editor Kit)的产 ...

  6. CSS3中的动画效果记录

    今天要记录的是CSS3中的三种属性transform.transition以及animation,这三个属性大大提升了css处理动画的能力. 一.Transform 变形 CSS中transform ...

  7. 6种炫酷的CSS3按钮边框动画特效

    6种炫酷的CSS3按钮边框动画特效Button border animate 用鼠标滑过下面的按钮看看效果! Draw Draw Meet Center Spin Spin Circle Spin T ...

  8. 15个超强悍的CSS3圆盘时钟动画赏析

    在网页上,特别是个人博客中经常会用到时钟插件,一款个性化的时钟插件不仅可以让页面显得美观,而且可以让访客看到当前的日期和时间.今天我们给大家收集了15个超强悍的圆盘时钟动画,很多都是基于CSS3,也有 ...

  9. OC语言编写:为视图添加丝滑的水波纹

    先看一下最终效果图: 首先我们可以把如此丝滑的水波纹拆分一下下: 一条规律的曲线. 曲线匀速向右移动. 曲线下方的位置用颜色填充. 于是先来一条曲线吧. 对于需要产生波动如此规律的曲线,我们首先想到的 ...

随机推荐

  1. hdu-1542 Atlantis(离散化+线段树+扫描线算法)

    题目链接: Atlantis Time Limit: 2000/1000 MS (Java/Others)     Memory Limit: 65536/32768 K (Java/Others) ...

  2. ivew组件的使用

    iview的官网:https://www.iviewui.com/docs/guide/start 1.选择快速上手 2.安装 解压,cmd,cd进你解压后的文件,cnpm i 3.打包 npm ru ...

  3. CentOS 性能监控之nmon

    工具集: Nmon  性能数据收集分析工具Nmon analyser 性能数据分析工具,excel文件nmon_x86_sles10  Nmon在x86_sles10下二进制执行文件 nmon概述 n ...

  4. HDU5875Function(单调队列)

    The shorter, the simpler. With this problem, you should be convinced of this truth.      You are giv ...

  5. 1080 Graduate Admission (30)(30 分)

    It is said that in 2013, there were about 100 graduate schools ready to proceed over 40,000 applicat ...

  6. 【Opencv】直方图函数 calchist()

    calchist函数需要包含头文件 #include <opencv2/imgproc/imgproc.hpp> 函数声明(三个重载 calchist函数): //! computes t ...

  7. apache之访问本地文件,绑定域名

    1.打开文件 C:\Windows\System32\drivers\etc\hosts,在文件末尾加上下面代码: 127.0.0.1 www.wangdongxue.com 2.打开Apache的配 ...

  8. python定时任务:apscheduler的使用(还有一个celery~)

    文章摘自:https://www.cnblogs.com/luxiaojun/p/6567132.html 1 . 安装 pip install apscheduler 2 . 简单例子 # codi ...

  9. linux——boot空间不足

    1. 先用df命令,查看磁盘分区情况 2. dpkg --get-selections|grep linux-image(查看更新了多少内核) root@ubuntu:/home/hadoop# dp ...

  10. nagios客户端安装与配置windows篇

    一.被监控的windows xp客户端的配置 1.安装NSClient++并安装下载地址: http://sourceforge.net/projects/nscplusNSClient++-0.3. ...