记 一次线上问题的排查和处理
场景复原
2019/12/28晚19:05左右,忽然被拉进微信群。放出一段微信聊天记录,公司(国内某知名的互联网金融公司)高管使用app时发现公司app中活动推广页面打开缓慢,20+s才打开,产品,市场部老大被质问。此时问题来到了我们开发组内。
收到问题后,组长和其余经营人员等其余人员,用手机访问同一个活动推广页,都可以1.5s内打开页面。
问题设想
先简单详情下项目结构和背景。
该项目是一个配置项目,姑且称之为”活动配置项目”,该项目分为一个配置平台和一个H5展现平台,在配置平台可以配置H5页面的展现图片,按钮定位,轮播图等等,通过生成一个结构化的json文件,上传到cdn。H5展现平台通过ajax获取cdn的json文件,同时解析JSon文件,并渲染出对应的页面。同时需要对接公司三大平台app,所有内部有很多和app进行交互的JS文件,还有各平台特有的统计JS。因为公司内三大平台基本相互独立,在技术层面没有对native的少量能力做统一,导致少量JS的功能存在冗余,但是又不得不引入。
“活动配置项目”配置生成的主要有两部分内容,第一部分:形容的配置JSon文件,第二部分:项目中用到的图片。两者均存放于cdn中。
由上场景复原可猜想,页面业务逻辑应该不会有问题。做以下猜想:并从上往下优先级排查
- 静态资源在某些特定网络下加载缓慢导致,包括html,JS,配置的JSon文件,以及图片资源。
- 检查前台页面代码,看能否是JS获取缓慢(阻塞)而导致页面无法进入业务中。
排查方向
第一点排查:对公司所用到的所有cdn进行测试,未发现显著异常。在cdn回源测试中,发现个别cdn站点出现504异常,后经排查,应该不是因为cdn导致缓慢。
第二点排查:服务器使用情况排查,发现当前活动部署与一台公用iis服务中,当前服务器中部署了多个服务,可能存在某些时刻服务资源争抢导致服务响应时间变长的情况。
第三点排查:发现H5展现平台对JS的引入都放在html的head或者body的首部进行加载,同时,通过chromeDev tool工具,发现一共引入了20左右个JS文件。
问题定位
由于无法重现公司老总的问题,但是既然问题出现了,还是要想尽办法处理问题,进行优化的。
前台中JS在未开启async,defer时,JS的载入执行都是依照从上往下执行的。所有党20个JS同时放在首部,只要要一个JS载入缓慢,则可以导致后续的业务无法执行。这一点是必需要处理的。
同时另一点,当有多个JS同时放在首部,每个JS的下载都需要和服务器建立连接,在Chrome浏览器中建立连接的并发数在7个左右,所有后续的资源都需要等待。同时建立多个连接,都需要进行TCP的建立,握手,SSL的建立,在网络层面是很大开销。
问题定位一:对此给出策略是降低连接的建立,即减少JS的网络请求
对于能否需要把所有的JS放在首部,主要取决于业务能否需要依赖这些js。因而对所有js进行了梳理,把业务强依赖相关的js放在首部加载。而对于业务弱相关的js放在尾部引用。这里弱相关的有两种类型,第一种是相似于统计功能的,即便js载入失败,也不会导致业务页面无法出现。第二种是只会在页面的点击事件等才会用到的js。基于第二种的,还是会存在js没有加载成功,此时点击事件中业务逻辑无法完成。
问题定位二:理清强依赖js和弱依赖js,分开进行首尾分别加载
文件的大小在文件传输时间中占有很大的因素,所以对文件进行特定的解决,会有比较大影响
问题定位三:对未进行压缩的js进行压缩解决。同时在服务器开启gizp压缩,减少网络传输的字节大小
基于定位的三点问题,得到的整体优化方案是:优化cdn回源配置,将活动迁移到单独的服务器上。在前台层面理清强依赖的js放在首部,弱依赖的js放在尾部,同时对首部的js进行合并压缩解决,对尾部的js进行压缩合并出来。并且服务器开启gzip压缩
修正问题
基本确定了优化方向,剩下就是如何实现优化方案了。
- 厘清页面渲染依赖关系,将强制依赖放在首部,非依赖或者弱依赖放在尾部。
- 项目前期并没有使用任何构建工具,并没有对少量js进行压缩。优化的方案是使用gulp对前置依赖js进行合并并压缩,对后置弱依赖或者者非依赖的js分开打包,在引入。
- 保证页面渲染为第一要务,剩下的其余sdk初始化等操作都等最后再进行。
测试性能报告
修改前
修改前在ChromeDev Tool工具下网络的连接传输情况。如下,从图上可以看到,页面载入了20个js,从这张图反馈出来的信息除了载入js的多少,在waterfall一栏中,可以看到诸多的黄色和紫色,期表示的就是网络连接必要的,黄色为建立连接的时间,紫色则是SSL建立连接的时间。而造成这个问题最主要的起因猜测是因为Chrome建立连接的并发数只能在7个左右,多余的资源需要下载,这需要排队等待,并且可能导致连接断开,无法复用连接,在这里就已经花费了较多的时间。
修改前.png
修改后
修改后,js的资源从20个变为10个,将前置依赖打包成vendor.js,将app的弱依赖或者者是非依赖打包成app.js。通过减少js的请求,以减低http连接的建立和ssl的建立,减少服务器的io操作。
从ChromeDev Tool中的waterfall已经不见了黄色和紫色,证实网络方面体现良好。
修改后@2x.png
总结
但凡免不了要总结一下
前台的体现性能直接影响着客户的体验,毕竟是里客户最近的,前台工程师更应该站客户的角度去了解产品。话说回来,前台优化抛开前台代码层面的实现因素,影响最大的莫过于网络的因素。而网络的因素是复杂的,资源的访问取决于你的网络架构是怎样样的。
从最简单的:用户端发起请求 -> (建立连接)-> 资源服务器返回资源 -> 用户端执行并渲染。
但是,为了提升服务的可用性,网络架构会使用代理商服务器
使用了代理商服务:
用户端发起请求 -> (建立连接) -> 代理商服务器检查资源能否有效 -> (有效) -> 资源返回 -> 用户端执行并渲染
用户端发起请求 -> (建立连接) -> 代理商服务器检查资源能否有效 -> (无效) -> 访问资源服务器 -> 资源返回 -> 代理商服务器缓存(继续响应用户端) -> 用户端执行并渲染
又但是,假如某些资源是存放cdn中,则资源又需要访问cdn和回源等问题
用户端发起请求 -> (寻觅最近节点的cdn服务器,建立连接) -> cdn能否存在资源 -> (存在) -> 资源返回 -> 用户端执行并渲染
用户端发起请求 -> (寻觅最近节点的cdn服务器,建立连接) -> cdn能否存在资源 -> (不存在) -> 回源解决 -> 资源返回 -> 用户端执行并渲染
当一个页面的包换的资源存在不一样的部署方式时,在排查问题时,就需要厘清最有可能导致问题的关键点。这当然取决于发生情况时候的具体体现。在网络方面的排查基本上就是回溯资源的访问过程。
回到最后,代码层面上的排查,能否存在影响代码执行,或者者耗时长的操作。如前文提到的js载入的问题,其实在前台已经是老生常谈了,在html中,假如未对js增加defer,async,则js代码的执行依赖于前置js代码执行完成才会执行。这个则会阻塞页面的渲染,所以都将js置于</body>之前。
对于复杂业务,将业务拆分成多个模块解决是一种很好的习惯,这样有利于以后维护和需求的递增。但是这样必然导致资源文件增多,当资源过多时则可能引起浏览器并发不够而耗时。左右在开发过程中建议模块化,但是发布前还是需要将资源合并压缩解决,这里也不是绝对,主要还是要看资源的数量,建议js资源文件保持在10个以内。
除此以外,对数据源这一块,可以使用缓存,目前浏览器对localStorage支持度已经很好,关键数据可以进行存储。在ajax异步成功前展现缓存数据。当然对少量数据精确性要求很高的,通过少量loading明确提醒其实也是不错的选择。
结束 2020-01-01 一眨眼,已经2020了。
老许,你要老婆不要。只需你开金口,今晚就给你送来。—— 《牧马人》
1. 本站所有资源来源于用户上传和网络,如有侵权请邮件联系站长!
2. 分享目的仅供大家学习和交流,您必须在下载后24小时内删除!
3. 不得使用于非法商业用途,不得违反国家法律。否则后果自负!
4. 本站提供的源码、模板、插件等等其他资源,都不包含技术服务请大家谅解!
5. 如有链接无法下载、失效或广告,请联系管理员处理!
6. 本站资源售价只是摆设,本站源码仅提供给会员学习使用!
7. 如遇到加密压缩包,请使用360解压,如遇到无法解压的请联系管理员
开心源码网 » 记 一次线上问题的排查和处理