重定向 → 拉取缓存 →DNS 查询 → 建立 TCP 链接 → 发起请求 → 接收响应 → 处理 HTML 元素 → 元素加载完成
网络传输性能优化
浏览器缓存
缓存一般分为强缓存和协商缓存,主要区别是:使用本地缓存的时候,是否需要向服务器验证本地缓存是否依旧有效。
强缓存
主要通过 http 请求头中的 Cache-Control 和 Expire 两个字段控制
一般,我们会设置 Cache-Control 的值为“public, max-age=xxx”,表示在 xxx 秒内再次访问该资源,均使用本地的缓存,不再向服务器发起请求。
协商缓存
每次都向服务器验证一下缓存的有效性
前端缓存方案
- HTML:使用协商缓存
- CSS JS Image:使用强缓存,文件名带上 hash 值
浏览器默认的缓存是放在内存内的,但我们知道,内存里的缓存会因为进程的结束或者说浏览器的关闭而被清除,而存在硬盘里的缓存才能够被长期保留下去。很多时候,我们在 network 面板中各请求的 size 项里,会看到两种不同的状态:from memory cache 和 from disk cache,前者指缓存来自内存,后者指缓存来自硬盘。而控制缓存存放位置的,不是别人,就是我们在服务器上设置的 Etag 字段。在浏览器接收到服务器响应后,会检测响应头部(Header),如果有 Etag 字段,那么浏览器就会将本次缓存写入硬盘中。
资源打包压缩
网络性能优化措施归结为三大方面:减少请求数、减小请求资源体积、提升网络传输速率
1 | gulp grunt webpack parcel |
图片资源优化
- 不要在 HTML 里缩放图像
- 使用雪碧图(CSS Sprite)-
webpack-spritesmith
- 使用字体图标(iconfont)- icomoon
- 使用 WebP - 图片压缩体积大约只有 JPEG 的 2/3,并能节省大量的服务器带宽资源和数据空间
网络传输性能检测工具
Page Speed | PageSpeed Insights
使用 CDN
页面渲染性能优化
浏览器渲染过程(webkit)
- 《Webkit 技术内幕》
浏览器的解释器,是包括在渲染引擎内的,我们常说的 Chrome(现在使用的是 Blink 引擎)和 Safari 使用的 Webkit 引擎,Firefox 使用的 Gecko 引擎,指的就是渲染引擎。而在渲染引擎内,还包括着我们的 HTML 解释器(渲染时用于构造 DOM 树)、CSS 解释器(渲染时用于合成 CSS 规则)还有我们的 JS 解释器。不过后来,由于 JS 的使用越来越重要,工作越来越繁杂,所以 JS 解释器也渐渐独立出来,成为了单独的 JS 引擎,就像众所周知的 V8 引擎,我们经常接触的 Node.js 也是用的它。
DOM 渲染层与 GPU 硬件加速
- ① 浏览器会先获取 DOM 树并依据样式将其分割成多个独立的渲染层
- ②CPU 将每个层绘制进绘图中
- ③ 将位图作为纹理上传至 GPU(显卡)绘制
- ④GPU 将所有的渲染层缓存(如果下次上传的渲染层没有发生变化,GPU 就不需要对其进行重绘)并复合多个渲染层最终形成我们的图像
重排和重绘
不论是重排还是重绘,都会阻塞浏览器。要提高网页性能,就要降低重排和重绘的频率和成本,近可能少地触发重新渲染。
重排是由 CPU 处理的,而重绘是由 GPU 处理的,CPU 的处理效率远不及 GPU,并且重排一定会引发重绘,而重绘不一定会引发重排。所以在性能优化工作中,我们更应当着重减少重排的发生。
重排 reflow
渲染层内的元素布局发生修改,都会导致页面重写排列。
比如:窗口的尺寸发生变化、删除或添加 DOM 元素;修改了影响元素盒子大小的 css 属性(width height padding…)
重绘 repaint
绘制,所有对元素的视觉表现属性的修改,都会引起重绘。
优化策略
- CSS 属性读写分离
- 通过切换 class 或者 style.csstext 属性去批量操作元素样式
- DOM 元素离线更新
- 将没用的元素设为不可见:visibility: hidden,减少重绘的压力
- 压缩 DOM 的深度:少用 DOM 完成页面样式,多使用伪元素或者 box-shadow 取代。
- 图片在渲染前指定大小:因为 img 元素是内联元素,所以在加载图片后会改变宽高,严重的情况会导致整个页面重排,所以最好在渲染前就指定其大小,或者让其脱离文档流。
- 对页面中可能发生大量重排重绘的元素单独触发渲染层,使用 GPU 分担 CPU 压力。(慎重)
JS 阻塞性能
负载均衡
Node.js 处理 IO 密集型请求
node 的核心是事件驱动,通过 loop 去异步处理用户请求,相对于传统的后端服务,他们都是将用户的每个请求分配到异步队列中进行处理。
事件驱动的优势:在高并发 IO 时,不会造成堵塞。
Frond-End(Browser) <- nodejs="" -=""> Back-End(Java Server)->
pm2 实现 Node.js“多线程”
pm2。这是它的官网:pm2.keymetrics.io/
它是一款 node.js 进程管理器,具体的功能,就是能在你的计算机里的每一个内核都启动一个 node.js 服务。
也就是说如果你的电脑或者服务器是多核处理器(现在也少见单核了吧),它就能启动多个 node.js 服务,并且它能够自动控制负载均衡,会自动将用户的请求分发至压力小的服务进程上处理。
nginx 搭建反向代理
资料
- 前端缓存最佳实践
- 网站性能优化实战——从 12.67s 到 1.06s 的故事
- 你应该知道的前端——缓存
- 《大型网站性能监测、分析与优化》
- 【原】雅虎前端优化的 35 条军规