记一次白屏统计与修复
发布在实践总结2015年1月30日view:2325性能优化
在文章任何区域双击击即可给文章添加【评注】!浮到评注点上可以查看详情。

白屏来源

上一版部门用的前端结构是python || lua渲染的html页面 + seajs + js模板 + less,但是这种情况发现对于不懂服务端渲染页面,或者服务端人员来说,在配合上存在工作不明,比如渲染的html应该由谁来维护,毕竟渲染的页面还是需要从服务端取数据的,以及在互相配合的过程中存在知识差异效率低的情况。

所以我们重构了,改成 backbone + modjs + js模板 + less, 打包模块也由grunt改成fis了,也就是前后端分离了。

白屏现象

重构了两个月,终于要上线了,好激动啊

白屏访问不了…白屏访问不了…白屏访问不了…

我去,我都没有重现啊

白屏定位与数量统计

既然出现了反馈,那肯定就是有问题了,但是本机又没有重现,该如何定位呢?

首先,还是要确定下白屏的数量占比。

统计方式,就是监听某个主DIV的变化(因为是单页面的应用,所以总会有个入口DIV来监听),白屏即是该DIV没有在规定时间内被放入东西,所以只要在规定时间内该DIV没有变化,那就可以进行白屏统计了。

最后统计上来,发现白屏占比在6%左右,数量还是蛮大的。

(如果说还需要统计网速之类的,因为我们的主程序js是通过async挂上去的,也可以在规定时间内检测加载到哪个script了,由此来确定程序的加载情况如何)

(如果说还需要统计API的调用情况的,比如是否timeout了,那可以在backbone的model里面的parseError进行监听)

白屏问题原因分析

既然问题出来了,数量出来了,那怎么找出原因就显得很重要了。

通过限速,重现用户反馈情况,步骤代码分析,最后确定:

1、网速渣渣导致相关依赖资源加载超时

2、客户端存在bug,缓存模块错乱,不缓存js等后来挂起的文件,以及乱缓存index.html

白屏解决

1、网速渣渣

针对这个情况,我们发现会出现4个现象

一、首页直出时间过长

二、依赖js没加载完全

三、文件依赖关系表map.js加载不正确

四、接口调用时间过长

对于首页直出时间过长,这个对于前后端分离的应用,基本都是会遇见的,毕竟首页的数据都需要通过再调API去拼接,加载模板等,这都是需要时间的,如果网速不行,那这个时间就更长的,但是考虑到需要做前后端分离,总不能还是以渲染模板的方式,那到底应该怎么才能确保前后端分离,又能够加快直出时间。

这个时候就需要nodejs直出了,通过在服务端增加一个nodejs中间层,由nginx将前端的请求转发到nodejs上,nodejs响应请求,加载资源,向底层的cgi进行API请求,之后进行拼接,返回html页面,这样资源跟api的请求时间都在服务端完成,缩短了时间,至于模板之类的,还是能够用到前端。当然nodejs也会有请求资源错误的情况,这个时候就需要返回错误标志给前端,前端再发起原来的异步请求,这种方式相当于一种容灾保障。

因为是应用方式,所以总是难免存在一些基础依赖,比如modjs,backbone, underscore, jquery等,这种一般都会通过打包成一个js来减少http请求以及文件大小。

但是不管怎么打这个文件大小还是会蛮大的,比如打了100k,那在网速渣渣,比如20k/s的情况还是需要5s的

再加上其他一些首页资源,那加载时间超过15s还是有可能的。

针对这种情况,只能通过打包模式,加载资源的模式进行改进。强烈按照“首页必须”进行开发,按需加载,其他的资源可以放在二屏,毕竟首页决定着是否还会继续使用。

文件依赖map.js加载失败

map.js主要是由fis打包插入到页面,用于解析模块之间的依赖关系的,这个文件是个超级入口

在网速渣渣,一旦这个文件加载失败了,那其他都不用玩了。

解决方法就是,尽量减少文件夹的嵌套,文件名不要过长,因为map.js会按照这种进行解析,其实也就是尽量减少map.js的大小

另外,因为fis中map.js的加载方式是require.resoureMap,之中的依赖关系是按照字符串的,没有使用变量,这个也可以按照seajs.config的方式进行

最后就是map.js容灾了,因为map.js加载失败,程序的启动入口require.async会直接请求路径,比如require.async(’index/app’),如果map.js加载失败,会变成请求index/app这个路径,这个时候,我们就可以在这里加入一个页面,用于重试加载页面等。

另外,接口调用时间过长也会导致单页面应用的加载时间过长,这种我们主要是前端需要给接口设置timeout时间,Backbone.async里面可以设置

对于不是nodejs直出的页面,那前端的页面框架需要做先把与数据无关的结构数出来,之后再通过api插入数据,虽然在整体的加载时间上没有减少太多,但是感官上可以看到页面的逐步输出。

2、客户端缓存bug

客户端随意缓存index.html,这种是大坑,只能通过url中加上随机数进行更新

资源不缓存主要是没有带上if-modify-since, if-none-match这种需要加上304验证,客户端自行补上即可。

白屏启发

做好性能检测,以及限速检测,订制应用性能数量级,比如10k/s加载时间应该在什么范围内

另外,对于可订制的客户端,也可以仿照(manifest/appcache,不完善不适合)做一个缓存机制,即是判断服务器版本是否与客户端保存的资源一致,不一致即下载新的,一致即直接使用本地的,这样就变成一个类本地应用了。

博文原地址:http://aihaos.com/rz/20150130.php

评论
发表评论
2年前

跟我现在想用的技术一模一样,感觉这个白屏问题,是fis的mod.js和map.js的坑啊,我现在有点儿不敢用了..

2年前
赞了此文章!
WRITTEN BY
格迪
喜欢前端,偶尔玩玩后端
TA的新浪微博
PUBLISHED IN
实践总结

工作上的一些前端开发总结

我的收藏