性能优化

# 性能优化

# 页面首页首次加载白屏怎么处理

  • ssr渲染(后端渲染)
  • 预渲染(prerender-spa-plugin)
  • 使用骨架屏

为什么会产生白屏? 在 JS 代码解析完成之前,页面不会展示任何内容,就是所谓的白屏

  1. SSR

    • 服务端渲染的好处
      • SEO
      • 加快内容展示
  2. 预渲染

    • 在项目构建过程中,通过一些渲染机制, 比如 puppeteer 或者 jsdom 将页面在构建的过程中就渲染好,然后插入到 html 中,这样页面启动之前首先看到的就是预渲染的页面了。
    • 预渲染并不会把异步加载的数据在构建文件的过程中就渲染好,而是把每个页面静态的那部分提前在构建的时候渲染出来
  3. 骨架屏

    • 骨架页面 指的是当你打开一个移动端 web 页面, 在页面解析和数据加载之前,首先给用户展示页面的大概样式。在骨架页面中,图片,文字,图标都将通过灰色矩形或圆形块来战士,在真实页面展示之前,用户能够感知到即将加载页面的基本 css 样式和页面布局。

# 提升页面性能的方法

  • 资源压缩合并,减少 http 请求
  • 非核心代码异步加载
  • 使用浏览器缓存
  • 使用 CDN 缓存
  • 预解析 DNS
  • HTTP 优化,如使用语义化标签,避免重定向
  • 减少页面的重绘和回流
  • 使用防抖和节流
  • 避免频繁操作dom(创建一个 documentFragment,在它上面应用所有 DOM 操作,最后再把它添加到文档中)
  • 避免频繁操作style(一次性重写 style 属性,或者将样式列表定义为 class 并一次性更改 class 属性)
  • CSS 优化
    • 避免使用 table 布局。
    • 尽可能在 DOM 树的最末端改变 class。
    • 避免设置多层内联样式。
    • 将动画效果应用到 position 属性为 absolute 或 fixed 的元素上(避免频繁回流)。
    • 避免使用 CSS 表达式(例如:calc())

# 其他优化

  • webpack 模块打包和 JavaScript 压缩(如 gzip 压缩)
  • 利用 CDN
  • 按需加载资源
  • 在使用 DOM 操作库时用上 array-ids
  • 缓存优化
  • 避免重定向
  • 启用 HTTP/2
  • 应用性能分析
  • 使用负载均衡方案
  • 为了更快的启动时间考虑一下同构
  • 使用索引加速数据库查询
  • 使用更快的转译方案
  • 避免或最小化 JavaScript 和 CSS 的使用而阻塞渲染
  • 用于未来的一个建议:使用 service workers + 流
  • 图片编码优化,尽量使用 svg 和字体图标

# Vue 相关性能优化

使用单文件组件预编译模板

当使用 DOM 内模板或 JavaScript 内的字符串模板时,模板会在运行时被编译为渲染函数。通常情况下这个过程已经足够快了,但对性能敏感的应用还是最好避免这种用法。

预编译模板最简单的方式就是使用单文件组件——相关的构建设置会自动把预编译处理好,所以构建好的代码已经包含了编译出来的渲染函数而不是原始的模板字符串。

提取组件的 CSS 到单独的文件

当使用单文件组件时,组件内的 CSS 会以 style标签的方式通过 JavaScript 动态注入。这有一些小小的运行时开销,将所有组件的 CSS 提取到同一个文件可以避免这个问题,也会让 CSS 更好地进行压缩和缓存。

持久化时写入数据的性能问题

Vue 社区中比较流行的 vuex-persistedstate,利用了 store 的 subscribe 机制,来订阅 Store 数据的 mutation,如果发生了变化,就会写入 storage 中,默认用的是 localstorage 作为持久化存储。

也就是说默认情况下每次 commit 都会向 localstorage 写入数据,localstorage 写入是同步的,而且存在不小的性能开销,如果你想打造 60fps 的应用,就必须避免频繁写入持久化数据。

我们应该尽量减少直接写入 Storage 的频率:

* 多次写入操作合并为一次,比如采用函数节流或者将数据先缓存在内存中,最后在一并写入
* 只有在必要的时候才写入,比如只有关心的模块的数据发生变化的时候才写入
1
2

避免持久化储存的容量持续增长

由于持久化缓存的容量有限,比如 localstorage 的缓存在某些浏览器只有 5M,我们不能无限制的将所有数据都存起来,这样很容易达到容量限制,同时数据过大时,读取和写入操作会增加一些性能开销,同时内存也会上涨。

尤其是将 API 数据进行 normalize 数据扁平化后之后,会将一份数据散落在不同的实体上,下次请求到新的数据也会散落在其他不同的实体上,这样会带来持续的存储增长。

因此,当设计了一套持久化的数据缓存策略的时候,同时应该设计旧数据的缓存清除策略,例如请求到新数据的时候将旧的实体逐个进行清除。

组件懒加载

//如果在判断加载条件为假的时候,什么都不渲染,就会带来一系列问题:

//用户体验比较差,最开始是白屏,然后突然又渲染出现内容。
最致命的是我们判断可见性是需要一个目标来观察的,如果什么不都渲染,我们就无从观察。

//这里引入一个骨架屏的概念,我们为真实的组件做一个在尺寸、样式上非常接近真实组件的组件,叫做骨架屏。
1
2
3
4
5
6

# 怎么处理高并发情况? (比如 1000 张图片要同时上传)

最后更新时间: 2022/10/23 10:24:55