流暢web動畫的十個法則
自從我們去年登陸了 Gyroscope ,許多人都問我有關用在我們網站上的javascript動畫庫。我們考慮過將此開源,但是這不是魔法真正實現的地方。
我不希望大家認為我們是依靠特殊的javascript插件來解決這些問題的。對于大部分人來說,我們只是充分利用了近來瀏覽器性能的提升,GPU和CSS3規格.
對于良好的動畫性能沒有高招,除了將大量的時間放在測試和優化。然而,過了許多年的實驗和撞擊瀏覽器性能的極限,我們發現了一系列的設計和代碼準則,看上去似乎是良好動畫可靠的結果。這些技術讓你的頁面,在現代桌面和手機瀏覽器上變得流暢,運行良好。最重要的是,易于維護。
對每個人來說,技術和實現方式都有所不同,但是大體上的規則對大多是情況都會有幫助。
什么是動畫?
動畫在互聯網出現之前就已經飽經世故了,并且如果你想做好它,這會是你一生的課題。然而對于應用于互聯網的動畫,有一些特別的約束和挑戰。
對于60幀的流暢動畫,每一幀都需要在16ms內渲染!這并沒有多少時間,因此為了流暢的性能,我們需要找到非常有效的方法來渲染每一幀。
T 在web上有一打方法做動畫。比如,幻燈片是一種方法,在互聯網之前就已經流行,通過輕微不同的手繪幀,在一秒內多次置換,來創造運動的視覺效果。
最近推ter使用這種簡單的方法,制作了新的愛心動畫,通過切換一組雪碧圖切換實現。
這個效果不能用一堆小元素單獨做動畫,或者做一個SVG,但是那樣會產生十分不必要的復雜以及可能會不流暢。
在許多例子中,你會想用CSS transition屬性來做自動動畫。這個技術也同樣以“補間動畫”聞名,在兩個不同的值之間的過渡。這個好處就是,你可以輕易地取消,而不需要建立所有的邏輯。這個對于“一勞永逸”樣式的動畫是理想的解決方式,就像介紹序列,等等,或者簡單如懸停的交互。
在其他例子中,關鍵幀為基礎的CSS動畫屬性也許對于不間斷運行的背景細節是非常理想的。舉個例子,在Gyroscope logo上的戒指計劃是不間斷地旋轉。其他受益于CSS動畫語法的是齒輪速比。
因此,事不宜遲,這里有些建議能夠幫助你很大程度上地提高你的動畫性能……
#1
不要改變除了opacity和transform之外的參數!
即使你覺得這樣ok,也不要這么做!
僅僅這一個基本的準則能幫你解決80%的問題,即使是在手機上。你可能在之前聽過這個——這不是最初的主意,但是是很少被跟隨。這相當于是web的“吃的健康和運動”的相同法則,這個聽上去是一個好的建議,但是你可能會無視。
一旦你如此想了,你會發現這個相對簡單,但是可能會是一個大跳躍,對這些習慣傳統CSS屬性的動畫。
舉個例子,如果你想讓元素變小,你可以使用 transform: scale() ,而不是改變他的寬度。如果你想移動他,不同于用外邊距或者內邊距混在一起——你可以僅僅使用一個簡單的 transform: translateX 或者 transform: translateY 。
為什么這個是有效的?
對于人類來說,改變寬度,外邊距或者其他屬性,看上去不是很大的交易——因為它更簡單,看上去更好——但是電腦需要做的事情和人類比起來簡直是天壤之別,他要做的更加多更加槽糕。
瀏覽器團隊花費了很大的力氣在優化這些操作。Transforms真的很簡單就能提高效率,并且經常能夠充分利用你的圖形界面,而不用重新渲染元素。
第一次載入頁面的時候,你可能會抓狂——在所有的角落,使用圖片,在每個元素上加上陰影,如果你覺得特別粗糙,你甚至可以加上一個動態模糊。如果這只發生一次,一些額外的毫秒時間計算并不影響。但是一旦內容重新渲染,你不會想重新計算所有的內容。
#2
將內容藏在不起眼的地方
使用pointer-events:通過透明度為0來隱藏元素
這個屬性也許會有瀏覽器兼容的問題,但是如果你只是為webkit或者其他現代瀏覽器做東西,這會讓你的生活更美好。
過去很長一段時間,當動畫需要通過jQuery的animate()處理的時候,許多漸變元素的復雜來自切換“display“屬性實現的:在一個合
CSS的pointer-events屬性(這已經存在了很長時間了,但是不經常用),讓元素不回應任何點擊和交互,就像他們不在那邊一樣。它可以簡單地通過CSS切換開啟和關閉,而不通過打斷動畫或者以任何方法影響渲染/可見性。
與opacity為0結合使用,他基本上和display:none是一樣的效果,但是不觸發新的渲染而影響性能。當隱藏元素時,我可以常常只設置opacity為0,并且關閉pointer-events,然后遺忘元素,他會自己照顧自己。
這和絕對定位的元素一起工作地特別好,因為你會十分有信心,它對頁面其他的元素完全沒有影響。
這也給你更多的回旋余地,因為定時并不完美——這不是世界末日,如果一個元素是可點擊的或者在其他元素上遮蓋一秒或者更長,或者如果這僅僅能被點一次,然后就隱藏起來了。
#3
不要同一時間所有元素都做動畫
除非使用編排
一個單獨的動畫自己是流暢的,但是同一時間許多元素都做動畫,就會擾亂他們。創建單個的流暢動畫很簡單——但是一個數量級的動畫就很難確保性能達到滿分。因此,合理地規劃特別重要。
將時間分開,那么所有的元素都不在一個相同的時間開始。典型的是,2,3個可以在同一時間運行,而不需要減速,特別是如果他們在稍不同的時間開始動畫。
除非你的頁面上只有一個元素,不然理解 編排 是很重要的。這可能看上去像一個舞蹈編排,但事對于動畫接口來說是同樣重要的。元素需要在一個合適得位置合適的時間進入。及時他們都是分開的,他們必須感覺是設計好的的一個單元。
Google素材設計在這個主題上又很有意思的建議。這不僅僅是做事的正確方式,也是你需要考慮的事情和測試。
#4
輕微地增加延遲,讓編排動作變得簡單_
編排動畫真的十分重要,并且需要十分多的實驗和測試才能找到感覺。然而,他的代碼并不十分復雜。
我通常會改變父元素上的一個Class(通常是在body上),來觸發一系列變化,每一個在特定的時間有自己的過度延遲。從代碼觀點來說,你只需要關心狀態改變,并且不需要在javascript中維護一堆定時。
交錯安排一系列元素,是最簡單的編排你的元素的方法。這很強大,因為這同時看上去很好,同時也帶來了珍貴的性能——記住只有一小部分元素在同一時間開始。你會將他們分開直至感覺足夠流暢,但是不要分得太開,導致整體看上去太慢。足夠應該是重疊,這感覺像一個不間斷的流,而不是一系列獨立的個體元素。
代碼樣例
這里有一系列簡單的技巧,交錯排序你的元素——特別是如果是一長串元素。如果有少于10個元素,或者有一個不可估量的數量(就像在靜態頁面),然后我通常在CSS指定值。這是最簡單的便于維護的方法。
一個簡單的SASS循環
對于很長的元素列表或者一個動態的內容,定時器可能需要通過循環每個元素動態設置。
最簡單的javascript循環
這里有兩個常用變量:你的基本延遲和每個元素之間的延遲。這是一個需要尋找的微妙的平衡,但是當你敲擊正確的數字集,這會感覺非常好。
#5
使用全局倍數來設計慢動畫
然后加速之后所有的元素
對于動畫設計,定時就是一切。20%的工具是實現他們,并且其他80%是找到正確的參數&讓一切同步的間距,以及感覺流暢。
特別是在編排一系列元素的時候,嘗試壓榨性能和頁面并發性,看看所有的元素在慢動作下會讓事情變得簡單。
無論你是否用javascript,或者一些CSS預處理器,如Sass(我的最愛),這都需要直接做些額外的算數,和創建變量。
你必須確認嘗試一些不用的速度或者定時是很方便的。比如,如果一個動畫在十分之一的速度下都很卡頓,那么有可能從根本上就有問題。如果將它調至50倍速度依然流暢,那么問題就是要找到他所能達到的最快的速度。在全速之下,5毫秒的問題很難察覺,但是如果你降低了整體的速度,那么他們就會變得特別明顯。
特別對于十分復雜的動畫,或者解決棘手性能的瓶頸,在慢動作下查看元素的能力可能十分有用。
最主要的問題是,你想包裝許多完美的細節,當它變得慢的時候,然后提高整體的速度,因此這感覺是十分棒的。這十分微妙,但是用戶會察覺流暢以及細節。
這些特性只是OS X的一部分——如果你點擊shift按鈕來減小按鈕或者一個app圖標,你會看到他在慢速運行。在這一點上,當你按shift按鈕的時候,我們甚至可以在Gyroscope實現激活慢動畫。
#6
拍下你的UI,并且重放他們,以獲取有價值的第三方關點。
有時候一個不同的關點,能幫助你看事物更透徹,并且視頻是一個極佳總這件事的方法。
一些人在AE中創建視頻,并且嘗試將他們在網站上實現。我經常換做其他的方式,然后嘗試做一個來自網站的UI好視頻。
能夠發表vine或者一些video,是十分高桿的。有一天,我十分激動于我做的東西,并且嘗試做成視頻,分享給一些小伙伴。
然而,當我再看一次的時候,我發現有一堆東西不夠完美。有一個大的滯后阻礙了之后的動畫,并且所以的定時器都有一些問題。這讓我有些擔心,我最后沒有發表它而是意識到我還有許多工作要做。
當要在正式環境使用它的時候粉飾這些很容易,但是看在視頻上的動畫——一遍又一遍或者在一個很慢的速度——讓所有的問題都變得十分明顯。
他們說相機加了10磅。也許這也增加了10幀。
I 這現在也變成了我工作流中重要的一部分,查看頁面慢動畫視頻,以及如果有任何幀讓我感覺不對,就馬上做些改變。要怪罪于慢瀏覽器很容易,但是在一些更加優化的瀏覽器上,測試,有可能解決了所有的問題。
一旦你在視頻上捕捉滯后停頓不覺得尷尬的時候,并且感覺視頻夠好,能夠分享了,那么頁面差不多就可以準備上線了。
#7
網絡活動導致滯后
你需要提前或者滯后加載大的http請求
圖片是這個問題的最黑禍首們,是否一些大家伙(也許是一個大的背景)或者大量地小圖片(想象50個表情符加載),或者僅僅有許多內容(一個很長的到底都有圖片的頁面)。
當頁面第一次加載,大量的東西初始化和下載。有統計,廣告和其他的第三方腳本讓事情變得更糟糕。有時候,延遲所有的動畫到加載完幾百毫秒之后對性能有極大的幫助。
除非必要,不要過度優化,但是一個復雜的頁面也許需要十分準確的延遲和內容定時,然后才能運行路暢。通常上來說,你想要在開始加載盡可能少的內容,一旦重的部分和簡介動畫做完之后,不斷地加載頁面其余的部分。
有許多數據的頁面,加載所有的元素的工作量似乎是巨大的。一旦在做動畫的同時開始加載真實數據,一個動畫和靜態頁面運行地很好也許看上去是分開的。如果一些東西看上去應該工作或者有時候工作地流暢其他時間不流暢。我建議減產網絡活動,確認你沒有在同一時間做其他事情。
#8
不要直接綁定滾動
看上去是一個很酷的主意,但實際上不是。
在過去幾年中,滾動為基礎的動畫很受歡迎,特別是在視差或者其他特殊效果中。是否是好設計,有待辯論,但是有一些好或者槽糕的方法去實現他們。
在這個類別中,適度的優化做些的事是將達到滾動到一定距離作為一個事件——并且僅僅運行一次。除非你真的了解你在做什么,我會建議避免這個類別,因為這很容易出問題而且真的很難維護。
更加糟糕的是,創建你自己的滾動條功能,而不是用默認的——也就是 scrolljacking 。請不要做么做!
這條建議對手機來說特別有用,但是也可能是用戶體驗的好實踐。
如果你確實有一個特別的體驗,你想專注在滾動或者其他特殊事件,我會建議創建一個快速原型,以確保這在花費大時間設計的時候,能夠運行良好。
#9
盡早&經常在手機上測試。
大多數網站是在電腦上創建的,并且很有可能在他們創建的相同機器上運行測試。因此手機體驗和動畫性能經常是后知后覺的。一些技術(比如canvas)或者動畫技術在手機并沒有運行地這么好。
然而,如果編寫&優化適當(看規則#1),一個手機體驗可能會比電腦體驗還要好。手機優化是一個非常棘手的課題,但是新的iPhone現在比大多數手提都要快!如果你按照之前的建議編寫,你會發現你做的東西在手機上有著極佳的性能。
手機用法會是對于大多數網站都是一個非常大而且重要的部分。這看上去和極端,但是對于一整個項目,我會建議將手機從你的項目中分離出來。這不應該感覺像是一個懲罰去做手機版本,雖然經常會這樣。
保持設計進步&性能加強,知道這感覺被打磨流暢已經像網站的大版本那樣方便。
如果你強迫自己只用手機網站一個禮拜,你很可能就會將它優化得向大型網站一樣,有著的極佳體驗。經常懊惱地使用是值得的,這意味著在你的用戶體驗之前解決問題。
#10
在不同的設備上經常測試
屏幕大小,像素,或者設備都有著極大的暗示 . 除了手機vs桌面,有許多關鍵點會徹底影響性能,就像是否屏幕是“retina”屏,窗口的總像素,硬盤多老了,等等。
即使Chrome和Safari都是webkit的瀏覽器,有著相同的語法,他們也都有各自怪異行為。每一次chrome更新都會修復一些東西以及引入新的bug,因此你需要一直保持警覺。
當然,你不僅僅只希望創建最低水準的性能,因此找到最機智的方法來漸進添加或者移除增強功能會十分有用。
我經常在我的小Macbook和大的iMac之間切換,并且每次切換都引出了一些小問題并且做些改進——特別是依據動畫性能,但是對于總體設計,信息密度,可讀性,等等。
媒體查詢,常常是強大的工具來處理這些不同環節樣式,通過不同的高度或者寬度是最基礎的媒體查詢的用法。找出OS和設備的類型會很有用,因為手機性能特性和電腦很不一樣。
我希望你在你的下一個項目中,會找到有用的技巧。好運!
來自:http://www.zcfy.cc/article/10-principles-for-smooth-web-animations-gyroscope-1765.html