在这篇文章中,我们将会去探究一下浏览器是如何去处理CSS Animations和CSS Transitions的,以便使你在写一些动画效果之前就可以对该动画在浏览器中运行效果有一个心理预判。有了这些预判,你就可以设计出一些在浏览器中运行流畅的动画效果,从而带来更流畅的用户体验。
浏览器的内部工作
让我们了解一些浏览器的工作原理,一探究竟。一旦我们了解了浏览器是如何工作的,我们就可以更好的去驾驭它。
现代浏览器通常拥有两个重要的执行线程,这两个线程相互配合来渲染出页面:
主线程
排版线程
通常情况下,主线程主要负责以下工作:
运行JavaScript
计算HTML元素的CSS样式
布局页面
把页面元素绘制成一个或多个位图
把这些位图移交给排版线程
通常情况下,排版线程主要负责以下工作:
通过GPU渲染位图,并显示在屏幕上
向主线程请求更新位图的可见部分或即将可见的部分
判断出当前页面处于可见的部分
判断出即将通过页面滚动而可见的部分
随着用户滚动页面来移动这些部分(译者注:可见部分的和即将可见的部分)
当长时间运行JavaScript或渲染一个很多的元素时,主线程会一直处于忙碌状态。在这期间它不会对用户的输入做出任何反应。
在另一方面,排版线程对用户输入保持着非常快的响应。当页面变化时,排版线程尝试以每秒60帧的速度去重绘页面,即便这时页面还不完整。
举例来说,当用户滚动页面时,排版线程向主线程请求更新页面新显示部分的位图,但是,如果此时主线程并不能迅速响应请求,排版线程并不会去等待响应,它会用它目前所拥有的这部分页面的内容去渲染页面,由于对应的内容还没有,所以会以白板的形式渲染出来。
GPU
我前边提到过排版线程通过GPU把位图绘制到了屏幕上。让我们快速的过一下GPU相关的东西。
GPU是一种芯片,在今天的大多数手机,平板以及电脑中都能发现它的身影。它是非常专业的,这意味着GPU在某些方面非常擅长,但是在另外一些方面去表现不好。
GPU比较擅长于:
绘制位图到屏幕
重复的绘制同一个位图
在不同的位置,以不同的旋转角度,或者不同的缩放大小来绘制同一个位图。
GPU相对慢的地方:
将位图加载到显存里。
transition: height
现在我们已经在软件层面和硬件层面对如何渲染页面有了一个粗略的认识。接下来,让我们看一下浏览器的主线程和排版线程是如何协同工作来完成一个CSS Transition的。
假设我们想要将一个元素的高度值从100px转换到200px,如下所示:
- div {
- height: 100px;
- transition: height 1s linear;
- }
- div:hover {
- height: 200px;
- }
主线程和排版线程会根据下图所示时序图来完成这个Transition。注意:在橙色方框中的操作是潜在的耗时操作,蓝色方框中的操作是较快的操作。
正如你所见,整个过程有很多橙色的方框,意味着浏览器有相当繁重的工作要处理,也意味着这个Transition可能会出现卡顿。
在整个Transition的每一帧中,浏览器都要去重新布局,绘制页面,并把最新的位图对象加载到GPU。我们前边了解过,把位图对象加载到GPU的内存中是个相对缓慢的操作。
浏览器之所以要在每一帧动画上处理如此繁重的工作是因为这个元素的内容一直在变化。修改一个元素的高度可能会引起其子元素也要相应的改变大小,因此浏览器必须去重新布局。重新布局后,主线程必须为该元素重新生成位图对象。
transition: transform
由此可见,对高度进行的Transition相对来说性能比较差,那有一些性能比较好的Transition吗?
假设我们想要把一个元素从一半大小缩放到实际大小,并假设我们使用CSS的transform 属性来对它进行缩放,同时使用CSS的transition属性来生成缩放的动画效果,如下所示:
- div {
- transform: scale(0.5);
- transition: transform 1s linear;
- }
- div:hover {
- transform: scale(1.0);
- }
我们看到只有很少的几个橙色的方框,意味着这个动画效果可能会很流畅!那么,一个元素的transform动画效果与其高度的动画效果有什么不同呢?
根据定义,CSS的transform属性不会改变元素的布局,也不会影响到其周围的元素。它把元素当做一个整体看待——缩放整个元素、旋转整个元素或者移动整个元素。
这对浏览器来说是一个好消息!浏览器只需在动画开始的时候生成这个元素的位图对象,并把它传递给GPU。在这之后,浏览器无需再做任何重新布局,绘制页面以及传递位图对象的操作了,相反,浏览器可以利用GPU擅长的绘制的特点来快速的在不同的位置,旋转或缩放同一个位图对象。
设计决策
那么,是否这就意味这我们不要去缓动一个元素的高度?非也,一些情况下,这是你的设计效果的一部分,并且动画效果可以非常快的完成。也许动画的元素是孤立的,不会引起页面其他部分进行重新布局;也许该元素只是单纯的进行重绘,浏览器可以快速的完成;也许该元素很小,浏览器只需将很小的位图对象传递给GPU。
当然了,在不影响你设计的视觉效果的情况下,最好去缓动一个性能较好的CSS属性,如transform,而不是去缓动一个性能较差的CSS属性,如height。举例来说,假设你的设计中有一个按钮,当点击它的时候会出来一个菜单,试着去缓动菜单的transform属性来显示它而不是缓动它的top或height属性来达到类似的效果。
在动画上特别快的CSS属性包括:
CSS transform
CSS opacity
CSS filter (依赖于过滤器的复杂度和浏览器)
目前这个列表是非常有限的,但是随着浏览器的进步,你将会看到越来越多的CSS属性在动画中变得越来越快。另外,不要轻视当前的列表。你可能会很惊讶你能通过组合这些属性创造出许多丰富的效果。只要有创意!
《魔兽世界》大逃杀!60人新游玩模式《强袭风暴》3月21日上线
暴雪近日发布了《魔兽世界》10.2.6 更新内容,新游玩模式《强袭风暴》即将于3月21 日在亚服上线,届时玩家将前往阿拉希高地展开一场 60 人大逃杀对战。
艾泽拉斯的冒险者已经征服了艾泽拉斯的大地及遥远的彼岸。他们在对抗世界上最致命的敌人时展现出过人的手腕,并且成功阻止终结宇宙等级的威胁。当他们在为即将于《魔兽世界》资料片《地心之战》中来袭的萨拉塔斯势力做战斗准备时,他们还需要在熟悉的阿拉希高地面对一个全新的敌人──那就是彼此。在《巨龙崛起》10.2.6 更新的《强袭风暴》中,玩家将会进入一个全新的海盗主题大逃杀式限时活动,其中包含极高的风险和史诗级的奖励。
《强袭风暴》不是普通的战场,作为一个独立于主游戏之外的活动,玩家可以用大逃杀的风格来体验《魔兽世界》,不分职业、不分装备(除了你在赛局中捡到的),光是技巧和战略的强弱之分就能决定出谁才是能坚持到最后的赢家。本次活动将会开放单人和双人模式,玩家在加入海盗主题的预赛大厅区域前,可以从强袭风暴角色画面新增好友。游玩游戏将可以累计名望轨迹,《巨龙崛起》和《魔兽世界:巫妖王之怒 经典版》的玩家都可以获得奖励。
更新动态
- 凤飞飞《我们的主题曲》飞跃制作[正版原抓WAV+CUE]
- 刘嘉亮《亮情歌2》[WAV+CUE][1G]
- 红馆40·谭咏麟《歌者恋歌浓情30年演唱会》3CD[低速原抓WAV+CUE][1.8G]
- 刘纬武《睡眠宝宝竖琴童谣 吉卜力工作室 白噪音安抚》[320K/MP3][193.25MB]
- 【轻音乐】曼托凡尼乐团《精选辑》2CD.1998[FLAC+CUE整轨]
- 邝美云《心中有爱》1989年香港DMIJP版1MTO东芝首版[WAV+CUE]
- 群星《情叹-发烧女声DSD》天籁女声发烧碟[WAV+CUE]
- 刘纬武《睡眠宝宝竖琴童谣 吉卜力工作室 白噪音安抚》[FLAC/分轨][748.03MB]
- 理想混蛋《Origin Sessions》[320K/MP3][37.47MB]
- 公馆青少年《我其实一点都不酷》[320K/MP3][78.78MB]
- 群星《情叹-发烧男声DSD》最值得珍藏的完美男声[WAV+CUE]
- 群星《国韵飘香·贵妃醉酒HQCD黑胶王》2CD[WAV]
- 卫兰《DAUGHTER》【低速原抓WAV+CUE】
- 公馆青少年《我其实一点都不酷》[FLAC/分轨][398.22MB]
- ZWEI《迟暮的花 (Explicit)》[320K/MP3][57.16MB]