说真的,好久没有写文章了,因为工作量越来越大了,非标准的技术知识例如各式各样的框架也越来越多了,脑袋疼,吐个槽!!!
顺便也把自己多年没有更新的日期组件翻新了一次:https://github.com/xfhxbb/LCalendar
最近这几年因为所谓的流行,跟着大家用react和vue,说真的,写的我头大,很多时候出现问题的话,框架内部的问题改也不是,不改也不是,完全是一片盲区嘛,感觉是把自己的领土让给他人一部分,天天参拜它要好好配合我的代码别出故障,当遇到框架内部问题的时候,你跟老板说框架问题,他会踢死你的。
state的更新和render的开销未必小
用户的交互行为并不一定就伴随着数据的变化,比如简单操作一个select标签,这个动作本来只需要浏览器正常反馈用户的行为即可,我们可以立刻根据原生的dom事件对标签进行取值,但是使用了react后,不仅页面需要定义一个不必要的状态控制变量来记录状态,导致维护一个很肥的state,同时,交互行为至少需要触发一个漫长的setstate和各种钩子操作,导致这么一个简单的选择操作而页面却无法快速的响应用户,很多时候,甚至在快速敲击键盘时在onkeyup上踩坑,莫名其妙的浏览器卡死,大多数的罪魁祸首应该就是框架内部的复杂运算导致。 所谓的diff算法快速的虚拟dom,不能作为每次用户操作都进行一系列框架内部执行各种复杂逻辑的借口,多次框架内部复杂的执行过程,开销可并不小。并且我发现一个项目中大多数场景都是简单的dom操作,性能开销远远低于render,而且dom操作后的事件冒泡的开发思维对用户反馈的掌控也更加清晰灵活,可以聚焦在原生的事件回调内,不用再将思维活生生的再沉入那一坨抽象的state中。
无法灵活的兼容原生事件或外部js
举个例子,当我们要在页面中给某个元素绑定一个点击事件,或者引入的第三方组件需要绑定在某种标签上,这是一个再简单不过的需求了,我们只需要在body闭合前追加一段脚本,如果我们这样写:
<script type="text/javascript">// <![CDATA[ document.addEventListener("DOMContentLoaded", e => { console.log(document.querySelectorAll("a")); document.querySelectorAll("a").forEach(el => { el.addEventListener("click", e => { try { //你要做的 } catch (error) {} }); }); }); // ]]></script>
如果这个项目是用的react框架进行开发,则我们在DOMContentLoaded回调内是拿不到react渲染的任何元素的,当然我们的事件绑定就是失败的: 因为要判断react是否把dom内容渲染出来,必须写在它的钩子里,所以一个本来简单的需求就必须要有源码并经过构建,没有源码没法找到生命周期函数,如果项目来自于其他成员开发,而引入的第三方库文件是来自远端的混淆加密的代码,而你只有操作线上html的权限,你接到这个需求就只好呵呵了 线上排障及调试成本高 假如代码不是长期在自己手上管理,一旦涉及交接,由于深度的组件嵌套,本该是一体的html切分的四分五裂,而该分离的js包罗万象六神合体,定位问题时,假设F12找到了某个div有问题,但因为组件都是用的别名,回到代码中从最外层组件开始阅读render内的dom结构,却无法一目了然的快速知道这个标签来源于哪个组件内,只感觉自己的目光在各种文件内跳跃。说真的,我觉得把html合在一起更方便我阅读页面内容,而不是切成小碎块!
此外,排查线上故障时,假如sourcemap丢失,包含所有页面内容的巨大的js文件真叫人无法阅读并进行快速排障,你可能会说把代码代理到本地调一下,但多人开发时,可能存在测试环境和正式环境代码不一致的情况,这种情况下,调试是无果的。谁还会为正式环境留一份sourcemap呢?
单页拷贝数据的不便
当用户想从上一个页面拷贝一些内容到新的页面,如果用单页,直接不留痕迹的跳走了。如果针对这个可新窗口打开的页面单独做一份代码,多遇到几次这种需求你就会想:我要这单页框架干嘛?我这代码干嘛要揉在一起?
脑力消耗大
曾经的编写方式就像是各个小的局部战争一样,互不影响,虽然偶尔代码量大一些,但是思路清晰啊,流水账而已。现在用这些框架就像世界大战,面向过程编程变成为了面向一个大全局变量的编程,分分钟提升了思考强度和工作量,大量高强度用全局思维编程,这很容易引发心脏病,头疼胸闷,我可不想猝死!