前端性能优化小笔记(CRP)

前端可优化的地方特别特别特别特别多,现在就从CRP方面简单说说。

输入URL到呈现页面过程:

image.png

CRP(Critical Rendering Path):关键路径渲染

关键流程一:浏览器渲染流程

1.构建DOM树、CSSOM树、渲染树

DOM树

转换,令牌,词法分析,DOM构建

image.png

2.CSSOM树

image.png

总结步骤:

1.处理 HTML 标记,构建 DOM 树

2.处理 CSS 标记,构建 CSSOM树

3.将DOM 树和 CSSOM 树融合成渲染树

4.根据生成的渲染树,计算它们在设备视口(viewport)内的确切位置和大小,这个计算的阶段就是回流=》布局(Lavout)或重排(reflow)

5.根据渲染树以及回流得到的几何信息,得到节点的绝对像素=》 绘制( painting)或棚格化 (rasterizing )

注意:

真正渲染到页面的时候,一定发生在DOM树和CSSOM树都完成后, HTTP和CSS都是阻碍页面渲染的东西。

image.png

优化方案

1.标签语义化

2.避免深层次嵌套(CSS选择器渲染是从右到左)

3.尽早尽快地把CSS下载到客端(充分利用HTTP多请求井发机制)

放到顶部:

style(html拿回来时候已经请求,比link更好一些)

link(发送HTTP请求,异步)

@import(减少import阻塞渲染的请求,同步)

4.避免阻塞的JS加载 放到底部

绿色:页面正在渲染
蓝色:遇到script请求拉取数据
红色:进行渲染

image.png async声明的JS不要设置依赖

5.减少DOM的回流和重绘

页面渲染一次一定有回流和重绘,回流:元素大小或者位置发生变化。 重绘:样式的改变,例如背景颜色。

回流触发重绘,重绘不一定回流

避免回流:

1.放弃传统操作dom的时代,基于vue/react开始数据影响视图模式。

2.分离读写操作(现代浏览器都有渲染队列的机制)

3.样式集中改变

4.缓存布局信息

5.元素批量修改

6.动画效果应用到position属性为absolute或fixed的元素上(脱离文档流)

7.CSS3硬件加速(GPU加速)

8.牺牲平滑度换取速度

9.避免table布局和使用css的javascript表达式

关键流程二:DNS解析

DNS解析先在本地解析再去其他地方解析

image.png

image.png

1.DNS方面的优化(每一次DNS解析时间预计在20~120毫秒)

减少DNS请求次数(很难做到,现在网站一个网站从多个服务器返回资源)

DNS预获取(DNS Prefetch)

<link rel="dns-prefetch" href="//d.jd.com"/>
复制代码

2.减少HTTP请求次数和请求资源大小

资源合并压缩、字体图标(不用矢量图,不独立发请求)、Base64、GZIP(一般文件压缩60%多)、图片懒加载、数据延迟分批加载、CDN资源(地域式分布)

3.应用缓存(第一次加载过后,重新加载,截止读取缓存)

缓存位置

常用的有:Memory Cache:内存缓存,Disk Cache:硬盘缓存

  1. 打开网页,地址栏输入地址:查找 disk cache 中是否有匹配,如有则使用,如没有则发送网络请求。
  2. 首通刷新(F5):因为 TAB 并没有关闭,因此memory cache 是可用的,会被优先使用(如果匹配的话),其次才是 disk cache.
  3. 强制刷新(Ctrl + F5):浏览品不使用缓存,因此发送的请求头部均带有 Cache-control: no-cache(为了兼容,还带了 Pragma: no-cache),服务器直接返回 200 和最新内容。

强缓存和协商缓存:

强缓存

image.png

强缓存离不开两个响应头 ExpiresCache-Control

Expires:Expires是http1.0提出的⼀个表示资源过期时间的header,它描述的是⼀个绝对时间,由服务器返回, Expires 受限于本地时间,如果修改了本地时间,可能会造成缓存失效

Expires: Wed, 11 May 2018 07:20:00 GMT
复制代码

Cache-Control: Cache-Control 出现于 HTTP / 1.1,优先级⾼于 Expires ,表示的是相对时间

Cache-Control: max-age=315360000
复制代码

⽬前主流的做法使⽤ Cache-Control 控制缓存, max-age 控制过期时间,还有以下指令

Cache-Control: public可以被所有⽤户缓存,包括终端和CDN等中间代理服务器

Cache-Control: private只能被终端浏览器缓存,不允许中继缓存服务器进⾏缓存

Cache-Control: no-cache,先缓存本地,但是在命中缓存之后必须与服务器验证缓存的新鲜度才能使⽤

Cache-Control: no-store,不会产⽣任何缓存

协商缓存

当第⼀次请求时服务器返回的响应头中没有Cache-Control和Expires或者Cache-Control和Expires过期抑或它的属性设 置为no-cache时,那么浏览器第⼆次请求时就会与服务器进⾏协商。

如果缓存和服务端资源的最新版本是⼀致的,那么就⽆需再次下载该资源,服务端直接返回304 Not Modified 状态码, 如果服务器发现浏览器中的缓存已经是旧版本了,那么服务器就会把最新资源的完整内容返回给浏览器,状态码就是200 Ok。

协商缓存生效,返回304

image.png

image.png

Last-Modi fied和If-Modified-Since

  1. 第一次访问资源,服务器返回资源的同时,响应头中设置 Last-Modified(服务器上的最后修改时间),浏览器接收后,緩存文件和响应头;
  2. 下一次请求这个资源,浏览器检测到有 Last-Modified,于是添加1f-Modified-Since请求头,值就是Last-Modified中的值:
  3. 服务品再次收到这个资源清求,会根据 if-Modifed-Since 中的值与服务器中这个资源的最后修改时间对比,如果没有变化,返回304和空的响应体,直接从缓存读取,如果
  4. Modifed-Since的时间小于服务品中这个资源的最后修改时间,说明文件有更新,于是返回新的资源文件和200;
  5. 但是Last-Modified 只能以秒计时,如果在不可感知的时间内修改完成文件,那么服务端会认为资源还是命中了,不会返回正磅的姿源;

协议缓存失败,返回200

ETag和If-None-Match

  1. Etag是服务器响应请求时,返回兰前资源文件的一个唯一标识(由服务器生成),只要资源有变化,Etag就会重新生成;
  2. 下一次加载资源向服务器发送请求时,会将上一次返回的Etag值放到请求头If-None-Match里,服务器只需要比较客户端传来的if-None-Match跟白己服务器上该资源的ETag是否一致,就能很好地判断资源相对客户端而言是否被修改过了。
  3. 如果服务器发现ETag匹配不上,那么直接以常规GET 200回包形式将新的资源( 当然也包括了新的ETag) 发给客户端:如果ETag是一致的,则直接返回304知会客户端直接使用本地缓存即可。
  4. 整体缓存流程图:

image.png

强缓存协商缓存都是针对文件的,针对数据可以用LocalStorage本地储存

另外的关键节点还有还有代码运行,代码编译,安全优化等

好了这就是个人的性能优化小笔记o(╥﹏╥)o,引用了一些博客还有珠峰培训的图片,然后写的可能不是很完善很好,只是给自己复习的一个小笔记

おすすめ

転載: juejin.im/post/7077069465145802788