瀏覽器實(shí)現(xiàn)移動(dòng)端高性能css3動(dòng)畫(開啟gpu加速)

高性能移動(dòng)Web相較PC的場(chǎng)景需要考慮的因素也相對(duì)更多更復(fù)雜,我們總結(jié)為以下幾點(diǎn): 流量、功耗與流暢度。 在PC時(shí)代我們更多的是考慮體驗(yàn)上的流暢度,而在Mobile端本身豐富的場(chǎng)景下,需要額外關(guān)注對(duì)用戶基站網(wǎng)絡(luò)流量使用的情況,設(shè)備耗電量的情況。
關(guān)于流暢度,主要體現(xiàn)在前端動(dòng)畫中,在現(xiàn)有的前端動(dòng)畫體系中,通常有兩種模式:JS動(dòng)畫與CSS3動(dòng)畫。 JS動(dòng)畫是通過JS動(dòng)態(tài)改寫樣式實(shí)現(xiàn)動(dòng)畫能力的一種方案,在PC端兼容低端瀏覽器中不失為一種推薦方案。 而在移動(dòng)端,我們選擇性能更優(yōu)瀏覽器原生實(shí)現(xiàn)方案:CSS3動(dòng)畫。
然而,CSS3動(dòng)畫在移動(dòng)多終端設(shè)備場(chǎng)景下,相比PC會(huì)面對(duì)更多的性能問題,主要體現(xiàn)在動(dòng)畫的卡頓與閃爍。
目前對(duì)提升移動(dòng)端CSS3動(dòng)畫體驗(yàn)的主要方法有幾點(diǎn):
盡可能多的利用硬件能力,如使用3D變形來開啟GPU加速
-webkit-transform: translate3d(0, 0, 0);
-moz-transform: translate3d(0, 0, 0);
-ms-transform: translate3d(0, 0, 0);
transform: translate3d(0, 0, 0);
如動(dòng)畫過程有閃爍(通常發(fā)生在動(dòng)畫開始的時(shí)候),可以嘗試下面的Hack:
-webkit-backface-visibility: hidden;
-moz-backface-visibility: hidden;
-ms-backface-visibility: hidden;
backface-visibility: hidden;
-webkit-perspective: 1000;
-moz-perspective: 1000;
-ms-perspective: 1000;
perspective: 1000;
如下面一個(gè)元素通過translate3d右移500px的動(dòng)畫流暢度會(huì)明顯優(yōu)于使用left屬性:
#ball-1 {
transition: -webkit-transform .5s ease;
-webkit-transform: translate3d(0, 0, 0);
}
#ball-1.slidein {
-webkit-transform: translate3d(500px, 0, 0);
}
#ball-2 {
transition: left .5s ease;
left:0;
}
#ball-2.slidein {
left:500px;
}
注:3D變形會(huì)消耗更多的內(nèi)存與功耗,應(yīng)確實(shí)有性能問題時(shí)才去使用它,兼在權(quán)衡
盡可能少的使用box-shadows與gradients
box-shadows與gradients往往都是頁面的性能殺手,尤其是在一個(gè)元素同時(shí)都使用了它們,所以擁抱扁平化設(shè)計(jì)吧。
盡可能的讓動(dòng)畫元素不在文檔流中,以減少重排
position: fixed;
position: absolute;
優(yōu)化 DOM layout 性能
我們從實(shí)例開始描述這個(gè)主題:
var newWidth = aDiv.offsetWidth + 10;
aDiv.style.width = newWidth + 'px';
var newHeight = aDiv.offsetHeight + 10;
aDiv.style.height = newHeight + 'px';
var newWidth = aDiv.offsetWidth + 10;
var newHeight = aDiv.offsetHeight + 10;
aDiv.style.width = newWidth + 'px';
aDiv.style.height = newHeight + 'px';
這是兩段能力上完全等同的代碼,顯式的差異正如我們所見,只有執(zhí)行順序的區(qū)別。但真是如此嗎?下面是加了說明注釋的代碼版本,很好的闡述了其中的進(jìn)一步差異:
// 觸發(fā)兩次 layout
var newWidth = aDiv.offsetWidth + 10; // Read
aDiv.style.width = newWidth + 'px'; // Write
var newHeight = aDiv.offsetHeight + 10; // Read
aDiv.style.height = newHeight + 'px'; // Write
// 只觸發(fā)一次 layout
var newWidth = aDiv.offsetWidth + 10; // Read
var newHeight = aDiv.offsetHeight + 10; // Read
aDiv.style.width = newWidth + 'px'; // Write
aDiv.style.height = newHeight + 'px'; // Write
從注釋中可找到規(guī)律,連續(xù)的讀取offsetWidth/Height屬性與連續(xù)的設(shè)置width/height屬性,相比分別讀取設(shè)置單個(gè)屬性可少觸發(fā)一次layout。
從結(jié)論看似乎與執(zhí)行隊(duì)列有關(guān),沒錯(cuò),這是瀏覽器的優(yōu)化策略。所有可觸發(fā)layout的操作都會(huì)被暫時(shí)放入 layout-queue 中,等到必須更新的時(shí)候,再計(jì)算整個(gè)隊(duì)列中所有操作影響的結(jié)果,如此就可只進(jìn)行一次的layout,從而提升性能。
關(guān)鍵一,可觸發(fā)layout的操作,哪些操作下會(huì)layout的更新(也稱為reflow或者relayout)?
我們從瀏覽器的源碼實(shí)現(xiàn)入手,以開源Webkit/Blink為例, 對(duì)layout的更新,Webkit 主要通過 Document::updateLayout 與Document::updateLayoutIgnorePendingStylesheets 兩個(gè)方法:
void Document::updateLayout()
{
ASSERT(isMainThread());
FrameView* frameView = view();
if (frameView && frameView->isInLayout()) {
ASSERT_NOT_REACHED();
return;
}
if (Element* oe = ownerElement())
oe->document()->updateLayout();
updateStyleIfNeeded();
StackStats::LayoutCheckPoint layoutCheckPoint;
if (frameView && renderer() && (frameView->layoutPending() || renderer()->needsLayout()))
frameView->layout();
if (m_focusedNode && !m_didPostCheckFocusedNodeTask) {
postTask(CheckFocusedNodeTask::create());
m_didPostCheckFocusedNodeTask = true;
}
}
void Document::updateLayoutIgnorePendingStylesheets()
{
bool oldIgnore = m_ignorePendingStylesheets;
if (!haveStylesheetsLoaded()) {
m_ignorePendingStylesheets = true;
HTMLElement* bodyElement = body();
if (bodyElement && !bodyElement->renderer() && m_pendingSheetLayout == NoLayoutWithPendingSheets) {
m_pendingSheetLayout = DidLayoutWithPendingSheets;
styleResolverChanged(RecalcStyleImmediately);
} else if (m_hasNodesWithPlaceholderStyle)
recalcStyle(Force);
}
updateLayout();
m_ignorePendingStylesheets = oldIgnore;
}
從 updateLayoutIgnorePendingStylesheets 方法的內(nèi)部實(shí)現(xiàn)可知,其也是對(duì) updateLayout 方法的擴(kuò)展,并且在現(xiàn)有的 layout 更新模式中,大部分場(chǎng)景都是調(diào)用 updateLayoutIgnorePendingStylesheets 來進(jìn)行l(wèi)ayout的更新。
搜索 Webkit 實(shí)現(xiàn)中調(diào)用 updateLayoutIgnorePendingStylesheets 方法的代碼, 得到以下可導(dǎo)致觸發(fā) layout 的操作:
Element: clientHeight, clientLeft, clientTop, clientWidth, focus(), getBoundingClientRect(), getClientRects(), innerText, offsetHeight, offsetLeft, offsetParent, offsetTop, offsetWidth, outerText, scrollByLines(), scrollByPages(), scrollHeight, scrollIntoView(), scrollIntoViewIfNeeded(), scrollLeft, scrollTop, scrollWidth
Frame, HTMLImageElement: height, width
Range: getBoundingClientRect(), getClientRects()
SVGLocatable: computeCTM(), getBBox()
SVGTextContent: getCharNumAtPosition(), getComputedTextLength(), getEndPositionOfChar(), getExtentOfChar(), getNumberOfChars(), getRotationOfChar(), getStartPositionOfChar(), getSubStringLength(), selectSubString()
SVGUse: instanceRoot
window: getComputedStyle(), scrollBy(), scrollTo(), scrollX, scrollY, webkitConvertPointFromNodeToPage(), webkitConvertPointFromPageToNode()
相關(guān)文章
怎么開啟GPU加速 QQ瀏覽器和360瀏覽器開啟GPU加速的方法步驟
怎么愛win10系統(tǒng)上開啟GPU加速?QQ瀏覽器和360瀏覽器開啟GPU加速的方法步驟,需要的朋友不要錯(cuò)過哦2020-06-10很嚇人的黑科技 余承東公布華為革命性圖形處理加速技術(shù)GPU Turbo
華為消費(fèi)者業(yè)務(wù)CEO余承東今天下午不僅出現(xiàn)在北京首都體育學(xué)院舉辦的榮耀突破性技術(shù)暨榮耀Play新品發(fā)布會(huì)上,還為我們帶來了傳言中“很嚇人的技術(shù)”——GPU Turbo!趕緊看看2018-06-07edge瀏覽器內(nèi)置flash如何設(shè)置硬件加速?Edge瀏覽器硬件加速GPU的方法
加快網(wǎng)頁打開速度,又能減輕CPU負(fù)擔(dān),降低瀏覽網(wǎng)頁時(shí)的系統(tǒng)資源占用,一些使用win10操作系統(tǒng)的朋友想要設(shè)置edge瀏覽器內(nèi)置flash的硬件加速,但是又不知道該如何設(shè)置,接下2018-05-16GPU硬件加速 享受酣暢淋漓的上網(wǎng)體驗(yàn)
如何享受酣暢淋漓的上網(wǎng)體驗(yàn)?開啟GPU硬件加速,真正享受電腦軟件、圖形處理和一些網(wǎng)站增強(qiáng)的用戶體驗(yàn),下面就為大家分享GPU硬件加速的開啟方法2016-04-27win8系統(tǒng)如何關(guān)閉IE瀏覽器硬件加速功能?win8系統(tǒng)關(guān)閉IE瀏覽器GPU加速
有win8用戶反映使用IE瀏覽器在線觀看視頻,有時(shí)我們會(huì)遇到播放視頻異?,F(xiàn)象,比如圖像不顯示、出現(xiàn)黑屏、白屏或只有聲音沒有圖像等情況,這是怎么回事呢?這種情況怎么辦呢2016-03-31Win8下打不開ATI顯卡的軟件及在photoshop中無法使用gpu加速功能
Win8系統(tǒng)不需要手動(dòng)安裝驅(qū)動(dòng)程序,但在Win8系統(tǒng)下打不開ATI顯卡的軟件以及在photoshop中無法使用gpu加速功能,關(guān)于這個(gè)問題的解決方法如下2014-10-29如何設(shè)置IE11瀏覽器把GPU加速的選項(xiàng)關(guān)閉
沒有獨(dú)立顯卡的老電腦用IE11觀看在線視頻時(shí),會(huì)自動(dòng)關(guān)閉,該怎么辦?可以下載播放器的插件或者設(shè)置IE11瀏覽器把GPU加速的選項(xiàng)關(guān)閉就可以了,下面本文將講述如何設(shè)置IE11瀏2014-09-30使用IE9時(shí)出現(xiàn)藍(lán)屏或死機(jī)通過禁用GPU硬件加速來解決
IE9出現(xiàn)藍(lán)屏或死機(jī)的情況目前有兩個(gè)解決方法:刪除KB2670838更新及禁用IE9 GPU硬件加速,兩者的具體操作過程如下,有類似問題的朋友可以參考下哈,希望對(duì)大家有所幫助2013-07-08Internet Explorer 9找不到“加速的圖形 - 使用軟件呈現(xiàn)而不使用 GPU
WIN7系統(tǒng)下---Internet Explorer 9 瀏覽器,打開“Internet選項(xiàng)〉高級(jí)”的時(shí)候,卻找不到“加速的圖形 - 使用軟件呈現(xiàn)而不使用 GPU 呈現(xiàn)”這個(gè)選項(xiàng)呢?2012-05-09win10 2004怎么才能開啟硬件GPU加速 GPU加速設(shè)置教程
win10 2004怎么才能開啟硬件GPU加速呢?硬件GPU加速需要什么條件呢?下面就和腳本之家小編一起了解下吧2020-06-10