性能优化
性能优化\浏览器渲染原理
Get Started有这样几个问题,我们来思考下:1.我们平常浏览的网页是否是应用?2.在操作系统中的应用是如何运行的3.浏览器究竟是什么4.webkit和浏览器的关系5.浏览器是如何呈现网页的6.经典问题:从浏览器的地址栏输入一个网址直到网页内容呈现完毕,发生了哪些事情?
基本概念浏览器浏览器是用户访问互联网最重要的接口。本质上,浏览器是方便一般互联网用户通过界面解析和发送HTTP协议的软件。浏览器历史1.1991年,世界第一个浏览器WorldWideWeb(后改为Nexus),功能简单,不支持图片2.1993年,Mosaic浏览器出现,可以显示图片,为了区分浏览器是否能显示图片,出现了UserAgent3.1994年,Mozilla浏览器出现,也就是后来大名鼎鼎的网景浏览器Netscape,它的UserAgent为Mozilla/1.04.1995年,IE浏览器出现,为了抢夺市场,UserAgent为Mozilla/1.225.1998年,网景浏览器失利,成立Mozilla组织6.2003年,网景公司解散,Mozilla基金会成立,这个组织推进了后来的Firefox7.Mozilla开发了Geoko,变成了Firefox,它的UserAgentMozilla/5.08.群雄并起,众多公司的浏览器的UserAgent上都带有Mozilla9.chrome和safari出现,占有了很大份额查看用户代理1.打开chrome浏览器的控制台2.在控制台中输入 navigator.userAgent3.会发现类似字符串 Mozilla/5.0 (Macintosh; Intel Mac 0S × 10_12_1) ApplewebKit/537.36 (KHTML, like Gecko)Chrome/64.0.3282.186 Safari/537.36
用户代理的作用1.判断浏览器类型,采用兼容方案2.判断是否为移动端3.标识H5容器,方便调用H5容器特定接口4.要注意userAgent伪装成本很低,不要过于依赖
内核对于操作系统来说,内核是操作系统的核心,是第一层基于硬件的软件扩充,提供最核心最基础的服务。应用程序通过内核进行系统调用来使用计算机的硬件,内核代码简洁高效,并且基本没有bug,由于是最底层的服务,一点微小的错误也会造成整个系统的崩溃。好处当然也显而易见,基于一个稳定的内核,开发者可以构建适合不同场景的操作系统和应用软件。对于浏览器来说,同样存在浏览器内核,与操作系统内核相似,浏览器内核需要提供API给浏览器开发者使用,同时提供最核心的功能,如加载和渲染网页,调用操作系统所提供的服务。对于浏览器厂商来说,高效使用和开发浏览器内核是核心问题。对于web开发者来说,理解浏览器内核的基本机制,才能开发出高性能的web应用。
浏览器内核知识浏览器内核定义我们可以初步认为浏览器中负责将表示页面的字符转变成可视化的图像的模块就是浏览器内核。回到“从输入URL...”的问题我们将输入URL到远程内容返回之前的阶段略过,从'Response*开始:使用Node.js的TCP模块来获取,远程主机究竟给我们返回了什么:
远程主机响应HTTP协议请求报文格式:·起始行:[方法][空格][请求URL][空格][HTTP版本][换行符]·首部:[首部名称]】[:][可选空格]】[首部内容][换行符]·首部结束:[换行符]·实体响应报文格式:·起始行:[HTTP版本][空格][状态码][空格][原因短语][换行符]·首部:[首部名称][:][可选空格][首部内容][换行符]·首部结束:[换行符]·实体换行符:\r\n
1.不同的外联资源,webkit中有不同的资源加载器。当浏览器解析到URL地址时,调用特定的资源加载器。如果不是特殊资源,加载过程不会阻碍渲染过程2.一般来说css资源不会阻碍渲染过程,但javascipt资源在旧版本中的浏览器中,会阻碍渲染过程的进行。如果放置在头部,渲染过程会暂停,造成“白屏”。但现代浏览器的优化已经做的很好了,所以当渲染被阻塞时,浏览器会开启新的线程继续渲染。3.渲染之前需要加载资源,渲染之后在DOM或者CSS变化后,重新进行布局计算和重渲染操作4.功能基本相同,但所运行的操作系统不同,渲染机制有差异
Chromium架构基于webkit内核就可以构建浏览器应用,了解著名的chromium浏览器对我们的web开发也有很多启发。几个问题:1.除去webkit内核完成的功能,浏览器的工作有哪些?2.进程是什么?3.IPC是什么?4.线程是什么?5.线程同步是什么?现代浏览器的工作·资源管理:·多页面管理:也就是多个标签页的管理·插件和扩展:如flash,油猴,chrome扩展程序·账户和同步·安全机制·多系统支持进程和线程·进程:对CPU,主存,IO设备的抽象,操作系统对一个正在运行的程序的抽象。·线程:组成进程的执行单元·进程通信:进程间传输数据(交换信息)·线程同步:进程通讯的方式
加载资源加载机制资源加载器分为三类:1.特定资源加载器:针对每种资源类型的特定加载器,仅加载某一种资源。对应设计模式中的单例模式。2.缓存资源加载器:与常规的缓存逻辑相同,特定加载器先通过缓存资源加载器来查找是否有缓存资源,如果在资源缓存池中存在缓存资源,则取出以便使用;若不存在,发送请求给网络模块3.通用资源加载器:于加载资源大多属于网络请求,而网络请求的逻辑是可以被特定资源加载器所共享的,所以通用资源加载器只负责通过网络获得目标资源的数据,但不负责进一步解析。资源缓存1.Page Cache:页面缓存2.Memory Cache:内存缓存3.Disk Cache:磁盘缓存
TCP相关请参考之前的网络课程如何提高加载速度思考题1.合并请求:nginx模块,sprite雪碧图2.缓存:from cache(memory disk),localstorage,本地缓存策略,HTTP头(结美业务)3.tcp网络连接优化:tcp调优,HTTP/2,keep-alive4.硬件:加大带宽,使用cdn(对象存储)5.资源大小:gzip,webp,image压缩,cookie体积6.预加载:多个cdn域名,dns预取,异步读取js
HTML解释器解释过程资源的变换:1.字节流2.字符流3. Tokens4.节点5.DOM树流程:1.词法分析2.XSSAuditor3.语法分析4.生成DOM树词法分析通过HTMLTokenizer来进行词法分析词法分析的任务是对输入字节流进行逐字扫描,根据构词规则识别单词和符号,分词词法分析器的主要接口是nextfokenO 函数,调用者只需要将字符串传入,就会得到一个词语。注意,在这里并不涉及标签类型信息,这是之后语法分析的工作
现代浏览器格局IE:Trident,IE8的JavaScript引擎是Jscript,IE9开始用ChakraFirefox:Gecko,JavaScript引擎SpiderMonkeySafari:Webkit,渲染引擎及JavaScript解析引擎,均是从KDE的KHTML及KJS引擎衍生而来Chrome:Blink,JavaScript引擎V8Opera:早期是Presto,现在改为Blink与V8国内浏览器大部分都是基于chromium以及IE核的外壳型浏览器。
网页可视化过程网页可视化:就是根据描述或者定义构建数学模型,通过模型生成图像的过程。Parsing HTMLLayout of thePainting therender treeRender treeto constructthe DOM treeconstructionrender tree解析html以构建dom树->构建render树->布局render树(layout tree)->绘制render树
对于前端开发的启示:尽量减少HTTP请求次数减少DNS查找次数资源加载的速度不会影响DOM树的建立,因为他们都是异步的。但js的URL除外,如果可以,请尽可能地使用如果js可能改变DOM,导致RenderObject树重新绘制,请尽可能提前加载如果js不会与DOM打交道,可以采用延迟加载
HTML5新特性:离线(offline):application cache、localstorage, Iindexed DB存储(storage):application cache、localstorage、 Iindexed DB连接(connectivity):web sockets,server-sent事件文件访问(file access):file api、filesystem、fileWriter、 progressEvents
HTML5新特性:语义(semantics):Media、link relation等音频/视频(audio/video):HTML5 video、webaudio、webRTC、video track等3D/图形(3D/graphics):canvas 2D、3D css变换、WebGL、SVG等展示(presentation):CSS32D/3D变换、转换(transition)、webfonts等性能(performance):web worker、httpcaching其他(Nuts and bolts):触控、shadow DOM等
什么是DOM?DOM是Document Object Model(文档对象模型)的缩写。DOM是W3C的标准。DOM定义了访问HTML和XML文档的标准:DOM是中立于平台和语言的接口,它允许程序和脚本动态地访问和更新文档的内容、结构和样式。”W3CDOM标准被分为3个不同的部分:核心DOM-针对任何结构化文档的标准模型XMLDOM-针对XML文档的标准模型HTMLDOM-针对HTML文档的标准模型
JavaScript的执行:在HTML解释器工作的过程中,可能会有JavaScript代码,需要执行的时候,它会发生在字符串解释为词法之后,创建各个节点之前。这也就解释了为什么全局执行的JavaScript代码无法访问DOM树了,因为DOM还没有被创建。JavaScript的执行可能改变文档结构,故JavaScript代码会阻塞后面节点的创建并且阻塞后面资源的下载两个建议:。在script加async属性。将script放在body最后
前端监控
监控分类-1)性能监控-2)数据监控-3)异常监控Ⅰ
为什么需要前端监控-获取用户行为以及跟踪产品在用户端的使用情况,并以监控数据为基础,指明产品优化的方向
前端性能监控和错误监控-前端衡量性能的指标(时间监控)- Resource timing Performance API-
前端资源监控- performance.getEntriesByType('resource');-
ajax请求监控-拦截open 和 send 方法
monitor
//我们要监控页面的性能- 算时间差Performance Apiimport perf from './performance.js';perf.init((data)=>{//获取到页面性能相关的数据//图片可能没大小空的图片new Image().src ="/p.gif?"console.log(data);});//我们要监控页面静态资源的加载情况//ajax监控ajax发送情况//页面的错误捕获//监控用户的行为// 1.通过ajax2.通过image
配合echat 数据屏幕时时监控回报...分析...通知mq..mail/info/sj....
数据可视化 diy plugin frame 组装
防抖节流
性能优化优化高频率事件 onscroll oninput resize onkeyup keydown..,降低代码执行频率网页展示的过程
LayoutJavaScriptStyleCompositePaint
·JavaScript 动画/往页面里添加一些DOM元素Style确定每个DOM应该用什么样式规则Layout 布局,计算最终显示的位置和大小Paint 绘制dom,在不同的层上绘制Composite 渲染层合并用户scroll和resize行为会导致页面不断的重新渲染,如果在绑定的回调函数中大量操作dom也会出现页面卡顿
函数节流(Throttle)节流就是保证一段时间内,核心代码只执行一次打个比方:水滴积攒到一定重量才会下落
防抖(Debounce)防抖就是一段时间结束后,才能触发一次事件,如果一段时间未结束再次触发事件,就会重新开始计算时间打个比方:你在电梯中,门快要关了,突然有人准备上来。电梯并没有改变楼层,而是再次打开梯门。电梯延迟了改变楼层的功能,但是优化了资源。
以前代码: https://www.cnblogs.com/KooTeam/p/17764485.html
lodash https://github.com/lodash/lodash/blob/master/throttle.js
requestAnimationFrame编写动画循环的关键是要知道延迟时间多长合适,如果时间过长会导致动画不流畅,时间过短会造成过度的绘制。requestAnimationFrame采用系统时间间隔,保持最佳绘制效率!此方法是用来在页面重绘之前,通知浏览器调用一个指定的函数,被调用的频率是约每秒60次,在运行时浏览器会自动优化方法的调用。
节流+防抖 组合...
V8垃圾收集
1.JavaScript中的垃圾收集·程序的运行需要内存,只要程序要求,操作系统就必须提供内存·JavaScript使用自动内存管理,这被称为”垃圾回收机制”(garbage collector)·优点是可以简化开发、节省代码缺点是无法完整的掌握内存的分配与回收的具体过程
1.1 NodeJS中的内存管理·网页端的内存泄漏·对于持续运行的服务进程Node服务器端程序,必须及时释放不再用到的内存。否则,来越高,轻则影响系统性能,重则导致进程崩溃如果不再用到的内存没有及时释放,就叫做内存泄漏
1.2.1V8内存限制在64位操作系统可以使用1.4G内存·在32位操作系统中可以使用0.7G内存1.2.2V8内存管理JS对象都是通过V8进行分配管理内存的process.memoryUsage返回一个对象,包含了Node进程的内存占用信息
1.2.3为何限制内存大小·因为V8的垃圾收集工作原理导致的,1.4G内存完全一次垃圾收集需要1秒以上·这个暂停时间成为stop The World,在这个期间,应用的性能和响应能力都会下降
1.24如何打开内存限制·一旦初始化成功,生效后不能再修改·-max-new-space-size,最大new space大小,执行scavenge回收,默认16M,单位KB·-max-old-space-size,最大old space大小,执行MarkSweep回收,默认1G,单位MB
2.V8的垃圾回收机制·V8是基于分代的垃圾回收·不同代垃圾回收机制也不一样·按存活的时间分为新生代和老生代
·年龄小的是新生代,由From区域和To区域两个区域组成o
在64位系统里,新生代内存是32M,From区域和To区域各占用16M。
在32位系统里,新生代内存是16M,From区域和To区域各占用8M
年龄大的是老生代,默认情况下,。64为系统下老生代内存是1400M。32为系统下老生代内存是700M
2.2新生代垃圾回收
新生代区域一分为二,每个16M,一个使用,一个空闲开始垃圾回收的时候,会检查FROM区域中的存活对象,如果还活着,拷贝到TO空间,完成后释放空间
完成后FROM 和 To互换
新生代扫描的时候是一种广度优先的扫描策略
新生代的空间小,存活对象少
当一个对象经历过多次的垃圾回收依然存活的时候,生存周期比较长的对象会被移动到老生代,这个移动过程被成为晋升或者升级
。经过5次以上的回收还存在
。TO的空间使用占比超过25%,或者超大对象
新生代GC流程
scan 分配指针
stack 全局执行上下文 a bc
2.3老生代·mark-sweep(标记清除)mark-compact(标记整理)·老生代空间大,大部分都是活着的对象,GC耗时比较长在GC期间无法响应,STOP-THE-WORLDV8有一个优化方案,增量处理,把一个大暂停换成多个小暂停INCREMENT-GC
2.3.1 mark-sweep(标记清除)·标记活着的对象,随后清除在标记阶段没有标记的对象,只清理死亡对象·问题在于清除后会出现内存不连续的情况,这种内存碎片会对后续的内存分配产生影响·如果要分配一个大对象,碎片空间无法分配2.3.2 mark-compact(标记整理)·标记死亡后会对对象进行整理,活着的对象向左移动,移动完成后直接清理掉边界外的内存
2.3.3 incremental marking 增量标记·以上三种回收时都需要暂停程序执行,收集完成后才能恢复,STOP-THE-WORLD在新生代影响不大,但是老生代影响就非常大了·增量标记就是把标记改为了增量标记,把一口气的停顿拆分成了多个小步骤,做完一步程序运行一会儿,垃圾回收和应用程序运行交替进行,停顿时间可以减少到1/6左右包括垃圾回收的占用时间
eagle-sdk-core-code.zip.png