liusaint/ls-blog

复杂单页系统维护与优化经验

liusaint opened this issue · 0 comments

复杂单页系统维护与优化经验

1.考虑边界值

比如localstorage最大缓存数量5mb左右。一般情况下用户缓存的数量不会有那么大。但是如果到了最大量,是怎么处理,报错导致本次事件循环任务停止运行,还是给用户以提示,还是以其他某种方式保障后续代码的运行。

2.timer的管理

setTimeout与setInterval。大型项目中不可避免会有一些timer的使用。正常逻辑下我们的timer是会在某种条件下清除,但是实际应用中,用户可能等待不到该timer清除的时机就离开了该页面,于是就有一个timer被遗忘在那里,但它依然会正常运行!比如我们的项目中,一个页面有很多个不同的编辑器,早先的逻辑里有一个timer,每隔200ms检测一下是否所有的编辑器都加载完毕,然后才可以执行一些操作,等到所有的编辑器加载完毕之后清除该timer。但是用户可能反复进入该页面并且没有等到所有编辑器都加载完毕。于是可能就会有越来越多个timer在同时运行。如果timer中有跟其他模块逻辑交互的地方,甚至有可能会出现逻辑错乱。

处理方式:

  • 在我们设置一个timer的时候,考虑好这个timer是做什么用的,在设置这个timer的时候是否应该先尝试clear掉上一个同功能的timer。
  • 不直接使用系统自带的timer。自已封装方法,统一管理timer。这样至少可以避免某个timer被遗忘在角落里。

3.包含多个富文本编辑器的复杂表单页面的数据丢失问题

我们的实验编辑页面,涉及多个模块,有10几个富文本编辑器,以及其他自定义模块,每个模块又涉及到很多的业务逻辑。
由于我们产品的缓存策略。会比较频繁地从表单中获取数据缓存到localstorage,这中间就有了出错的可能。在我们网络和设备条件好的时候可能感觉不到,但是用户的网络或设备配置比较低,很多问题就暴露出来了。

提交或缓存数据,正常表单的数据一般是可以直接获取到的,但是,富文本编辑器,比如我们用的ewebeditor,kindeditor,结构式编辑器,excel表格等,如果它们没有加载好,原始内容还没有加载到它们的里面,缓存或提交的时候从编辑器中就拿不到数据,如果保存成功,那么该编辑器中之前的数据就丢失了。这种情况下,我们需要逐一判断编辑器是否已经加载好,如果加载好了我们按正常的逻辑走,如果没有加载好,我们就取用于初始化编辑器的原始数据。
另外一种思路是等待所有富文本编辑器都加载好才可以执行缓存或保存的操作,但是从网站可用性来讲,网络和设备的条件多种各样,我们无法保证所有就的编辑器就一定能操作成功。在用户无法加载成功编辑器的情况下,我们保障了功能的可用性并且保证之前的数据不丢失无疑更好。

4.自定义事件的使用。

事件是js中必不可少的功能点。我们一般用原生的事件比较多。但是如果能理解掌握自定义事件,很多功能处理起来会很轻松。是设计模式观察者模式的典型应用了。
比如我们的系统有一个自定义的前端路由管理的模块。我们在这个方法里处理url分发、页面内容替换、以及所有页面加载成功之后共同处理。那么单个页面的特殊的非公共的逻辑要如何初始化呢。
我们在页面完成替换之后触发一个自定义事件。$('body').trigger('pageLoaded');

然后在我们的业务逻辑的某个模块监听这个自定义事件。

$('body').on('pageLoaded',function(){  
    console.log('这里是日历页面,如果当前打开的是日历页面,请执行后面的代码,否则请return');     
 })

5.事件命名空间。

事件命名空间可以对事件进行更好的管理。

6.复杂系统中的变量变化追踪。

对于复杂且没有良好管理全局变量的系统而言。常常因为某个全局变量的意外改变而导致bug。你并不知道是谁在哪个地方动了这个变量,你只是发现你的断点断着断着,断到某个异步函数中之后。这个变量意外的改变了。那么在事件循环中哪里插入了什么任务,就蒙了。
这个时候就要用到Object.defineProperty这个方法了。在setter中放一个断点。当该变量修改的时候调用栈一下子就看到了。

Object.defineProperty(window, 'expUpdate', {
    get: function() {

    },
    set: function(value) {
        debugger;
    }
});

当时定位bug到一个富文本编辑器中的自定义修改中去了。
Object.defineProperty()的set方法除了用于双向绑定还能干嘛?

7.js加载顺序可控吗

8.浏览器开发工具。