前端架构与性能优化那些事
性能优化的学徒工
- html数量控制 html css hint 善用css
- 压缩、合并、文件MD5戳更好的缓存
- (引用多个cdn http1.1有用) 设置为gzip cookie
- http2
- 离线缓存 localstorage
- a.js -> a.xxx5.js
- active.js 激活a.js 1.eval 2. add塞进
- 去localstorage 中取得的时候 需要判断版本号 是否一致
1. 维护一个全局版本 通常webpack直接生成 obj = { a.js :'a.xx5.js' } 2. 建立一个active.js 去激活js 3. 例如请求 a.js 4. active("a.js") 5. localStorage["a.js"] -> script src="a.js" 没有存过 ajax =>datatype:'text' script src="a.js" localStorage["a.js"] = "a.xx5.js" -> localStorage["a.xx5.js"] = "js内容" -> script src="a.js"== obj["a.js"] 有存过 -> eval(localStorage["a.xx5.js"]) -> 请求并重新缓存 6. 总共5M 超过 2.5M出现卡顿 复制代码
- 广告位置 通过web SQL存储
- localForage basket.js 缓存兼容
- 缓存的优先级 cache-control expires etag last-modified
last-modified / if-modified-since 这是一一组请求/相应头 -> 响应头: last-modified: Wed, 16 May 2018 02:57:16 GMT -> 请求头: if-modified-since: Wed, 16 May 2018 05:55:38 GMT 服务器器端返回资源时,如果头部带上了了 last-modified, 那么 资源下次请求时就会把值加入入到请求头 if-modified-since 中, 服务器可以对比这个值,确定资源是否发生变化,如果没有发生变化,则返回304 etag / if-none-match 这也是一一组请求/相应头 -> 响应头: etag: "D5FC8B85A045FF720547BC36FC872550" -> 请求头: if-none-match:"D5FC8B85A045FF720547BC36FC872550" 原理理类似,服务器器端返回资源时,如果头部带上了了 etag, 那么资源下次请求时就会把值加入入到请求头 if-none-match 中, 服务器器可以对比这个值,确定资源是否发生变化,如果没有发生变化,则返回 304 expires -> expires: Thu, 16 May 2019 03:05:59 GMT 在 http 头中设置一个过期时间,在这个过期时间之前,浏览器的请求都不会发出, 而是自动从缓存中读取文件,除非缓存被清空,或者强制刷新。缺陷在于,服务器时间和 用户端时间可能存在不一致,所以HTTP1.1加入了cache-control头来改进这个问题 cache-control 设置过期的时间长度(秒),在这个时间范围内,浏览器请求都会直接读取缓存。当expires和 cache-control都存在时,cache-control的优先级更高 复制代码
- http2 多路复用
浏览器器请求//xx.cn/a.js -->解析域名 —>HTTP连接 —>服务器器处理文件 —>返回数据 ->浏览器器解析、渲染文文件。 Keep-Alive解决的核心心问题就在此,一定时间内,同一域名多次请求数据, 只建立一次HTTP请求,其他请可复用每一次建立的连接通道,以达到提高请求效率的问题。 一定时间是可以配置的,HTTP1.1还是存在效率问题 第一个:串串行行行的文文件传输。 第二个:连接数过多。HTTP/2对同一域名下所有请求都是基于流,也就是说同一域名不管访问多少文件,也只建立一路连接。 同样Apache的最大大连接数为300,因为有了这个新特性,最大的并发就可以提升到300,比原来提升了6倍! 复制代码
渲染中的性能优化
- Rendering
- Paint flashing 重绘
- FPS meter 一秒绘制多少帧
- Performance
- loading 加载时间
- scripting 脚本执行时间
- rendering 重排时间
- painting 重绘时间
- system 系统执行时间
- idle 空闲时间
- event log
复制代码
重绘和重排 网页整体渲染过程
- 获取dom 分割层
- 根据每层节点结算样式结果 Recalculate Style
- 为每个节点生成图形和位置 Layout
- 将每个节点绘制填充到当前帧的位图中
- 将图层上传到gpu(显卡) gpu bimap 专门处理图像
- 显卡根据符合要求的多个图层合并生成图像 Composite Layers
总结 渲染阶段 : Layout -> Paint -> Composite Layers
什么情况下会分层
根元素、position、transfrom、半透明、滤镜、canvas、video、overflow
什么时候gpu直接参与?: css3d,video,webglk,transform,滤镜 硬件加速
重排一定会引起重绘 重绘不一定引起重排
重排引起的情况
- 添加或者删除元素
- 元素位置的变化
- 元素变化尺寸
- 页面的初始化
- 读取一些属性会引起重排 offset、scrolltop、client、width
- requestAnimationFrame ==> 下一帧
页面加载的性能优化
- FP: 仅有一个div根节点
- FCP: 包含页面的基本框架,但没有数据
- FMP: 包括页面所有元素以及数据
- window.performance.getEntriesByType("paint")// 获取重绘的时间
- const observer new performanceObserver(); observer.observe({entryTypes:['paint']})
- const observer new performanceObserver(); observer.observe({entryTypes:['longtask']})
- requestAnimationFrame() //每一帧都要渲染
- requestIdleCallback() //
nodeJS性能优化
未完待续......