自在解决网页设计(html+css+js)》 ,轻松解决网页设计(html+css+js)》 

  • CSS动画属性会触发整个页面的重排relayout、重绘repaint、重组recomposite
  • Paint常常是内部最开支品质的,尽大概幸免使用触发paint的CSS动画属性,那也是干什么我们引进在CSS动画中利用 webkit-transform: translateX(3em)的方案代替使用 left: 3em,因为left会额外触发layout与paint,而webkit-transform只触及整个页面composite
  • CSS动画属性会触发整个页面的重排relayout、重绘repaint、重组recomposite
  • Paint日常是里面最开销质量的,尽大概防止使用触发paint的CSS动画属性,那也是为啥大家推荐在CSS动画中使用 webkit-transform: translateX(3em)的方案代替使用 left: 3em,因为left会额外触发layout与paint,而webkit-transform只接触整个页面composite

 

 

 

 

 
div {
  -webkit-animation-duration: 5s;
  -webkit-animation-name: move;
  -webkit-animation-iteration-count: infinite;
  -webkit-animation-direction: alternate;
  width: 200px;
  height: 200px;
  margin: 100px;
  background-color: #808080;
  position: absolute;
}
 
div {
  -webkit-animation-duration: 5s;
  -webkit-animation-name: move;
  -webkit-animation-iteration-count: infinite;
  -webkit-animation-direction: alternate;
  width: 200px;
  height: 200px;
  margin: 100px;
  background-color: #808080;
  position: absolute;
}

 

 

 

 

 
@-webkit-keyframes move{
    from {
        left: 100px;
    }
    to {
        left: 200px;
    }
}
 
@-webkit-keyframes move{
    from {
        left: 100px;
    }
    to {
        left: 200px;
    }
}

 

 

 

 

 

 

 

 

 

 

如下图使用left将持续触发页面重绘,表现为石黄边框:

正如图使用left将四处触发页面重绘,表现为粉红色边框:

图片 1

图片 2

 

 

 
@-webkit-keyframes move{
    from {
        -webkit-transform: translateX(100px);
    }
    to {
        -webkit-transform: translateX(200px);
    }
}
 
@-webkit-keyframes move{
    from {
        -webkit-transform: translateX(100px);
    }
    to {
        -webkit-transform: translateX(200px);
    }
}

 

 

 

 

 

 

 

 

 

 

附:《[韩顺平]自在解决网页设计(html+css+js)》 http://www.gooln.com/dir/16908.html 

附:《[韩顺平]轻松解决网页设计(html+css+js)》 http://www.gooln.com/dir/16908.html 

正如图使用-webkit-transform页面只发生结合,表现为桔红边框:

一般来说图使用-webkit-transform页面只爆发结合,表现为浅绿灰边框:

图片 3

图片 4

  • CSS属性在CSS动画中行为表
  • CSS属性在CSS动画中行为表

图片 5

图片 6

高性能 CSS3 动画

高品质移动Web相较PC的场景必要考虑的因素也针锋相对更加多更复杂,大家统计为以下几点: 流量、耗能与流畅度。
在PC时期大家愈来愈多的是考虑体验上的流畅度,而在Mobile端本身丰硕的情景下,须要额外关切对用户基站互联网流量使用的景况,设备功耗量的情状。

关于流畅度,首要显示在前端动画中,在存活的前端动画种类中,经常有两种形式:JS动画与CSS3动画片。
JS动画是通过JS动态改写样式落成动画能力的一种方案,在PC端包容低端浏览器中正是一种推荐方案。
而在移动端,大家接纳品质更优浏览器原生已毕方案:CSS3动画。

而是,CSS3动画在运动多终端设备场景下,相比PC相会对更加多的品质问题,首要反映在动画的卡顿与闪亮。

当下对升级活动端CSS3动画体验的重大方法有几点:

高性能 CSS3 动画

高品质移动Web相较PC的意况要求考虑的因素也相对更多更扑朔迷离,大家总括为以下几点: 流量、功耗与流畅度。
在PC时期大家越多的是考虑体验上的流畅度,而在Mobile端自身丰盛的场所下,必要出色关心对用户基站网络流量使用的气象,设备耗能量的景色。

关于流畅度,主要显示在前者动画中,在现有的前端动画种类中,经常有二种方式:JS动画与CSS3动画片。
JS动画是因此JS动态改写样式完结动画能力的一种方案,在PC端包容低端浏览器中正是一种推荐方案。
而在移动端,大家选取品质更优浏览器原生落成方案:CSS3动画。

不过,CSS3动画在运动多终端设备场景下,比较PC相会对越来越多的性情难点,主要反映在动画的卡顿与闪亮。

此时此刻对升官活动端CSS3动画体验的紧要性情局有几点:

尽心尽力多的拔取硬件能力,如使用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);

 

 

 

如动画进度有闪光(日常发生在动画先河的时候),可以品味下边的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;

 

 

 

 

 

如上边1个成分通过translate3d右移500px的动画流畅度会肯定优于使用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变形会消耗越多的内存与功耗,应真正有质量难题时才去行使它,兼在衡量

尽量多的行使硬件能力,如应用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);

 

 

 

如动画进程有闪光(平常发生在动画早先的时候),可以品味下边的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;

 

 

 

 

 

如上边二个要素通过translate3d右移500px的卡通流畅度会分明优于使用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变形会花费更加多的内存与耗电,应真正有品质难点时才去行使它,兼在衡量

尽只怕少的应用box-shadowsgradients

box-shadowsgradients屡次都以页面的个性刀客,特别是在二个要素同时都采纳了它们,所以拥抱扁平化设计啊。

尽大概少的拔取box-shadowsgradients

box-shadowsgradients数次都是页面的质量刀客,特别是在1个成分同时都使用了它们,所以拥抱扁平化设计吧。

尽量的让动画成分不在文档流中,以减小重排

 

 
position: fixed;
position: absolute;
 

 

尽量的让动画成分不在文档流中,以减弱重排

 

 
position: fixed;
position: absolute;
 

 

 

 

优化 DOM layout 性能

大家从实例开端描述这一个主旨:

 

 
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’;

 

 

 

 

 

这是两段能力上完全等同的代码,显式的出入正如咱们所见,唯有举行种种的界别。但正是如此呢?上边是加了证实注释的代码版本,很好的讲演了中间的愈来愈差别:

 

 
// 触发两次 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
 
// 只触发一次 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

 

 

 

 

 

 

从注释中可找到规律,一而再的读取offsetWidth/Height属性与一连的设置width/height属性,相比较分别读取设置单个属性可少触发一次layout。

从结论看就如与履行队列有关,没错,那是浏览器的优化策略。全体可触发layout的操作都会被目前放入 layout-queue 中,等到必须创新的时候,再总括整个队列中拥有操作影响的结果,如此就可只举行五次的layout,从而升高质量。

关键一,可触发layout的操作,哪些操作下会layout的立异(也号称reflow或者relayout)?

大家从浏览器的源码完成入手,以开源Webkit/Blink为例,
对layout的换代,Webkit
主要透过 Document::updateLayout 与Document::updateLayoutIgnorePendingStylesheets 多少个方法:

 

 
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 方法的内部贯彻可见,其也是对 updateLayout 方法的恢弘,并且在存活的
layout 更新形式中,半数以上景观都以调用
updateLayoutIgnorePendingStylesheets 来开展layout的立异。

 

优化 DOM layout 性能

我们从实例初叶描述这么些焦点:

 

 
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’;

 

 

 

 

 

那是两段能力上完全一样的代码,显式的分裂正如咱们所见,唯有进行顺序的区分。但正是如此呢?下边是加了求证注释的代码版本,很好的阐释了内部的愈益差别:

 

 
// 触发两次 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
 
// 只触发一次 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

 

 

 

 

 

 

从注释中可找到规律,接二连三的读取offsetWidth/Height属性与延续的装置width/height属性,比较分别读取设置单个属性可少触发四遍layout。

从结论看犹如与实施队列有关,没错,那是浏览器的优化策略。全数可触发layout的操作都会被一时半刻放入 layout-queue 中,等到必须创新的时候,再统计整个队列中装有操作影响的结果,如此就可只进行一遍的layout,从而提高质量。

关键一,可触发layout的操作,哪些操作下会layout的革新(也号称reflow或者relayout)?

小编们从浏览器的源码已毕入手,以开源Webkit/Blink为例,
对layout的换代,Webkit
首要通过 Document::updateLayout 与Document::updateLayoutIgnorePendingStylesheets 多个形式:

 

 
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 方法的中间贯彻可知,其也是对 updateLayout 方法的扩展,并且在现有的
layout 更新方式中,半数以上现象都是调用
updateLayoutIgnorePendingStylesheets 来开展layout的翻新。

 

相关文章