溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊(cè)×
其他方式登錄
點(diǎn)擊 登錄注冊(cè) 即表示同意《億速云用戶服務(wù)條款》

瀏覽器怎么實(shí)現(xiàn)移動(dòng)端高性能css3動(dòng)畫(huà)

發(fā)布時(shí)間:2021-08-07 23:43:16 來(lái)源:億速云 閱讀:99 作者:chen 欄目:web開(kāi)發(fā)

本篇內(nèi)容主要講解“瀏覽器怎么實(shí)現(xiàn)移動(dòng)端高性能css3動(dòng)畫(huà)”,感興趣的朋友不妨來(lái)看看。本文介紹的方法操作簡(jiǎn)單快捷,實(shí)用性強(qiáng)。下面就讓小編來(lái)帶大家學(xué)習(xí)“瀏覽器怎么實(shí)現(xiàn)移動(dòng)端高性能css3動(dòng)畫(huà)”吧!

高性能移動(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)畫(huà)中,在現(xiàn)有的前端動(dòng)畫(huà)體系中,通常有兩種模式:JS動(dòng)畫(huà)與CSS3動(dòng)畫(huà)。 JS動(dòng)畫(huà)是通過(guò)JS動(dòng)態(tài)改寫(xiě)樣式實(shí)現(xiàn)動(dòng)畫(huà)能力的一種方案,在PC端兼容低端瀏覽器中不失為一種推薦方案。 而在移動(dòng)端,我們選擇性能更優(yōu)瀏覽器原生實(shí)現(xiàn)方案:CSS3動(dòng)畫(huà)。
然而,CSS3動(dòng)畫(huà)在移動(dòng)多終端設(shè)備場(chǎng)景下,相比PC會(huì)面對(duì)更多的性能問(wèn)題,主要體現(xiàn)在動(dòng)畫(huà)的卡頓與閃爍。
目前對(duì)提升移動(dòng)端CSS3動(dòng)畫(huà)體驗(yàn)的主要方法有幾點(diǎn):

盡可能多的利用硬件能力,如使用3D變形來(lái)開(kāi)啟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)畫(huà)過(guò)程有閃爍(通常發(fā)生在動(dòng)畫(huà)開(kāi)始的時(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è)元素通過(guò)translate3d右移500px的動(dòng)畫(huà)流暢度會(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í)有性能問(wèn)題時(shí)才去使用它,兼在權(quán)衡

盡可能少的使用box-shadows與gradients

box-shadows與gradients往往都是頁(yè)面的性能殺手,尤其是在一個(gè)元素同時(shí)都使用了它們,所以擁抱扁平化設(shè)計(jì)吧。
盡可能的讓動(dòng)畫(huà)元素不在文檔流中,以減少重排

代碼如下:


position: fixed;
position: absolute;

優(yōu)化 DOM layout 性能

我們從實(shí)例開(kāi)始描述這個(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';

這是兩段能力上完全等同的代碼,顯式的差異正如我們所見(jiàn),只有執(zhí)行順序的區(qū)別。但真是如此嗎?下面是加了說(shuō)明注釋的代碼版本,很好的闡述了其中的進(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),沒(méi)錯(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)入手,以開(kāi)源Webkit/Blink為例, 對(duì)layout的更新,Webkit 主要通過(guò) 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 來(lái)進(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()

到此,相信大家對(duì)“瀏覽器怎么實(shí)現(xiàn)移動(dòng)端高性能css3動(dòng)畫(huà)”有了更深的了解,不妨來(lái)實(shí)際操作一番吧!這里是億速云網(wǎng)站,更多相關(guān)內(nèi)容可以進(jìn)入相關(guān)頻道進(jìn)行查詢,關(guān)注我們,繼續(xù)學(xué)習(xí)!

向AI問(wèn)一下細(xì)節(jié)

免責(zé)聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點(diǎn)不代表本網(wǎng)站立場(chǎng),如果涉及侵權(quán)請(qǐng)聯(lián)系站長(zhǎng)郵箱:is@yisu.com進(jìn)行舉報(bào),并提供相關(guān)證據(jù),一經(jīng)查實(shí),將立刻刪除涉嫌侵權(quán)內(nèi)容。

css
AI