xinglie / xinglie.github.io

blog
https://xinglie.github.io
153 stars 22 forks source link

那些年的magix #41

Open xinglie opened 5 years ago

xinglie commented 5 years ago

  magix3缘起

 我原本以为以magix1.2版本的稳定性可以支撑好些年,不曾想人在江湖,身不由己:出了一个magixbrix共用事件模块的magix2.0版本。magix2.0是在magix1.2的基础上,把事件模块换成brix提供的事件模块而已。在实际项目开发中,brix提供的事件模块并不能有效的解决dom变化事件需要解绑或绑定的问题。这是因为brix的事件模块是扫描dom节点找到有哪些事件,这样当dom变化时,都要重新扫描,而dom是否变化是在magixview中由开发者做的,这就导致需要在view中把所有与dom变化的地方都要关注起来,从而可以在dom变化的时候通知到brix的事件模块。如果存在大量的dom变化,事件这块的每次扫描整个dom,性能并不怎么好。

 分久必合,通过magix2.0brix整合重复的部分,使我意识到仅仅做事件这块是不够的,模块的加载和实例化也是重复的,viewbrix组件间的关系也是分不清楚的,那时候我被问的最多的一些问题:在项目中我应该把这个封装成brix组件么?brix组件里不能包含业务代码么?包含业务代码在我自己的项目里也是没问题啊?在brix组件里我怎么能够使用magix管理的接口?

 magix2.0的一些事情没有做好,我们回过头来重新审视,总结经验:这些合并应该更彻底一些。

 magix3.0,合并magix与brix,使view与组件归一化,统一模板引擎。brix抱歉了,有些必须割舍,包括brix这个概念。原来的brix组件变成magixview,现在这些组件对应的view在这里:magix-galllery

  模板引擎

 许多问题皆源于它,时至今日仍然还在围着模板引擎转,使用合理的模板引擎,生成最优的目标代码,以达到高效的界面更新

 合并后第一个挑战就是选择一个合适的模板引擎,统一我们之前在项目中用到的mustache,crox,xtemplate,vue等各式各样的模板。

 underscore.template,最后一版brix用的模板引擎,也没有什么学习成本,magix3就选择了它做为模板引擎。现在来看这个模板引擎的选择并不怎么好,但在当时要整合brix,要升级组件库,许多方案只能先使用旧方案,减少新方案带来的坑和其它问题。统一,在当时显得更重要。就这样我们选择了underscore.template模板写法。

  局部刷新之字符串拆分

 如果view数据有变化,我们可以用最新的数据和模板生成最新的HTML,然后通过view根节点的innerHTML属性更新界面。当然目前也可以通过dom diff最细粒度的更新。不过那时候的需求是:找一种可以介于把整个view粗犷的刷掉和最细粒度更新之间的方案。那就是以dom节点与数据进行绑定的局部刷新,感谢波哥在这块的探索与实现,magix3的首次使用的局部刷新就是该方案

 当时的局部刷新方案的弊端是:需要在待刷新节点上写上对应的数据key,如果对应key的数据有变化时,则只刷新该节点下的innerHTML,开发过直通车的同学应该有体会。有时候忘记写key了,导致数据变化界面没刷新,如果多写了,则会有不必要的刷新。

 带着不完善的方案,magix3的使命完成:使用原有的经验,统一割裂的开发方式,减少概念上的认知。

  离线处理

 处理不好性能的程序猿都是耍流氓。大概2015年底和波哥聊优化的事情,发现很多运行在线上的处理完全可以线下做,这样上线后可以减少计算,提升运行效率。同时因为是线下提前处理好的,可以通过查看结果来发现一些原来线上不能复现的问题。加上magix的本身也需要把html合并到js中,这时候magix-combine就出来了。

 最初magix-combine只是合并文件,并做一些简单替换。

 第一个主要的离线处理是前面提到的局部刷新之字符串拆分,为了方便开发人员,不在节点上标记数据变化的key,由程序自动识别完成。magix-combine做这一个功能时,从一个文件到拆分成十几个文件,从简单的正则到复杂的parser方案,前后持续时间最长,难度系数也最大,详细的技术方案可以查看这里 局部刷新与模板 。终于凭一己之力把它做了出来,也正是得益于该方案的实现,后续很多离线处理都在该功能的基础上顺利完成。

 第二个主要的离线处理是样式的scoped化,这里有记录在实施scoped之前遇到的问题 关于style的scope。 样式scoped方案线上处理的版本居多,但我们的要求是线下完成。参考过vue给节点增加data-v-hash的方式,私以为样式选择器从原来的标签或类选择器经过scoped后加上了属性选择,浏览器在处理样式匹配上性能会下降。参考过css-modules的做法,需要通过对象+旧选择器来使用变化后的选择器名称,很难和magix这种jshtml分离的开发方式结合起来,使用起来也不方便。同时要照顾开发人员,不能因为要使用scoped功能就要做很大的变化。

 “无感使用”是我在做样式scoped时候的感受。我该如何引入新的功能而不用改变现有的开发方式?我该如何平滑稳定的把有问题的方案引导到新的方案上来?虽说不破不立,但同事的感受更重要,我不能太唐突的推进。我要实施新功能,我也要照顾现有的开发流程,如何在二者间平衡,很难。最终在不改变当前开发方式的情况下,实现了想要的功能,新的方案得以顺利实施。难,吾往矣!

 其实,一直在跟随着社区的发展,只是像前面所说的,有些功能的实现是无感知的,许多开发者在使用的时候或许并不知道我们早已默默应用了该技术。不过也正是由于我们自己的工具,可以把社区中一些优秀的方案在我们的项目中做的更彻底,能工具化的为什么要开发者参与呢?

 第三个主要的离线处理是代码检查,之前我们的开发框架和组件可以快速的搭建出页面,但是如何保证产出的代码质量,如何让开发人员自己快速检查代码,如何避免别人踩过的坑,如何让别人的经验成为自己的经验,是我想解决,并且一定要解决的,尽管很难,If not me , who?

 目前代码检测涵盖样式检查(书写要求、使用情况等),js代码循环检查(n层循环嵌套),js接口服务数据检查,模板命令语法检查,模板图片src属性检查,模板不建议使用的标签检查,模板危险属性检查,模板a或area标签检查,模板iframe标签检查,模板mx事件写法检查,模板mx-view检查,模板重复属性检查,模板命令语句中function及for of语句检查,模板标签配对检查等

 把常见问题写到代码检测里面去!把别人的经验写到代码检测里面去!把需要掌握的知识点写到代码检测里面去!授鱼不如授渔

 所以2016-2017年我的精力都放在magix-combine上,尽管有些事情远远超出离线处理这个愿景。

  我回来了

 老实说,在我做magix-combine这段时间里,magix除必要的支持外并没有怎么跟进,不过我终于忙完magix-combine回来了。

 他们说underscore.template语法写多了比较乱,好的,支持类mustach的模板语法。他们说局部刷新使用字符串模板拆分的方式仍然刷新的范围太大了,而且社区里都是细粒度的刷新,好的,https://github.com/thx/magix/blob/master/src/tmpl/dom.js。真实dom与真实domdiff,真实dom与虚拟domdiff,虚拟dom与虚拟domdiff,满足你的一切好奇心。

 我说历史的原因,我们的dom转换是在线上完成的,这显然应该在线下做,jsx的是不错的首选,好的,使用jsx去写magix,感谢竹隐的支持。我说根据同事间的调查,并不是每个人都乐意使用jsx,而且刚熟悉的类mustache写法要丢弃么,好的,支持类quickapp形式的模板。我说这些加载器requirejs,seajs,webpack都是过客,浏览器原生的import才是主场,好的,https://github.com/thx/magix/tree/master/src/module

 你有问题我有解决方案,最美好的事情不过如此吧?

  局部刷新之dom diff

 magix3提供了比较多的diff,目前线上用的是真实dom之间的diff,这是要照顾一下开发人员还有部分组件,时间久了都会有一些技术债。真实dom diff可以操作dom,而使用虚拟dom是无论如何都不能操作真实dom的,所以目前我们想直接用虚拟dom还需要一段时间的过度

  当下

 啰嗦了一大堆,有些伤感,回头看了下有用的并不多

 magix最新版本3.8.10,magix-combine的最新版本是3.11.0。模板引擎不要再使用unerscore.template,请换用类mustache的模板,当然,不换也没问题,兼容的。局部刷新使用拆分字符串的方案应该不会再使用(旧项目有bug会继续修复),pc端目前使用真实dom diff,移动端没历史包袱可以使用虚拟dom diff,长远看都会切到虚拟dom上,当然,如果浏览器本身提供了增量更新,我们就不用这么费劲了。magix3版本里面的方案切换应该没有什么成本。

 magix-combine看下 https://github.com/thx/magix-combine/blob/master/CHANGELOG.md 吧,想做一下magix-combine的分享,太多也太专了,讲的无聊,听的枯燥。今天看了下magix-combine,好像不是那么容易看懂。

 实验中的功能:离线转虚拟dom,这个由magix-combine支持。dom diff按时间片更新,这个是看reactTime Slicing后做的。

 我会继续做magixmagix-combine,有些功能因为个人工作上的安排晚了些,但不会缺席。

 github.com上的magix-gallery暂无精力维护,我们后台项目开发中使用的组件请使用虞佳维护的zs_gallery,组件使用等相关的问题可以直接联系虞佳

 解决开发、调试、打包、发布工具的magix-cli工具由崇志维护,magix3统一了技术方案,magix-cli则统一了开发方式。这个工具在这里:http://gitlab.alibaba-inc.com/thx/magix-cli

 2016年底有感于崇志、浩添去北京支援一淘商家后台项目,虽说当时我们的开发效率很高,我觉得还可以再突飞猛进,所以做了面向开发人员的可视化页面搭建:生成可供编译的代码而非线上页面。2017年集团可视化页面搭建遍地开花,而我们的则由宫卫默默无闻的开发,除了支持业务外,到目前仍然在持续完善中。这个工具在这里:http://gitlab.alibaba-inc.com/thx/magix-desiger ,附一个搭建gif图:https://img.alicdn.com/tfs/TB19JeNrL9TBuNjy0FcXXbeiFXa-1700-880.gif 现在开发一个页面只需要几分钟。重要的是以后普通页面会由运营搭建,彻底解放前端。

 移动端的cell由竹隐在负责维护,我们移动端基本上都是由cell支持的,开发移动端页面的同学应该不陌生吧。

 还有很多想法,没有落地,一个人的时间和精力是有限的。

  后记

 以古作镜,可知兴替。技术的发展是飞速的,没有哪一套技术实现可以久远,相对不变的,唯思路尔。想在技术上长足的同学,不要留于使用的表面,走进喜欢的框架里,读懂作者的悲喜。犹记得木头曾聊过微软的htc技术,时至今日,微软自己的浏览器都不支持了吧,但是这种解决问题的思路,不还在react,vue上持续发光么,iframe标签不也在淡化,由新的方案替代么。

 没有什么是不能被淘汰的,要抓住本质。去理解他人的思路,方可一反三,去读懂他人的实现,方可知深坑,去按自己的想法实施,方可胜于蓝。