zoukankan      html  css  js  c++  java
  • 半年拾遗

    惭愧,上一篇blog发表时间是12年8月份,现在已经13年2月份了。唉... 此处省略1w字。

    半年有余,blog一直闲置了。但是闲置并不代表忘记。时不时还是会敲开cnblogs的域名胡乱逛逛。马上年关了,公司里该回家的人基本不是准备回家就是在回家的路上。年前该忙的事情忙的差不多了,该做的项目也做的差不多了。顺手记点东西吧。表示我并木有忘记这里 :)

    既然是技术博,个人总结,感想之类的还是就免了。就算总结也要总结的跟技术沾沾边不是 :)

    【关于Web App】

    咋们现今说的web app,现阶段亦可简要定义为OPOA,或者再详细一点是经由 路由(hash)驱动的OPOA,单页应用。开发这种类型的应用,需要关注的几个点,大致可以归结为以下几个方面。

    1. hash驱动: 现在主流的方案都是 hashchange + history[pushState] 来做。每一个 #hash的变更对应一个 单页应用 “子App”的加载和启动。好的和强大的router机制就显得尤为重要。将hash的匹配转化为对应的js可执行方法,主流的web app 的框架基本都是此做法,通过hash匹配对应的function,此为“驱动”。
    2. 子路由和hash持久化:当然单页应用复杂起来,除了会衍生出很多“子app”,可能在每个“子app”里面也需要更为细分的“路由驱动和持久”。比如一个“子app”里面有翻页,或者富交互的弹层等... 所谓持久化,即为每一个“有意义”的url都能使页面还原为预期的样子,比如子路由里面带页码,带tabid,带弹层显示与否的flag。一旦有这种在交互设计中有意义的参数,实现上都应该记入持久化考虑的范畴(除非这个产品交互本身就不要求)。页面完全按照url的要求而表现。
      当然也可以用url之外的东西来完成持久化的功能,比如记入cookie或者localstorage来做。但既然你已经有了一套完善的router机制,为什么不用呢?
    3. 数据异步化:web app和web page还有个较大的不同点在于 web page是server端直接吐页面,异步数据可能也是页面中局部的模块在用。但是web app是整站,整个app都是异步数据接口在做。server端只负责从数据库中挖数据做拼装。数据parse,数据填模版都是前端的工作。大量的异步接口和数据必然导致异步编程体验。改善异步编程体验,这是一份重要的工作。这就需要你有一套好的Model机制。Backbone很多人喜欢用,除了它有我上面说的较为的完善router机制外,还在于它也把异步的数据请求体验通过 message 改善了不少。
      fetch或者Model.set的时候自动会触发 ‘model.change’事件。其实对于消息订阅机制稍微熟悉一点的高级开发者,这种消息机制完全可以自己实现,并且代码量极少。关键在于你的思路有木有跟上。
    4. 模版前端化:上面说了数据异步化,既然数据都放到了前端的处理,模版自然也就放到了前端。从后端的模版慢慢发展到前端,逐渐也有了好多好多人的工作。有Less-Logic的,比如大名鼎鼎的mustache的js版本,或者mustache的改进版Handlebars等。为了针对js这种语言,后面又有了针对js的模版,Full-Logic的,大量的,每个公司自成一套的js模版,比如jQuery.tmpl, tmpl, ejs, micro template ... 以及各种以公司或者js基础框架命名的js模版,这里就不提了。模版的优劣不在本文的讨论范围,这里要提的是在使用模版的时候尽量也要考虑到局部刷新的机制,再复杂的app都一个render,一个大模板,任何一小块数据更新都整块全部干掉重新填进去,显然是不合适的。所以建议在模版划分的的时候也考虑到子模板的划分。(除非你的模版系统本身就支持局部刷新【chunk机制】)
    5. 事件代理:接上面,因为前端模版的出现,页面上dom大多不是html页面一开始被浏览器解析完就有的,而是后来通过获取异步数据->拼接模版->innerHTML填到html对应容器里面的。正因为这种情况的出现。事件的绑定就要特别的小心了。好多开发不是很熟练的同学经常会犯的低级错误,说怎么我模版里面有这个dom,而且我通过inspector调试工具也确实找得到这个dom,但是怎么事件绑上去没效果。这里就要小心检查下是否你绑事件的时机是在render,也就是你拼接好的的dom str 填进页面dom树之前了。当页面中都没有这个dom,怎么可能绑事件有效果。用jq的同学又因为jq的容错机制,导致dom其实没有都没有发现报错而一头雾水。
      即使你确定在render之后再绑的事件,但是也不一定是好的策略,因为模版机制会让你的容器里的html不断的刷新。一旦dom刷新了,不但你之前绑的事件没了,还容易引发内存泄漏各种问题。
      所以这里delegate明显是更舒服的方案。通过外围的容器来代理容器里面的dom事件。方便且可以规避很多不必要的问题。

    上面说了这几个点,是我个人认为,开发web app需要着重注意的几个点。把这几个点都一一做好了,开发OPOA的web app自然也会变得容易起来。

    【关于框架】

    • 看了上面说的,好多同学应该都会说那我直接用backbone不就好了。它把上面几点都做的还算不错。而且易用性也蛮好,上手也快,backbone+underscore+jquery 快速开发OPOA应用蛮不错的搭配。
    • 但是我还是想说说可能更深层次的需求和其他的框架间的对比:
    • 比如就backbone这种mvc式,它足够轻量级,api也友好,搭配其他js基础库也方便,可是它的router配置机制似乎还是没有期望中强大,至少简单的和python这种后端脚本对比一下就发现。另外就是backbone并没有提供“组件”机制。这也是国内外很多大公司迫切需要的东西。大公司都渴望沉淀,都希望在做项目的同时还可以顺带沉淀下各种组件,控件等。但是如果你用backbone,就会发现它并没有提供 它的规范下的“组件”机制。 当然我们必须得承认人家在设计这个东西的时候“组件机制”可能本身就不在它的范畴。
      所以,“组件”其实也是每个大公司都在尝试深挖和沉淀的东西。可惜似乎没有特别优秀的例子。
    • 除了mvc老式框架。后来国内外(主要是国外)又衍生出了MOVE[model,operations,view,events], MVVM[model-view view-model] 等等各种适应不同场景的开发模式。MOVE算是MVC一个小进化版,Linkedin的一个工程师提出的,但似乎没有好的清晰的实现版。有的实现看起来跟MVC并没大出入。 MVVM我觉得 微软一直在致力和尝试的方向,从doNet到现在win8的开发模式中,都或多或少的可以看到MVVM的影子。尤其是win8的开发。使用过win8的js lib的同学应该都会有感觉,他的控件和模版的方式,以及data-bind, 和另一个目前主流的MVVM 框架knockout.js 都有不少相似的地方。 其实我是觉得knockout.js 是借鉴的 微软的思路在做。:)
      另外还有google的一个MVVM流派,那就是angularjs, 当然knockout和angular我都没深入使用过,没什么发言权。
    • 但是就我个人观点认为,mvvm的模式可能目前来看更适用于PC端的web app开发。mvvm的模式内耗太大了,而且像angularjs这样通过自定义标签来做二度parse和渲染的模式,在浏览器渲染引擎不够给力的情况下,难免会存在组件渲染消耗高,甚至页面组件“闪动”的情况。就PC端而言,我想这些还不是大问题,但是对于mobile端,我并不是很推荐。负荷有些重。
    • 然而对于backbone应用在mobile端,我这里还要提一下,backbone 的 getHash 和内部 this.location的 对象缓存在 低版本android上[android 2.2, 2,3] 是有坑的,可能导致router失效。使用的同学在这种场景下需要特别注意!

    【关于 Web For Mobile】

    这半年我几乎一直投入在Mobile端 web app 的开发上。有几点可以和大家分享讨论下。

    • 首先,做mobile端的web app,顺手的地方在于H5相关的新的特性基本上大体都可以随手拿来用,不管是css3的样式,排版,transition动画等,基本上加上webkit前缀都可以放心拿来用。其他的特性,像什么localStorage,sessionStorage,history api,要用起来也是很方便。
    • 但是不要高兴的太早,mobile端蛋疼的可能不在于 features的支持上,而是在于客户端版本和浏览器的多样化上面。css咋们放心的用,放心的排版,基本出来的东西各个平台,各个版本基本都八九不离十。但是在交互行为的表现上,低版本的android 和 很多奇葩的第三方浏览器 诡异的坑有可能让叫天不应,叫地不灵。
    • 表现比较乖的ios 5+ 的原生safari 和 android 4.0+的原生浏览器我就不多说了。 重点说说不太乖的低版本的android和第三方浏览器的各种坑。随便举几个例子:
      • 针对于弹出层,这是最容易出坑的地方,比如一个特殊的场景,在一个浮层中,加入有一个list列表,并且通过事件代理,list中每个item都通过delegate绑定有点击事件,假如列表很高,而弹层始终保持屏幕可是区域高。此时假如list的scroll采用overflow:auto原生滚动的话,除了低版本android不支持外,在高版本android中,靠近底部的list的最后一个item点击可能会出现诡异bug,e.target获取到的可能是遥远位置的元素。
      • 同理,由于android对于事件代理以及dom表现的“缓存”机制,当有类似“抽屉”效果这种简单的展开,收起的效果时。假如使用overflow:auto原生的滚动,当展开抽屉-滚动-关闭抽屉或者展开别的抽屉的时候,再点击可能出现诡异的bug。
      • 所以建议还是自己写scroller靠谱,既兼容低版本android又能规避一些未知bug
      • 另外,关于android上input:focus时input不随软键盘升起而抬高的情况,建议尝试 :focus{-webkit-tap-highlight-color:rgba(255, 255, 255, 0);-webkit-user-modify:read-write-plaintext-only;}
      • 还有比如ios5极其以下版本使用 transition 针对input[display:block]进行变化的时候,会有极其明显的残影,建议有这种对input有动画需求又有改变display属性需求的时候,尽量采用 inline-block;
      • 还有比如ios上使用transform的时候的闪屏问题可以尝试使用
        -webkit-transform-style: preserve-3d; -webkit-backface-visibility: hidden;
        解决。
      • 另外还有android上的touch事件穿透的问题,原生的浏览器基本上 e.preventDefault(); e.stopPropagation(); 结合一下可以解决大部分版本的浏览器。但是 UC for android 穿透依旧继续...
      • 另外再吐槽一下UC的极速模式,在脚本请求高并发的时候可能会让你的脚本一个也down不下来。这种情况请使用 脚本loader的同学同时又有兼容UC浏览器需求的注意。
      • 还有,“target=_blank”, "window.open" 这样的尝试新开窗口的东东 在低版本android上的uc 和qq浏览器上 都将失效。
      • ......
    • 总之一句话,想在mobile端做到浏览器全兼容,体验全一致,同样是件极其蛋疼的事。
    • 另外,对于mobile端,尤其是2G网络的情况,http请求更多的时间可能是花在DNS连接和握手上面,所以这种情况下的 资源合并,和http链接数的减少就显得更为重要。这对于使用loader或者类似 seajs 这样的默认按 app package 打包压缩的同学,在优化的时候可能可以考虑下更进一步的资源combo, 有可能对你的项目性能提升会有帮助。
    • 此外,我想说的针对mobile端,还可以探索的领域还有不少,比如一个很重磅的东东,canvas,在目前mobile端的web 上,几乎见不到任何实际应用的例子,但是我觉得其实mobile端也是可以开始有空间给canvas发挥了。现在2000块的android机 的cpu 跑 canvas的demo,300粒子的系统跑到50fps没有什么压力。关键是应用场景,我觉得未来canvas在移动端的尝试可以从替代一些简单的gif,或者flash动画开始。甚至可以做runtime的 资源分离 和组合的系统, 这种东西对于电商的“牛皮癣”需求是可以形成新的解决方案的。

    【关于响应式】

    这一两年这个概念开始在互联网圈子里面慢慢热起来。起因也是由于多终端的普及,同时降低开发维护成本。我同样一套代码和样式,可以兼容不同大小,不同分辨率的终端,不用为了不同的分辨率重新设计一套系统,这种降低成本的事,谁不愿意做?

    关于响应式,我想说的不多,

    • 一个是css中注意 @media query 这种东西的使用,在mobile端极其有用。在使用 @media 的同时,也不要忘了 background-size 这样的东西,在某些特殊的时候,会给你意外的惊喜。
    • 另外一个就是 js中 resize事件的合理使用。 我并不建议在resize 事件里面 为了适配 不同的大小 大幅篇章的直接操作一大片dom的样式。我估计这样做的同学自己也会被绕晕。在dom树外围容器上 加上 class 的命名空间, resize 适配的时候只需要将 这个className 适配为预期的className, 其他的布局改变 还是放在css里 这个对应 class 命名空间下面来做。会为你省事很多,也提升性能不少。

    不知不觉,将近3个小时就过去了... 打了不少字。大部分也算自己这半年来的心得和感知吧。

    打了这么多字手也累了,总之还是希望勉励自己一下,blog还是希望继续写下去,“

    勿以善小而不为,不以恶小而为之

    ” 

    PS:instagram昨天好像出 web 版了,这算是道内的新消息,总体来说,instagram这个产品,我挺喜欢的。

  • 相关阅读:
    希望走过的路成为未来的基石
    第三次个人作业--用例图设计
    第二次结对作业
    第一次结对作业
    第二次个人编程作业
    第一次个人编程作业(更新至2020.02.07)
    Springboot vue 前后分离 跨域 Activiti6 工作流 集成代码生成器 shiro权限
    springcloud 项目源码 微服务 分布式 Activiti6 工作流 vue.js html 跨域 前后分离
    spring cloud springboot 框架源码 activiti工作流 前后分离 集成代码生成器
    java代码生成器 快速开发平台 二次开发 外包项目利器 springmvc SSM后台框架源码
  • 原文地址:https://www.cnblogs.com/hongru/p/2902938.html
Copyright © 2011-2022 走看看