飞道科技

飞道科技文档总汇

服务性能优化

客户(对开发而言,客户就是产品经理)会报怨:

  1. 系统太慢了,半天还不出来东西
  2. 用户操作时等待的时间太长了,上个厕所回来还没搞好
  3. 本以为死机了,后来有经验了才知道原来是系统太慢。

为什么要优化服务性能

我们为什么要优化服务性能呢?

  1. 用户体验不够好(有时候其实是很差)
  2. 云服务器或事件成本太高

原因分析

  1. 客户端程序执行太慢
  2. 服务执行时间过长
  3. 硬件因素,包括服务器和客户端的硬件(cpu,内存等)以及网络因素

本文将抛开硬件因素,从设计和开发层面上分析服务性能并给出优化的几个方向。

客户端

可能会造成客户端速度慢的因素有:

  1. 页面初始化加载内容过多,这包括页面上用到的css文件,js文件以及图片及文字图标等文件
  2. 页面初始化加载内容过多过大,这包括页面上用到的css文件,js文件以及图片及文字图标等文件
  3. 页面初始化js脚本执行时间过长

解决方案:

  1. 减少代码中对控件依赖

    如果控件在该页面上没有使用,请不要引用它,目前没有非常好的方案对此作自动检查,需要依赖开发人员的主动分析,示例项目中引用了两个控件,一个是富文本框控件,一个是分页控件,一些开发人员将示例组件代码拷贝后没有将这些依赖去掉,这不仅会造成打包后的js文件变大,还会使页面加载多余的样式文件,甚至js文件

  2. 样式文件使用cdn源

    浏览器的安全策略是对同一站点的请求不会同时超过6个,所以我们将标准的样式文件放到cdn上。同时,样式文件(包括样式图标)不宜过大,不应包括过多无用样式(可能还包含有base64格式的背景图片)

  3. js文件

    目前js文件开发人员不需要关心,打包时会根据页面中引用的原子操作最小限度对js文件进行打包

  4. 图片文件过大

    图片文件的初始化是非常关键的,它们是直接能影响到用户体验的,如果页面中很快图片显示出来了,给用户的感觉就是你这个系统很快,如果图片加载很慢,用户就很直观地认为你的系统很慢。所以页面初始化用到的图片不宜过大,在保证人眼能分辨的前提下,尽可能使用压缩较小的图片格式,如webp,jpg等。

  5. 图片文件过多

    在商城类网站中,图片文件有时候会非常多,其中呢又可以分为样式图标和页面中独立的图片,一般来讲,样式图标使用base64直接编码进样式文件较好,这样会减少大量小图标的风格加载。而页面上的<img>的加载我们可以使用懒加载、预加载的策略,使得页面在初始化时只加载可视区域的图片,合理利用网络带宽。

服务

可能会造成服务端速度慢的因素,除去硬件因素外,主要两类因素:

  1. 传输,这里指的是内网传输(可以按千兆网卡预估),内网的传输虽然比外网速度快,但是再快,也比没有慢,况且,有些数据量如果很大的情况下,这是不容忽视的因素之一。
  2. 调用服务次数过多,如果一个服务内部取数(或调用其他服务)过多,也会严重影响性能。
  3. 调用服务时内容传输过多,这包括调用服务的参数和服务的返回结果

解决办法:

  1. 良好的产品设计

    一个良好的数据库设计是非常关键的,如果考虑问题不足,很有可能造成编码上的很多麻烦。后面提到的编码习惯都依赖于此前提,否则服务代码写地再好,也是杯水车薪。

  2. 使用关系型数据库

    如果数据间存在关系,是不适合使用非关系型数据库的,非关系型数据库不适用于这种场景。对我们来讲,可以整体全部使用关系型数据库来存储业务数据。

  3. 好的编码习惯

    1. 尽可能减少请求其他服务(主要是数据服务)的次数,比如多次取数改为in条件一次取数,比如多个表一次取数
    2. 多个表有关系的情况下,尽可能使用数据库服务(即将提供,但目前20180620尚未提供,可以直接使用sql代替)代替数据操作
    3. 减少循环次数,使用map代替for循环查找,特别是要尽可能避免嵌套循环(尤其多层嵌套)
    4. 为了数据安全和传输速度,尽量减少参数的个数和内容大小。
    5. 减少服务的返回内容大小,非必要的信息不要返回给服务的调用者。
  4. 使用数据库服务代替内存数据操作

    1. 统计类服务尽量直接使用数据库服务(暂未提供,可使用sql代替),不要大量取数后在服务内部进行统计计算。
  5. 耗时服务

    非常耗时服务应当使用单独的服务器运行,不抢占主服务器硬件资源。web前端开发人员应拒绝这种服务的开发任务。因为nodejs是单进程,如果有服务抢占了服务资源(主要是cpu),其它服务会因等待时间过长而超时。

    首先,开发人员需要培养鉴别耗时服务的能力,如何鉴别呢?

    1. 服务请求次数
    2. 数据量大小
    3. 是否有循环操作