讨论一下性能优化的方案

527 阅读4分钟

我们进行性能优化,一般就是从网络层渲染层进行优化。

网络层

减少网路请求

主要几种在图片优化上。

base64

将小图编译为base64字符串,来减少请求次数。 但是在经过base64编码之后,体积一般都会变为原来的3 / 4,也就是说大图最好不要使用base64编码,会增加打包产物的体积。

雪碧图

雪碧图是将多个小图,合并为一个大图的方案,在使用的时候通过background的postion属性去控制,展示哪张图。

image.png

通过 postion 属性指定展示那张图。

比如: image.png

减少传输时间

gizp / br压缩

一般可以减少70%左右的体积。 这两压缩,现在的处理方式一般是,由前端压缩完成之后,给到服务器,就不用服务器在压缩了。

压缩的原理:

压缩的原理就是将文件中出现过的重复字符串替换为更短的字符,解压的时候在替换回来。

图片压缩

image.png 从上图看来,webp是一种很优秀的方案,并且无论是有损还是无损,压缩之后体积都要比png,和jpg更小。

拿BOSS直聘这个网站来看

image.png webp的图片很多,但是能否梭哈使用使用webp的图片呢。 看一下兼容性 image.png 依旧是存在兼容性问题。

看一下BOSS这个网站是如何处理这个问题的

image.png 发现webp的前缀还有jpg,在CDN或者服务器上就可以通过浏览器的accpet-type字段来判断到时候要返回哪种图片。 如果不兼容webp的话就会将.webp后缀去掉。

分包

如果打包压缩后,单个文件的体积仍然很大,可以通过分包来解决这个问题,比如将第三方库的代码单独打包。

预加载 dns-prefech prefech

image.png 例如:

  <!-- DNS 预解析:提前解析外部字体的域名 -->
  <link rel="dns-prefetch" href="//fonts.googleapis.com">

  <!-- Prefetch:浏览器空闲时预加载 about 页的脚本 -->
  <link rel="prefetch" href="/about.js" as="script">
CDN

假设公司购买了一个深圳的服务器,但是用户在北京,没有CND那么网络就需要从北京到深圳去请求资源,加上了CDN之后,首先去CDN服务器去查询,因为CDN名字叫做内容分发网络,所以CDN的节点是很多的,但是DNS解析的时候会获取相对最近的CDN服务器,然后去这个CDN服务器上去获取资源,假设我们购买的CDN服务,在北京有对应的服务器,那么网络请求就是直接从北京 --> 北京,这个就是CDN的作用。

推荐视频 www.douyin.com/jingxuan/se…

CDN的查询过程

对于普通域名来说

域名 --> (DNS解析)直接得到域名的ip

CND --> (DNS解析)得到服务商CDN专用的DNS调度系统的域名 --> (DNS解析)得到ip

浏览器缓存

建议直接看这篇文章,个人感觉这篇文章讲的很好。

然后纠正大家一个误区就是浏览器缓存不是http缓存。

大家以后在回答浏览器缓存的时候不要直接说http缓存了。 juejin.cn/book/684473…

另外在浏览器的四大缓存中

  • memory cache
  • service worker Cache
  • http cache
  • push cache 对push cache 缓存来说,是建立在http2中的服务器推实现的缓存,由服务器预先推送资源,客户端缓存下来的就是push cache,Push Cache 和 Server Push 本身存在一些 性能不确定性,导致主流浏览器和 CDN 厂商开始废弃或禁用 Server Push,在谷歌v106已经禁用服务器推。

image.png

懒加载,防抖,节流

这个不多说了

渲染层

js阻塞

对于js阻塞,我们可以分为以下两个方面

  • 首屏加载的js

    可以使用defer或者async关键次,最起码可以做到,不会因为网络下载导致阻塞。

    执行js一定会阻塞的,除非用webwork,将js执行放到另一个线程

  • 长任务js

    1.不可分段执行,且耗时的任务,可以使用webwork

    2.可以分段执行,比如100000个 n = 10000 while (n--){}的循环 可以使用requestIdleCallback,在浏览器空闲的时候执行。

  • WebAssembly

    首先大家要知道,js的运行速度远小于c++ / go / rust等编译型语言,WebAssembly是一种,可以在浏览器端运行c++, rust语言的技术。

页面渲染元素过多导致的阻塞

  1. 如果是过多元素回流导致的卡顿,可以试试能否将回流改为重绘来解决,比如说通过getBoundingClientRect读取元素的宽度信息,能否使用读取style样式中的宽高来替代。
  2. 再就是看看是否能通过将一次渲染全部改为分页,下拉加载更多这种。
  3. 虚拟列表,只渲染视口的数据,但是依然会存在网络问题,对于几万条数据的这种表格数据可能网络方面就需要几秒的时间。

参考资料juejin.cn/book/684473…