网站性能优化—浏览器渲染

news/2024/5/2 8:58:42/文章来源:https://blog.csdn.net/weixin_34129145/article/details/89107333

上篇文章《网站性能优化——CRP》已经介绍过网站性能优化中的关键渲染路径部分,相当于从一个“宏观”的角度去优化性能,当然,这个角度也是最重要的优化。本篇就从一个“微观”的层面去优化——浏览器渲染。

在视频领域,电影、电视、数字视频等可视为随时间连续变换的许多张画面,而帧则指这些画面当中的每一张。——维基百科

网页上来说,其实就是指浏览器渲染出的页面。目前大多数设备的屏幕刷新频率为60次/秒(60fps),每一帧所消耗的时间约为16ms(1000 ms / 60 = 16.66ms),但实际上,浏览器还有一些整理工作要做,因此开发者所做的所有工作需要在10ms内完成。

如果不能完成,帧率将会下降,网页会在屏幕上抖动,也就是通常所说的卡顿,这会对用户体验产生严重的负面影响。所以如果一个页面中有动画效果或者用户正在滚动页面,那么浏览器渲染动画或页面的速率也要尽可能地与设备屏幕的刷新频率保持一致,以保证良好的用户体验。

像素管道

提高帧率,其实就是优化浏览器渲染页面的过程。当你在工作时,需要了解并注意五个主要的区域,这些区域是你能在最大程度上去控制的地方,当然,也就是优化性能、提高帧率的地方。
clipboard.png

  • JavaScript:一般情况下,我们会使用JS去处理一些导致视觉变化的工作,比如动画或者增加DOM元素等。当然,除了JS,还有其他一些方法,比如:CSS Animations、Transitions、 Web Animation API

  • Style calculations:这个过程是根据匹配选择器(.nav > .nav-item)计算出哪些CSS规则应用在哪些元素上面的过程

  • Layout:浏览器知道对一个元素应用哪些规则之后,就可以开始计算这个元素占据的空间大小及其在屏幕上的位置

  • Paint:绘制是填充像素的过程。它涉及绘出文本、颜色、图像、边框和阴影,基本上包含了元素的每个可视部分。绘制一般是在多个上完成的

  • Compositing(合成):由于页面的不同部分可能被绘制到多个上,因此它们需要按照正确的顺序绘制到屏幕上以正确渲染页面

像素管道的每个部分都有可能产生卡顿,因此,准确了解你的代码会触发管道的哪些部分十分重要。
帧不一定都会经过管道每个部分的处理。实际上,在改变视觉呈现时,针对指定帧,管道的运行通常有三种方式:

  • JS / CSS > Style > Layout > Paint > Composite
    clipboard.png当改变了某个元素的几何属性(如width、height,或者表示位置的left、top等)——即修改了该元素的“布局(layout)”属性,那么浏览器将会检查所有其他元素,然后对页面进行“重排(reflow)”。任何受到影响的区域都需要重新绘制,然后进行合成。

  • JS / CSS > Style > Paint > Composite
    clipboard.png当改变了只与绘制相关的属性(如背景图片、文字颜色或阴影等),即不会影响页面的布局,则浏览器会跳过布局阶段,但仍需要执行绘制、合成。

  • JS / CSS > Style > Composite
    clipboard.png当改变了一个既不需要“重排”也不需要“重绘”的属性(如transform),则浏览器将跳过布局、绘制阶段,直接执行合成。

浏览器渲染优化

JavaScript

使用 requestAnimationFrame

requestAnimationFrame应该作为开发者在创建动画时的必备工具,它会确保JS尽早在每一帧的开始执行。

之前我们可能看到过很多用setTimeoutsetInterval创建的动画,比如老版本的jQuery。但是使用这两个函数创建的动画效果可能不够流畅,JS引擎在安排这两个函数时根本不会关注渲染通道,参考《Html5 Canvas核心技术》中的论述:

1.即使向其传递毫秒为单位的参数,它们也不能达到ms的准确性。这是因为javascript是单线程的,可能会发生阻塞。
2.没有对调用动画的循环机制进行优化。
3.没有考虑到绘制动画的最佳时机,只是一味地以某个大致的事件间隔来调用循环。

使用 Web Worker

前面讨论过刷新一帧消耗的最佳时间大概在10ms左右,但是一帧里面通常又包括JS处理、样式处理、布局、渲染等等,所以JS执行的时间最好控制在3~4ms。JS在浏览器的主线程上运行,如果运行时间过长,就会阻塞样式计算、布局等工作,这样可能导致帧丢失。

许多情况下,可以将纯计算性的工作移到Web Worker,比如,不需要访问DOM的时候。数据操作或者遍历(如排序或搜索)往往很适合这种模型,加载和模型生成也是如此。

使用Timeline分析JS

当觉察到页面有卡顿的时候但又不知道是哪部分的JS造成的,这时可以打开Timeline录制时间轴,查看、分析是哪个地方的JS造成了页面卡顿,然后做针对性的JS优化。有关Timeline的使用,请参考《Chrome DevTools - Timeline》。

样式

计算样式(computing styles)的第一部分是创建一组匹配选择器,以便浏览器计算出给指定元素应用哪些类、伪选择器和 ID。第二部分涉及从匹配选择器中获取所有样式规则,并计算出此元素的最终样式。
在当前的Chrome渲染引擎中,用于计算某元素计算样式的时间中大约有 50% 用来匹配选择器,而另一半时间则用于从匹配的规则中构建 RenderStyle。

降低选择器的复杂度:能写出高效率选择器的前端开发者本来就不多,又加上当前Less和Sass的普及,一些前端开发者对Less、Sass的滥用,导致编译后的css选择器有时候甚至能达到六七层嵌套,这大大增加了浏览器计算样式所消耗的总时间。
最理想的状态是每个元素都有一个唯一的id,这样选择器最简单也是最高效的,可是我们知道这是不现实的。但是,遵循一些指导原则依然能让我们写出较为高效的CSS选择器:Writing efficient CSS selectors

布局

尽可能避免布局操作

在修改CSS样式时,心里要清楚哪些属性会触发布局操作,能避免则避免。考虑到实际的开发情况,几乎避免不了啊~~如果无法避免,则要使用Timeline查看一下布局要花多长时间,并确定布局是否会造成性能瓶颈。如果布局消耗时间过多,则要从布局前面的JS和样式阶段查找一下原因,并做进一步的优化。
想知道哪些CSS属性会触发布局、绘制或合成?请查看CSS触发器

优先使用flexbox布局

如果用定位、浮动和flexbox都能达到相同的布局效果,在浏览器兼容的情况下,优先使用flexbox布局,不仅因为其功能强大,更是因为其性能在布局上更胜一筹。

避免强制同步布局

将一帧绘制到屏幕上会经历以下顺序:
clipboard.png
首先执行JS,然后计算样式,然后布局。但是,某些JS有可能强制浏览器提前执行布局操作,变成 JS > Layout > Styles > Layout > Paint > Composite,这被称为强制同步布局(Forced Synchronous Layout)

用一个demo来说明一下FSL:

clipboard.png

点击Trigger按钮,改变上面三个按钮的宽度,index.js内容如下:

1. var element1 = document.querySelector('.btn1');
2. var element2 = document.querySelector('.btn2');
3. var element3 = document.querySelector('.btn3');
4. var triggerBtn = document.querySelector('.trigger');
5. triggerBtn.addEventListener('click', function trigger(){
6.   // Read
7.   var h1 = element1.offsetWidth;
8.   // Write (invalidates layout)
9.   element1.style.width = (h1 * 2) + 'px';
10.
11.   // Read (triggers layout)
12.   var h2 = element2.offsetWidth;
13.   // Write (invalidates layout)
14.   element2.style.width = (h2 * 2) + 'px';
15.
16.   // Read (triggers layout)
17.   var h3 = element3.offsetWidth;
18.   // Write (invalidates layout)
19.   element3.style.width = (h3 * 2) + 'px';
20. });

clipboard.png

可以看到,读取offsetWidth属性会导致layout。但是,要注意的是,在 JS 运行时,来自上一帧的所有旧布局相关的值是已知的,并且可供查询。所以,在Timeline中看到第7行代码只是触发了Recalculate Style事件,并未触发Layout事件。当JS执行到第12行代码的时候,为了获取element2.offsetWidth,浏览器必须先执行计算样式(因为第9行代码改变了element1的width属性),然后执行布局,才能返回正确的宽度,第17行代码也是如此。这是不必要的,而且可能导致很大的时间开销。JS执行到第19行时,触发最终的Recalculate Style事件和Layout事件,渲染出新的一帧。

避免强制同步布局:先读取布局属性,然后批量处理样式更改。

...
6. // Read
7. var h1 = element1.clientHeight;
8. var h2 = element2.clientHeight;
9. var h3 = element3.clientHeight;
10.
11. // Write (invalidates layout)
12. element1.style.height = (h1 * 2) + 'px';
13. element2.style.height = (h2 * 2) + 'px';
14. element3.style.height = (h3 * 2) + 'px';// Document reflows at end of frame

图片描述

可以看到,先读取布局属性,然后批量处理样式更改,只会导致最终的Layout,避免了FSL。

绘制与合成

当在页面上进行交互时,想知道哪些区域被重新绘制了?打开DevTools的副面板,切换到Rendering,勾选“Paint Flashing”:
clipboard.png

交互发生后,重新绘制的区域会闪烁绿色:
clipboard.png

绘制并非总是绘制到内存中的单个图像上。实际上,如果必要,浏览器可以绘制到多个图像(层)上。这种方法的优点是,定期重绘的元素,或者通过动画变形在屏幕上移动的元素,可以在不影响其他元素的情况下进行处理。这和图像处理软件Photoshop、Sketch等层的概念是类似的,各个层可以在彼此的上面处理并合成,以创建最终图像。

创建新层的最佳方式是使用will-change CSS 属性,当其属性值为transform时,将会创建一个新的合成器层(compositor layer)

.moving-element {will-change: transform;
}

对于不支持will-change属性的浏览器,可以使用以下css做兼容处理:

.moving-element {transform: translateZ(0);
}

需要注意的是:不要创建太多层,因为每层都需要内存和管理开销。如果你已将一个元素提升到一个新层,最好使用 DevTools 确认一下这样做能带来性能优势。请勿在不分析的情况下提升元素

最后说一下如何使用Timeline了解网页中的层。
图片描述

勾选Paint,然后录制Timeline,然后点击单个帧,这时详情选项里面多了个“layer”选项卡,切换到此选项卡。展开左侧#document,即可看到页面里面有多少个层(layer),单击每个层时,右侧还会显示这个层被创建的原因。
如果在性能关键操作期间(比如滚动或动画)花了很多时间在合成上(应当力争在4-5ms左右),则可以使用此处的信息来查看页面有多少层、创建层的原因,进一步去管理页面中的层数。


References

  • https://developers.google.com...

  • https://cn.udacity.com/course...

  • https://gist.github.com/pauli...

  • http://wilsonpage.co.uk/preve...

  • http://stackoverflow.com/ques...

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.luyixian.cn/news_show_730432.aspx

如若内容造成侵权/违法违规/事实不符,请联系dt猫网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

实验室网站试运营期间的信息管理

注册 试运营期间使用二级域名http://hhuec.site9.mc-test.com/ 备案完成后使用域名hhuec.com 首先在网站主页注册用户名,实验室成员使用实名制注册,注册完成后可以通过上面的在线联系直接联系由管理员分配后台操作权限,管理员分配后方可使用后…

j2ee 简单网站搭建:(二)添加和配置 spring + spring-mvc 的 mvc 开发环境

为什么80%的码农都做不了架构师?>>> 《j2ee 简单网站搭建:(一) windows 操作系统下使用 eclipse 建立 maven web 项目》《j2ee 简单网站搭建:(二)添加和配置 spring spring-mvc 的…

美国防部公开邀请黑客测试网站安全性

本文讲的是 : 美国防部公开邀请黑客测试网站安全性 , 北京时间3月3日凌晨消息,美国国防部周三称,该部将于下个月邀请外部黑客对其某些公共网站的安全性进行审查测试,这是该部一项试点计划的部分内容,同时也代表着有史以来美国联…

JSON.parseObject(String str)与JSONObject.parseObject(String str)的区别

一、fastjson fastjson 是一个性能很好的 Java 语言实现的 JSON 解析器和生成器,来自阿里巴巴的工程师开发。其主要特点是: ① 快速:fastjson采用独创的算法,将parse的速度提升到极致,超过所有基于Java的json库&#x…

ytkah网站建设解决方案 大中小微企业营销利器

为大中小微企业提供网站设计制作优化服务,PC移动微网站三合一,抢占市场先机。读万卷书不如走万里路,走万里路不如阅人无数。说再多空洞无物不如上案例几簇 优秀案例展示,上市公司人人网旗下游戏《天书奇谈》门户网站,年收入高达5亿&#xff1…

php后端框架 模板,PHP的Laravel框架中使用AdminLTE模板来编写网站后台界面

AdminLTE 是一个基于Bootstrap 3.x的免费高级管理控制面板主题,完全响应式管理,适合从小型移动设备到大型台式机很多的屏幕分辨率。AdminLTE的特点:充分响应可分类的仪表盘18插件和3自定义插件重量轻和快速与大多数主流浏览器兼容完全支持Gly…

独家揭秘影响SEO排名的17项核心因素

大道至简知易行难是SEO行业中容易遇到的一个砍,很多事情看似简单,但是真正下手操作的时候变得思路模糊、操作不当等,很大一部分原因是由于对于SEO核心本质的理解有偏差所造成的。在整个搜索引擎结果排序当中,影响SEO排名的因素众多…

网站相对 绝对路径 html,解惑页面中的相对路径和绝对路径

写在前面:最近做一个前后端结合的项目时,突然发现自己被页面中使用的相对路径搞糊涂了(PS:其实已经不是第一次了。。。之前有一次屡清楚了,但发现又忘记了,瞧我者好记性O(∩_∩)O)。所以我要趁这次好好记一下&#xff…

服务器不稳定网站收录下降,服务器的不稳定,会对搜索引擎优化产生什么影响?...

原标题:服务器的不稳定,会对搜索引擎优化产生什么影响?许多人在选择租赁服务器时,往往忽略了一个特别重要的问题,那就是稳定性!服务器租赁是否稳定对于能够做出直接决策的客户以及百度搜索引擎是否喜欢浏览…

SEO实战干货:网页建库与未建库的标准规则!

很多SEO人稍微有点基础就都知道降权这个词语,但是在搜索引擎规范标准指南里面并未提到站点降权一说,严格来讲用建库这个说法更加准确。 首先我们不妨来回顾一下搜索结果排序的过程,从蜘蛛的爬行到蜘蛛的抓取再到网页收录(这里面包括了页面纯收…

《淘宝店铺 大数据营销+SEO+爆款打造 一册通》一一2.6 营销推广助力提升销量...

本节书摘来自异步社区出版社《淘宝店铺 大数据营销SEO爆款打造 一册通》一书中的第2章,第2.6节,作者:葛存山 , 耿寿礼,更多章节内容可以访问云栖社区“异步社区”公众号查看。 2.6 营销推广助力提升销量 营销推广包括营销工具、营…

外链应该这样发,网站排名速度提升十陪

说起发外链工作几乎是每个SEO人员都发过,但是比较蛋疼的是外链应该如何发,怎么发才有效,又该怎样发不会导致网站降权,不发又不行因为外链建设是网站外部优化的一个非常重要的环节,外链发布的质量直接影响着咱们SEO工作…

计算机视觉(图像处理)相关的比较全面的好网站

计算机视觉在生活和工业应用等领域越来越广泛。在科学研究中,常常需要借鉴和参考巨人的IDEA和资料,这里总结了一些常用的网站供大家参考,世界很大,这只是小部分。如果你有什么补充,发email给我,补充。 htt…

Nginx主配置参数详解,Nginx配置网站

阅读目录 1.Niginx主配置文件参数详解2.Nginx.conf配置文件详细说明(附备注)3.Nginx代理网站回到顶部1.Niginx主配置文件参数详解 a.上面博客说了在Linux中安装nginx。博文地址为:http://www.cnblogs.com/hanyinglong/p/5102141.html b.当Nginx安装完毕后&#xff0…

让你不再恋家的9款小众时尚的酒店网站设计

2019独角兽企业重金招聘Python工程师标准>>> 一场说走就走的旅行少不了一家精挑细选的酒店。出门在外,没有一个舒适的住处,恐怕旅行的记忆也并不是那么美好。大牌酒店住不起,小众酒店性价比高,但哪家最合适&#xff1f…

我的网站搭建 (第十五天) 用户注册与登录

2019独角兽企业重金招聘Python工程师标准>>> 这几天正好学了Flask的用户注册登录功能设计,发现与Django的使用特别类似,所以学习Flask的同时也加强了我对Django表单的印象。正好网站搭建也差不多更新到用户操作部分了,就索性把Dja…

Html代码seo优化最佳布局实例讲解

2019独角兽企业重金招聘Python工程师标准>>> Html代码seo优化最佳布局实例讲解 搜索引擎对html代码是非常优化的&#xff0c;所以html的优化是做好推广的第一步。一个符合seo规则的代码大体如下界面所示。 1、<!–木庄网络博客–> 这个东西是些页面注释的&am…

大型互联网站解决海量数据的常见策略

文章来源&#xff1a;http://www.javabloger.com/article/big-data-architecture.html 大型互联网站的数据存储与传统存储环境相比不仅是一个服务器、一个数据库那么简单&#xff0c;而是由网络设备、存储设备、应用服务器、公用访问接口、应用程序 等多个部分组成的复杂系统。…

大型网站架构系列:电商网站架构案例(转)

转载地址&#xff1a; http://www.aboutyun.com/thread-17407-1-1.html问题导读&#xff1a;1、电商网站考虑的客户需求有哪些&#xff1f;2、网站架构如何演变的&#xff1f;3、电商架构优化需考虑哪些内容&#xff1f;大型网站架构是一个系列文档&#xff0c;欢迎大家关注。本…

thinkphp5项目--企业单车网站(一)

thinkphp5项目--企业单车网站&#xff08;一&#xff09; 项目地址 fry404006308/BicycleEnterpriseWebsite: Bicycle Enterprise Websitehttps://github.com/fry404006308/BicycleEnterpriseWebsite 一、命名空间 二、 模板页面后缀配置 三、 输出替换 使用 四、 视图实例化 1…