Chrome渲染分析之Rendering工具使用(2)

距离这个专题的上一篇 《Chrome渲染分析之Rendering工具使用(1)》 已经隔了一年多了,迟迟没有下笔,囧!

2.show composited layer borders

中文可翻译为:显示层的组合边界。

我们知道,在页面最终是由多个“图层”渲染而成。勾上这个选项,页面上的“layer(层)”会加上一个黄色的边框显示出来,如下图的 天猫首页 头部所示:

其中:

  • 黄色边框:用于显示页面上的layer
  • 蓝色栅格线:表示的是分块,这些分块可以看作是比层更低一级的单位

当然,还有其他颜色的边框线,比如图片如果单独有个layer的话,边框线是 蓝色的 

使用这个工具,可以查看当前页面的layer情况,更好的发现页面不需要的layer将之清除。

layer存在的意义

在弄明白这个问题之前,我们需要先了解一个dom元素最终是如何转变为我们屏幕上可视的图像。在概念上讲,可简单的分为四个步骤:

  1. 获取 DOM 并将其分割为多个层
  2. 将每个层独立的绘制进位图中
  3. 将层作为纹理上传至 GPU
  4. 复合多个层来生成最终的屏幕图像。

可以将这个过程理解为设计师的Photoshop文件。在ps源文件里,一个图像是由若干个图层相互叠加而展示出来的。分成多个图层的好处就是每个图层相对独立,修改方便,对单个图层的修改不会影响到页面上的其他图层。

基于photoshop的图层理念来理解web端的层,那么就很容易理解了。layer存在的意义在于: 用最小的代价来改变某个页面元素 

我们可以将某个css动画或某个js交互效果把它抽离到一个单独的渲染层,这样可以加快渲染的效率。

如何创建layer

  • 3D 或透视变换(perspective transform) CSS 属性
  • 使用加速视频解码的 <video> 元素
  • 拥有 3D (WebGL) 上下文或加速的 2D 上下文的 <canvas> 元素
  • 混合插件(如 Flash)
  • 对自己的 opacity 做 CSS 动画或使用一个动画 webkit 变换的元素
  • 拥有加速 CSS 过滤器的元素
  • 元素有一个包含复合层的后代节点(换句话说,就是一个元素拥有一个子元素,该子元素在自己的层里)
  • 元素有一个 z-index 较低且包含一个复合层的兄弟元素(换句话说就是该元素在复合层上面渲染),关于这点,更详细的实践可查看 该文章

在webkit内核的浏览器中,如果有上述情况,则会创建一个独立的layer。

其中第一点是最常用的手段,比如我们有时候给一个css效果加上 transform: translateZ(0); ,目的就是为了创建一个独立的layer。

另外还有另外一个css属性: will-change 也能实现同样的效果。

layer 过多带来的问题

还是拿photoshop来做比喻,一个ps文件如果有非常多的图层,那么这个文件肯定是非常大的。那对于web端也是一样,创建一个新的渲染层,它得消耗额外的内存和管理资源。当在内存资源有限的设备,比如手机上,由于过多的渲染层来带的开销而对页面渲染性能产生的影响,甚至远远超过了它在性能改善上带来的好处。

举个栗子,我们在天猫首页上加入css: * {-webkit-transform: translateZ(0);} 。 然后使用 timeline 可以看到,天猫的渲染耗时非常严重。

其影响的是页面渲染的最后一个环节: Composite Layers 

那么,一个合理的策略是: 当且仅当需要的时候才为元素创建渲染层。

更直观的查看页面layer

除了rendering 里提供的 show composited layer borders 选项外,还有一个更为直观的3d图像展示:

先选中 timeline 的某一帧,然后选择下面的 layer 标签tab,在右侧的区域就可以看到整个页面的3d图层了。

在这个视图中,你可以对这一帧中的所有渲染层进行扫描、缩放等操作,同时还能看到每个渲染层被创建的原因。

扩展阅读

若需要更细致的资料,可以查看下面这些文章。(可能需要翻墙)

wordpress 使用七牛镜像插件与SyntaxHighlighter插件冲突的解决方法

今天本博的阿里云服务器过期了。早上起来续费,发现要2k大洋。想想心疼啊,博客日访问量不超200UV,搞个大宽带,着实浪费。

续费时,就选了流量按需收费,0.8元/G。为了节省带宽,想到了用七牛云存储来保存及加速图片。

于是,在七牛上注册了账户,并安装了水煮鱼的 七牛镜像存储插件

整个过程一切顺利,图片成功转换为七牛图片了。但发现文章里的代码片段无法显示了。而我使用的是 SyntaxHighlighter 插件来高亮代码,于是我判断应该是 七牛镜像存储插件 与 SyntaxHighlighter插件 冲突。

google了一番,发现没有解决方案,莫非同时安装这2个插件的人太少?泥煤啊。

于是,只有放弃使用七牛镜像插件了。看了下七牛加速的原理,实际就是一个url替换,比如我的这张图片: http://www.ghugo.com/wp-content/uploads/2015/08/52.png 只需要替换域名后就可以直接使用 http://7qnca0.com1.z0.glb.clouddn.com/wp-content/uploads/2015/08/52.png

那么简单的一个功能,也不需要专门使用插件来处理了,直接写代码替换下即可。于是继续google一下,找到一段代码,将如下代码贴到你主题里的 functions.php 文件最末尾即可。


if ( !is_admin() ) {
    add_action('wp_loaded','c7sky_ob_start');
    
    function c7sky_ob_start() {
        ob_start('c7sky_qiniu_cdn_replace');
    }
    
    //修改自七牛镜像存储 WordPress 插件
function c7sky_qiniu_cdn_replace($html){
    $local_host = 'http://www.ghugo.com'; //博客域名
    $qiniu_host = 'http://7qnca0.com1.z0.glb.clouddn.com'; //七牛域名
    $cdn_exts   = 'css|png|jpg|jpeg|gif|ico'; //扩展名(使用|分隔)
    $cdn_dirs   = 'wp-content|wp-includes'; //目录(使用|分隔)
    
    $cdn_dirs   = str_replace('-', '\-', $cdn_dirs);

    if ($cdn_dirs) {
        $regex  =  '/' . str_replace('/', '\/', $local_host) . '\/((' . $cdn_dirs . ')\/[^\s\?\\\'\"\;\>\<]{1,}.(' . $cdn_exts . '))([\"\\\'\s\?]{1})/'; $html = preg_replace($regex, $qiniu_host . '/$1$4', $html); } else { $regex = '/' . str_replace('/', '\/', $local_host) . '\/([^\s\?\\\'\"\;\>\<]{1,}.(' . $cdn_exts . '))([\"\\\'\s\?]{1})/';
        $html =  preg_replace($regex, $qiniu_host . '/$1$3', $html);
    }
    return $html;
}
}

七牛云加速就是那么简单!