自在搞定网页设计(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;

 

 

 

 

 

如下边一个因素通过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往往都是页面的属性杀手,尤其是在一个因素同时都拔取了它们,所以拥抱扁平化设计吧。

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

 

 
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的换代。

 

相关文章