性能规范缘由

  • 1、适用场景:

    • 本篇文章,适用于单个/多个大型项目、拥有超过 10 个以上的前端开发的场景。
    • 前端项目的规模不同,成本收益比也会有所差别。
    • 通常来说,人员越多、项目复杂度越高,那么收益/成本的比值越大。
    • 对于人数较少、项目简单的开发团队,可能有部分措施不适用,因此应该根据具体情况来选用。
  • 2、核心思想:

    • 【1】解决问题:前端架构的设计,应是用于解决已存在或者未来可能发生的技术问题,增加项目的可管理性、稳定性、可扩展性。
    • 【2】人效比:对于需要额外开发工作量的事务(本文中存在一些需要一定开发量的内容),我们在决定是否去做的时候,应该考虑到两个要素:

      第一个是花费的人力成本,第二个是未来可能节约的时间和金钱、避免的项目风险与资损、提高对业务的支撑能力以带来在业务上可衡量的更高的价值、以及其他价值。
    • 【3】定性和定量:架构里设计的内容,一定要有是可衡量的意义的,最好是可以定量的——即可以衡量带来的收益或减少的成本,至少是可以定性的——即虽然无法用数字阐述收益,但我们可以明确这个是有意义的,例如增加安全性降低风险。
    • 【4】数据敏感:专门写这一条强调数据作为依据的重要性。

      当我们需要说服其他部门/上级管理者,以推动我们设计的内容时,只有数据——特别是跟钱有关的数据,才是最有说服力的证明。

      由于篇幅所限,本文很难直接给出定量的值,因此建议架构设计者,先确保项目中设计使用 2.7 里的埋点系统,根据埋点系统获取的数据,对项目效果进行定量分析,并以此写成 PPT 和其他部门/上级管理者进行协调。
  • 3、切入角度:

    • 分为基础层和应用层。
    • 基础层偏基础设施建设,与业务相关性较低。
    • 应用层更贴近用户,用于解决某一个问题。
    • 部分两个都沾边的,根据经验划分到其中一个。
  • 4、其他

    • 由于已经谈到架构层级,因此很多内容,并不仅仅只属于前端领域,有很多内容是复合领域(前端、后端、运维、测试),因此需要负责架构的人,技术栈足够全面,对未来发展有足够的前瞻性。
    • 文章的内容结构为:【项目】—>【解决的问题和带来的好处】—>【项目的实际意义】
  • 一、安全管理

  • 二、静态资源优化

  • 三、接口访问优化

    首屏直出、同构

    接口合并

  • 四、页面渲染速度优化

  • 五、总结

一、安全管理


前端的安全管理,通常要依赖于后端,至于只跟单纯有关系的例如 dom.innerHTML= xxx 这种太基础,就不提了。
安全管理的很难从架构设计上完全避免,但还是有一定解决方案的,常见安全问题如下:
XSS 注入:对用户输入的内容,需要转码(大部分时候要 server 端来处理,偶尔也需要前端处理),禁止使用 eval 函数;
https:这个显然是必须的,好处非常多;
CSRF:要求 server 端加入 CSRF 的处理方法(至少在关键页面加入);
意义:
减少安全漏洞,避免用户受到损失,避免遭遇恶意攻击,增加系统的稳定性和安全性。

二、静态资源优化

这个 level,主要是减少静态资源的加载时间,主要包括 html、css、js 和图片文件,静态资源的加载时间是前端性能最大的瓶颈(特别是图片),现如今优化的手段也很丰富,以下简要列举几种常用的方法

  • 合并 css、js 文件,制作雪碧图:减少 http 的请求次数,节省网络请求时间
  • 静态资源 cdn 分发:客户端可以通过最佳的网络链路加载静态资源
  • js、css 文件压缩,图片压缩,gzip 压缩:减少请求返回的数据量
  • 静态资源缓存机制
  • 权衡 dns 的查找

本文旨在提供一个清晰的优化思路,上述优化方法不做具体的说明,网上也能搜索到很多具体的教程,也可以留言、简信一起讨论

三、接口访问优化

如果第一个 level 做得好,可以保证静态资源以一个较快的速度加载出来,然而,此时情况并没有完美,依然还存在两个明显的问题:
1.静态资源加载完成了,页面依然还在转菊花,用户依然还在等待。现如今 web 应用已经走过完全由 php 和 jsp 等后端脚本语言渲染界面的时代,ajax 异步加载数据的方式已经成为主流,各种前端的 mvc 框架层出不穷,先加载静态资源,在执行 js 中的 ajax 请求到后台请求数据,重新渲染界面已经是一种通行的方案,这样便出现了静态资源加载完成,页面可见,然而用户还需要等待请求数据的进度条的情况(特别是接口访问速度慢的时候)
2.用户点击任意一个按钮,进度条加载了半天,也没有响应。很多复杂的功能需要并行或者串行的请求很多接口才能完成,前端的网络状况稍微差一点,给与用户的体验都极差。
以上两个问题在网络情况优异,接口请求速度快的情况下都不是问题,然而终端如果是一个手机,常常连 wifi 都不能保证,3g/4g 的网络你能期待它有多快,所以优化的潜力是巨大的

首屏直出、同构

对于上述的问题一,如果页面的初始化数据,在后端完成渲染,其它的用户交互使用 ajax 的方式完成,也就是传统意义上的首屏直出,就可以得到很好的解决
这种介于完全后端渲染和完全 ajax 渲染的方式是一个不错的思路,但是在 node 出现之前,很多人宁愿容忍首屏加载的菊花,也不愿意使用,为什么?因为前端和后端要维护两套模板,令人抓狂
node 出来之后,前后端都都可以使用 js 语言,前后端同构(前端和后台公用模板代码)使得首屏直出重新拥有了生存的土壤,所以同构直出现在常常相提并论,形同一个成语

react 在同构直出方面做得比较出众,更多相关知识,可以留言、简信讨论

接口合并

一个交互需要请求多个并行或串行接口实属正常,前端使用 3g/4g 等弱网络也着实是不可抗因素,所以最好的办法就是通过接口合并的方式来提高接口访问速度
后台提供的接口有其既有粒度,强行合并不合时宜,提供一个新的合并的接口也缺乏机动性(前端发现一个新的合并需求,就要求后端提供一个接口,后端有开发工作量不说,还得没完没了的发版)
如果把接口合并的主动权交给前端,那情况将会好很多,前端是最接近战火的地方,最知道应该如何组合接口。基于代理服务的接口合并方案应运而生(这是本人第一个值得骄傲的原创方案,这其中还包含了 node 实现,想想还有点小鸡动~)

欢迎使用 node 实现的基于代理服务的接口合并框架,欢迎建议、拍砖,您的意见是我优化的动力

页面渲染速度优化

在页面不复杂、dom 层次不深的情况下,完成以上两个 level,就已经足够了。然而在复杂的页面上,却还有很大的优化空间,页面渲染速度的优化很大的程度上依托于程序员的个人编程素质,下面简要列举几点:

  • css 放在顶部:优先渲染
  • js 放在底部:避免阻塞
  • 减少 DOM 元素数量:这个最能体现变成水平了
  • img 标签要设置高宽:减少重绘重排

    另外,新晋前端框架 vue、react,虚拟 dom 的渲染方案,在内存中进行 dom diff 比较,做到最小化的操作真实的 dom (操作真实的 dom 常常会成为性能瓶颈),能极大的提高渲染速度

使用一些页面性能分析工具给自己的页面跑分,可以帮助养成良好的编程习惯、提升编程素质,例如:WebPagetest、Yslow

总结

极致的性能优化需要有清晰的 step,这是理解以上三个维度的意义所在