避免无用的渲染绘制(Avoiding Unnecessary Paints)
本文翻译自html5rock上的文章,文章英文原版地址在最后给出。
文中的Paints我翻译成渲染绘制,我自己是这么理解。
开始
绘制(渲染)一个网站或者一个应用的元素对浏览器来说开销是很大的,它会对运行时的效率产生负面影响,在这篇文章中我们将快速的过一遍,哪些情况会导致导致绘制事件在浏览器中产生,以及如何在你今后的工作中尽量避免没必要的绘制。
绘制(渲染):一场超快的旅行
浏览器的主要任务之一就是将DOM和CSS转换成像素并绘制到屏目上,这是一系列复杂的处理过程。浏览器先读取HTML标签并由此创建DOM树,它对CSS也是进行了类似的工作,读取CSS并创建CSSOM树,然后将两者合并,最终我们就可以根据合并后的结构渲染成像素到屏目了
绘制过程本身就挺有趣。在Chrome浏览器中,合并后的DOM树与CSS树被一款名叫Skia的软件进行栅格化。如果你曾使用过CANVAS的API,那么你会觉得它们的API非常相似。
不光是moveTo, lineTo等这些API,另外的一些高级API也一样非常相似。本质上来讲,所有需要被绘制的元素都将被提取到能被Skia执行的集合中,执行后输出的是一堆位图。这些位图将被上传到GPU中,GPU将帮他们组合在一起并最终输出到屏目上。
Skia的工作量是直接受你在元素上所应用的样式引响的。如果你在元素应用的样式算法很复杂那么,会大大加重Skia的工作。你可以参考这篇文章article on how CSS affects page render weight,以更深的理解CSS如何影响页面渲染。
总而言之,绘制工作费时间,如果我们不减少绘制,那么可能会掉侦。用户可能会注意到掉帧,看起来会闪一下。这对于我们的APP上来说是从根本上伤害了用户体验。我们不希望看到这样的结果吧,so让我们来看看哪些东西会产生必要的绘制(渲染)工作,以及我们能对这些做些啥优化。
Scrolling(滚动)
无论你是往上还是往下滚动,内容在显示到屏目上之前浏览器都需要进行重绘。如果一切顺利的话,可能产生重绘的区域会是很小一块,但是即使是很小一块,那一小块元素可能就是应用了复杂的CSS样式。所以不会因为绘制的区域小而绘制的速度会快。
为了看清哪些区域被重绘了,你可以使用Chrome中自带的调试工具,点击右上角的设置按钮,选中 “Show Paint Rectangles”后,在你的页面中做一些简单的交互,你便会看到一些会闪动的矩形框,那就是重绘的区域了。
滚动的性能表现,是你网站成功的关键。用户真的会关心你的站点或应用滚动的是不是顺畅,他们可不会喜欢滚动的不流畅的网站。我们在滚动时保证轻量的绘制工作,因此而得到的一个好处就是用户看不到闪动或掉帧这类事情了。
我之前已经写过一篇文章是关于滚动性能的,如果你想了解更我,可以参考这篇文章 article on scrolling performance
Interactions(交互)
交互是另一个产生绘制工作的原因,如:hovers, click,touches drags无论用户执行了其中的哪一样操作都会引发绘制或重绘。让我们以hover举个栗子,当hover某个元素时,Chrome不得不重绘那个被hover影响的元素。如果滚动时有一个很大很复杂的重绘工作,那么你将会看到绘制帧频的下降。
大家都想要好的、流畅的交互动画,这咱又得关心一下动画样式在变化时的花费时间及性能成本
An unfortunate combination(不幸的组合)
当我滚动的同时移动鼠标时会发生什么 ?在无意中是完全有可能触发昂贵的重绘开销的,这将导致我的帧频率小于16.7ms(我们应该保持在每秒60帧的频率)。我已经写了一个demo来更直观的表达我所说的情况created a demo 希望你在滚动的同时移动鼠标能看到hover效果。但是让我们看看Chrome调试工具告诉了我们什么
在上图中你可以看到,当我在某一个块元素上(blocks)上hover时调试工具已捕获了绘制工作。为了看效果,我在demo中疯狂的加重了样式效果(缩放,阴间等动画效果)。这导致帧频逼近或偶尔间超过了帧频的临界值。最后我想要的是减少不必要的绘制工作,尤其是在滚动时。
我们如何实现呢,实现其实很简单,技巧是添加一个scroll回调handler处理函数,在这个函数内禁止hover效果,同时设置一个计时器,用以恢复hover效果。这意谓着我们保证在滚动时禁止一些开销昂贵的交互效果,并且在停止滚动足够的时间后恢复那些效果
实际应用时注意!
改变此项会影响你应用程序用户体验,所以明智的对待它,延时恢复效果要在你和的团队能接受的时间范围内
这是对应的代码
// Used to track the enabling of hover effects
var enableTimer = 0; /*
* Listen for a scroll and use that to remove
* the possibility of hover effects
*/
window.addEventListener('scroll', function() {
clearTimeout(enableTimer);
removeHoverClass(); // enable after 1 second, choose your own value here!
enableTimer = setTimeout(addHoverClass, 1000);
}, false); /**
* Removes the hover class from the body. Hover styles
* are reliant on this class being present
*/
function removeHoverClass() {
document.body.classList.remove('hover');
} /**
* Adds the hover class to the body. Hover styles
* are reliant on this class being present
*/
function addHoverClass() {
document.body.classList.add('hover');
}
如你所见,我们用了一个class来决定hover效果是否被允许使用,下面就是这个class的css表达式
/* Expect the hover class to be on the body
before doing any hover effects */
.hover .block:hover {
…
}
这就是所有的内容了
Conclusion(结束语)
渲染的性能表现对于用户是否喜欢你的应用至关重要,你需要的是尽量保证绘制工作量保持在16ms帧频率以下,为了帮助实现这一目标,你得使调式工具一直贯穿于你的开发过程中,确保帧频保持在正常范围内,并随时修复上升的帧频。
被忽略的交互过程,特别是重试绘制元素,是渲染性能的杀手,正如你所见,我们可以用一些简单的代码解决掉这些问题。
看一看你的站点和应用,能不能做一些渲染绘制上面的优化
本文翻译自:
http://www.html5rocks.com/en/tutorials/speed/unnecessary-paints/
我英文水平有限,凑合着翻,全当自我学习欢迎交流学习
========================================================
转载处请注明:博客园(王二狗)willian12345@126.com
避免无用的渲染绘制(Avoiding Unnecessary Paints)的更多相关文章
- Cocos2d-x 学习笔记(25) 渲染 绘制 Render
[Cocos2d-x]学习笔记目录 本文链接:https://www.cnblogs.com/deepcho/p/cocos2dx-render.html 1. 从程序入口到渲染方法 一个Cocos2 ...
- CSS性能优化的8个技巧
本文作者:高峰,360奇舞团前端工程师,W3C性能工作组成员,同时参与WOT工作组的学习. 我们都知道对于网站来说,性能至关重要,CSS作为页面渲染和内容展现的重要环节,影响着用户对整个网站的第一体验 ...
- QML的渲染方式相较于之前的版本也有了重大的更新(CPU线程负责绘制,GPU线程负责渲染),还有好多经常评论 good
作者:qyvlik链接:http://www.zhihu.com/question/38867614/answer/78583440来源:知乎著作权归作者所有,转载请联系作者获得授权. 做UI啊.如果 ...
- 渲染、render与绘制
渲染是抽象到具体的过程: 抽象:图片信息的描述(比如一条线:两个端点的位置.线粗.颜色等特征): 具体:依据抽象信息得到的可视图片(绘制过程). 渲染是中文翻译的问题,有种添油加醋的感觉.直意就是交与 ...
- 源码分析篇 - Android绘制流程(二)measure、layout、draw流程
performTraversals方法会经过measure.layout和draw三个流程才能将一帧View需要显示的内容绘制到屏幕上,用最简化的方式看ViewRootImpl.performTrav ...
- Quartz2D复习(一)--- 基础知识 / 绘制线段圆弧 / 图片水印 / 截图
1.Quartz 2D是一个二维绘图引擎,同时支持ios和Mac系统: Quart2D的API是纯C语言的,API来自于Core Graphics框架: 2.Quartz 2D可以绘制图形(线段/三 ...
- 第1部分: 游戏引擎介绍, 渲染和构造3D世界
原文作者:Jake Simpson译者: 向海Email:GameWorldChina@myway.com ---------------------------------------------- ...
- iOS 开发:绘制像素到屏幕
转载:https://segmentfault.com/a/1190000000390012 译注:这篇文章虽然比较长,但是里面的内容还是很有价值的. 像素是如何绘制到屏幕上面的?把数据输出到屏幕的方 ...
- 小强学渲染之OpenGL渲染管线详析
什么是OpenGL? OpenGL是一套图形硬件的软件API接口库,它直接和GPU交互,将3D场景渲染绘制到2D屏幕上.总结说,OpenGL的功能是将程序中定义的各种2D或3D模型绘制到帧缓存中,或者 ...
随机推荐
- 【Nginx】优化配置
nginx优化 突破十万并发 一.一般来说nginx 配置文件中对优化比较有作用的为以下几项: 1. worker_processes 8; nginx 进程数,建议按照cpu 数目来指定,一般为它 ...
- AdminLTE 框架应用(一 )- 插件介绍
原AdminLTE中的插件让我大部分都移除了,第一是占地方,需要的时候再引入也不迟,第二就是有些插件已经过时了,有比较好的插件可以替代.附上项目插件截图 1.bootstrap-addTabs 提供多 ...
- POSt 提交参数 实体 和字符串
//1.后台接受是 字符串形式 [HttpPost] public int SendTaxiAudioByWX(string userid, string suid, string indexno, ...
- iOS 关于MVC和MVVM设计模式的那些事
一.概述 在 iOS 开发中,MVC(Model View Controller)是构建iOS App的标准模式,是苹果推荐的一个用来组织代码的权威范式.Apple甚至是这么说的.在MVC下,所有的对 ...
- 图解用HTML5的popstate如何玩转浏览器历史记录
一.popstate用来做什么的?简而言之就是HTML5新增的用来控制浏览器历史记录的api. 二.过去如何操纵浏览器历史记录? window.history对象,该对象上包含有length和stat ...
- 下载文件 通过a 标签 请求某个servlet进行下载的
下载文件 通过a 标签 请求某个servlet进行下载的
- wp如何代码重启手机
用过windows phone手机操作系统的人都知道,wp的系统设置界面很长一串,我们并不能快速进入想要的设置项,更受不了的是有些常用的设置项竟然在最下边.因为前段时间没事做,于是乎写了个wp的工具类 ...
- 深入理解JVM一性能监控工具
一.前言 工欲善其事必先利其器,性能优化和故障排查在我们大都数人眼里是件比较棘手的事情,一是需要具备一定的原理知识作为基础,二是需要掌握排查问题和解决问题的流程.方法.本文就将介绍利用性能监控工具,帮 ...
- DjangoORM使用mysql注意
注意事项1:需要在project下的setting里面做设置.让Django生成MySQL类型的数据库. 注意事项2:在Django内部,连MySQL的时候,需要添加下面2句代码: 4.******* ...
- BZOJ1089 [SCOI2003]严格n元树 【dp + 高精】
Description 如果一棵树的所有非叶节点都恰好有n个儿子,那么我们称它为严格n元树.如果该树中最底层的节点深度为d (根的深度为0),那么我们称它为一棵深度为d的严格n元树.例如,深度为2的严 ...