前端性能优化总结

这是我参与更文挑战的第10天,活动详情查看: 更文挑战

从输入 URL 到页面加载完成,发生了什么?

可以回看我之前的文章:前端HTTP知识总结

性能优化大概都是围绕以下4个过程进行:

  1. DNS 解析
  2. TCP 连接
  3. HTTP 请求
  4. 浏览器渲染

而对于DNS解析TCP连接这两个步骤,我们前端可以做的努力非常有限,相比之下,HTTP请求浏览器渲染的过程优化才是前端性能优化的核心。

DNS 解析

问:DNS解析花时间,如何尽量减少解析次数或者把解析前置?

答:浏览器DNS缓存和 DNS prefetch。

TCP 连接

问:每次都要三次握手TCP,有没有解决方案?

答:长连接、预连接等。

HTTP请求

我们最终写好的前端代码最终会打包成一些浏览器可识别的资源包,这个资源包的大小往往决定了HTTP请求次数和HTTP请求时间,或者我们可以将一些资源放到缓存里,不用每次都去请求。

gzip

在请求头中加上accept-encoding:gzip,服务器了解到Gzip压缩的需求,它会启动自己的 CPU 去完成压缩,可理解牺牲一些服务器时间开销和CPU开销,省下了一些HTTP传输过程中的时间开销。

webpack

  1. loader:比如babel-loader,最常见的优化方式是,用 include 或 exclude 来帮我们避免不必要的转译,还可以选择开启缓存将转译结果缓存至文件系统。
  2. 插件:由于第三方库的庞大,webpack构建速度依然会因此大打折扣。我们可以选择一些当依赖自身发生版本变化时才会重新打包、如DllPlugin。
  3. Tree-Shaking:基于import/export 语法,Tree-Shaking可以在编译的过程中获悉哪些模块并没有真正被使用,这些没用的代码,在最后打包的时候会被去除。
  4. 多进程:webpack是单线程的,多任务时只能一个接一个地等待处理。而我们的 CPU 是多核的,使用比如Happypack会充分释放 CPU 在多核并发方面的优势,帮我们把任务分解给多个子进程去并发执行,大大提升打包效率。

缓存

  1. HTTP Cache(重点)

强缓存:利用ExpiresCache-Control这两个字段控制缓存时间。浏览器根据expires和cache-control字段判断是否命中,命中则直接从缓存中获取资源并返回的HTTP状态码为200,不再发HTTP请求给后端。服务器返回响应在 Response Headers 中将过期时间戳写入 expires 字段,对比本地时间和 expires 的时间戳,如果本地时间小于 expires 设定的过期时间,那么就直接去缓存中取这个资源,如果直接手动去把客户端的时间改掉,那么 expires 将无法达到我们的预期,HTTP1.1 新增了 Cache-Control 字段来设置时间长度,在时间长度秒以内都是有效的,规避了时间戳带来的潜在问题。
Snipaste_2021-06-22_09-57-32.png
协商缓存:如果我们启用了协商缓存,它会在首次请求时随着响应头返回Last-Modified时间戳字段,随后我们每次请求时,会带上一个叫 If-Modified-Since 的时间戳字段,它的值正是上一次 response 返回给它的 last-modified 值,服务器接收到这个时间戳后,会比对该时间戳和资源在服务器上的最后修改时间是否一致,从而判断资源是否发生了变化。如果发生了变化,就会返回一个完整的响应内容,并在 Response Headers 中添加新的 Last-Modified值;否则,返回缓存资源未改动(304 Not Modified),资源会被重定向到浏览器缓存,Response Headers 不会再添加 Last-Modified 字段。

优先级较高的是强缓存,在命中强缓存失败的情况下,才会走协商缓存。

  1. Memory Cache
  2. Service Worker Cache
  3. Push Cache(HTTP2新特性)

按需加载

比如十个路由对应了十个页面,我们先给用户展示主页,其它页面等请求到了再加载。

内容展示

浏览器端的性能优化——这部分涉及资源加载优化、服务端渲染、浏览器缓存机制的利用、DOM 树的构建、网页排版和渲染过程、回流与重绘的考量、DOM 操作的合理规避等等

© 版权声明
THE END
喜欢就支持一下吧
点赞0 分享