🔥码云GVP开源项目 12k star Uniapp+ElementUI 功能强大 支持多语言、二开方便! 广告
### 什么是web app [WebApp](https://baike.baidu.com/item/web%20app/9475982?fr=aladdin)是指基于Web的系统和应用,其作用是向广大的最终用户发布一组复杂的内容和功能。 从一个简单的帮助消费者计算汽车租借费用的网页,到为商业人员和度假者提供全套旅游服务的大型复杂的WEB站点,都是WebApp。它包括一些完整的WEB站点,WEB站点的专门功能以及在Internet、Intranet或ExtraNet上的信息处理应用。 webapp 框架是一种简单的与WSGI兼容的网络应用程序框架,可以与 App Engine 配合使用。不必为了使用 App Engine 而使用 webapp:网络服务器支持任何使用 CGI 的 Python应用程序。webapp 提供一种简单的方式来开始为 App Engine 开发应用程序。 响应式网页设计的大部分技术,是可用在WebApp开发中的。 移动端Web App和WAP有什么不同?最直接的区别就是功能层面。WAP更侧重使用网页技术在移动端做展示,包括文字、媒体文件等。而Web App更侧重“功能”,是使用网页技术实现的App。总的来说,Web App就是运行于网络和标准浏览器上,基于网页技术开发实现特定功能的应用。 * * * * * ### 扩展 [pjax是什么以及为什么要推荐给大家 看完马上就懂](https://www.toutiao.com/i6503489296748511757/) [Pjax是什么以及为什么推荐大家用 - Sub的个人页面](https://my.oschina.net/sub/blog/123447) [defunkt/jquery-pjax: pushState + ajax = pjax](https://github.com/defunkt/jquery-pjax) [luruke/barba.js: Create badass, fluid and smooth transition between your website's pages.](https://github.com/luruke/barba.js) [关于innerHTML的试验 · 前端笔记 · 看云](https://www.kancloud.cn/xiak/quanduan/371061) [SUI Mobile](http://m.sui.taobao.org/) 算是pjax另一种实现吧,它甚至不要求服务端返回HTML片段,整个的页面的也接受,它好像可以剥离,当然可能有一定剥离规则(也用了缓存,但把这么大页面当做字符串缓存起来是不是也不太好啊,还有如果新页面引入了外部文件怎么处理呢),然后再直接添加到容器节点上去替换上一个页面,并转场。花样菜场就是这个。但总感觉这样实现太粗暴了,不太好。(感觉这不是真正意义上的单页,只是一种野蛮粗鲁的做法。) 过滤:怎么过滤,正则匹配出dom结构,外部资源,script,link等,太麻烦了吧。 哈哈,其实,过滤,滤什么滤,直接用的find哈。还说正则匹配过滤,想多了,没那么复杂。下面是关键代码 ~~~ …… * 路由实现约定 * - 每个文档的需要展示的内容必需位于指定的标识(routerConfig.sectionGroupClass)的元素里面,默认是: div.page-group (注意,如果改变这个需要同时改变 less 中的命名) * - 每个块必需带有指定的块标识(routerConfig.pageClass),默认是 .page * * 即,使用路由功能的每一个文档应当是下面这样的结构(省略 <body> 等): * <div class="page-group"> * <div class="page">xxx</div> * <div class="page">yyy</div> * </div> …… /** * 把一个页面的相关信息保存到 this.cache 中 * * 以页面的 baseUrl 为 key,而 value 则是一个 DocumentCache * * @param {*} doc doc * @param {String} url url * @private */ Router.prototype._saveDocumentIntoCache = function(doc, url) { var urlAsKey = Util.toUrlObject(url).base; var $doc = $(doc); this.cache[urlAsKey] = { $doc: $doc, $content: $doc.find('.' + routerConfig.sectionGroupClass) }; }; ~~~ 原来没用整个页面的,只缓存“容器”部分。但是这个还要这个$doc键做什么呢,浪费空间啊。 所以如果新页面需要引用外部资源,则需要放在div.page-group里面,否则没用哦,另外它也强调建议了,返回文档不要完整的文档结构,多返回了没用的html,浪费流量何必呢,何必呢,还是老老实实的按照pjax的建议吧: ~~~ 这个请求带有X-PJAX的HEADER标识, 服务器在收到这样的请求的时候, 就知道只需要渲染部分页面返回就可以了。 xhr.setRequestHeader('X-PJAX', 'true') xhr.setRequestHeader('X-PJAX-Container', context.selector) ~~~ >[danger] **注意:**测试是否为单页最好在PC浏览器上面看,跳转新的页面时**加载状态**会转,但是在微信(PC/手机)或者一些手机浏览器上面,由于没有“转”的状态,而是用**页面顶部加载进度条**的表示加载状态,在手机端即使没有跳转页面(PC浏览器上没看到“状态转”),某个单页需要加载图片等资源,那么加载进度条还是会有,所以手机上面看不出来到底是跳转还是单页。电脑浏览器加载只要加载资源,没有跳转时**加载状态**也会转(**并且有时也不一定**),而且由于现代浏览器的优化,跳转时出现“空白页面”的情况基本不会出现,**所以表面上根本看不出来的页面是单页还是普通跳转网页。需要使用控制台网络调试,看Doc下面有没有加载才能准确的看出有没有跳转页面。** 经过一些分析,我们渐渐发现了单页技术的实现方式,下面总结出了一些技术要点: 1. ajax 2. 自己拼接html字符串 3. 使用前端模板引擎,如[artTemplate](https://github.com/aui/artTemplate) 4. 后端直接返回的html片段 5. 后端返回完整/常规文档也行(SUI Mobile这种,它会处理,但是这是错误的做法,后端应该要配合,别做蠢事) 6. react单页(其实模板都是组件,打包编译在js中了,另外它还有虚拟DOM算法,数据和视图是绑定的,所以会数据变动时会自动改变DOM) 7. 路由(根据url做某动作/显示某页面,分两种,一种单页入口#后面,一种看不出的,前者做普通链接访问时不会出现“跳转”,后者则不能直接点击“跳转”,需要程序拦截原生链接事件,自己控制pushState ) 8. 转场(两个页面间的切换效果,跟路由紧密相关) > 当然这些技术也可以相互结合使用,没有规定说要怎么用,在最合适的时候用最合适的就是最好的。 可以看到react最符合,最优雅,最适合做单页,但是也有缺点,缺点就是一个单页的模板都加载进来了(这也是有点,对于它来说,后面请求不需要任何模板了,只需要数据就可以,因为模板都在本地了,这种方式实在是太激进了,而pjax虽然实现了很好的效果,但还需要加载部分页面,这还是浪费流量,所以pjax不是最完美的解决方案,相对于react时代来说已经是落后的东西了),首次比较慢,但是后期完全不需要从后端获得任何html了,只需要纯数据就可以渲染DOM了,后期访问就会很快。当然这里面也有很多值得优化的地方,一般一栏为一个单页(单页入口/单页着落点,这个需要规划好,哪些页面在是一个单页上,哪些页面做单页入口,哪些页面用普通的跳转,就像后端的路由规划一样,也很重要),如果页面比较大,也可以拆分出去,单独做成普通页面也可以。 > 在react时代来看 SUI Mobile 可以算是落后的产品了,但是SUI Mobile也是有意义的,算是传统网页向单页页面前进的重要一步,起码思想上做到了,能够不刷新页面,可以说实现了“单页”的体验,可以说这是具有里程碑意义的,代表传统网页像单页迈向了巨大的一步,其实这个算是利用了多个综合技术实现的一个伪单页。如果想改变用户体验,但是又不想改变传统的开发模式,或者项目很难转变过来,那么尝试一下它也未尝不可,毕竟很低的成本就能获得和单页差不多的用户体验性价比还是比较高的。 看这段话: >[info] 人们对于单页系统的加载时间容忍度与Web页面不同,如果说他们愿意为购物页面的加载等待3秒,有可能会愿意为单页应用的首次加载等待5-10秒,但在此之后,各种功能的使用应当都比较流畅,所有子功能页面尽量要在1-2秒时间内切换成功,否则他们就会感觉这个系统很慢。引自:[构建单页Web应用](https://github.com/xufei/blog/issues/5) 还有一个哪儿看的记不清了,大体意思是: > 世界排名1000以内的网站几乎都是使用了jQuery,但是科技类网站使用react的占比很高,说明先进的网站使用新技术。这是未来的一个方向。 人们能感觉到这种页面的特殊性,不需要刷新,没有链接跳来跳去的,没有白屏(其实现在浏览器优化的很好了,一般不会出现白屏的糟糕体验),体验和原生应用差不多,这种页面人们愿意为它等待更多时间,因为人们知道,首次慢一点,之后的各种操作就会很快了。 虽然很多体验目前很多做得还不是很好,但这种web端全新的体验对于传统web页来说已经是迈向很大的一步了。这正是单页的魅力,未来各端的发展,设备的支持,我们有理由相信,一切都在向好的方向发展。 **关于salt-router的分析:** 这个转场用的是钉钉客户端JS-SDK,其实就是`location.href`只不过用的是钉钉的打开页面,这其实根本就不是我们web app传统意义上的转场,传统意义转场使我们在单页容器里面模拟出来的特效,salt-router这个其实利用的原生钉钉程序的特效,本质是`location.href`,所以这样就导致一个问题,那就是没有操作pushState了,每次都是重新加载页面了,呵呵,这根本就不是路由好吧!如果不是#形式,会加载页面,这根本就不是单页的套路了好吧。所以这个只能算是JS-SDK的小玩意,好流氓。 update:2017-3-1 12:40:24 * * * * * ### 参考: - [web app - 百度百科](http://baike.baidu.com/link?url=gv7Po5g36CtBFZQLzkSOXcGu4jMowR8Mn-pnccPm9jjofA0wQNRAc9c4kd40WwVrvrvpDxVj0QOGLVmZsUxaRID_dL_D6GcWfbWuXQEfG13) - [Web App 和 Native App,哪个是趋势?](https://www.zhihu.com/question/19558750) - [什么 是 Native Web App ?](https://www.zhihu.com/question/27820437) - [什么算是webapp](https://segmentfault.com/q/1010000007190832) - [为什么单页应用看起来很火,但都没有看到大厂们的产品在用?](https://segmentfault.com/q/1010000006979251?_ea=1511534) - [也许,DOM 不是答案](http://www.ruanyifeng.com/blog/2015/02/future-of-dom.html) - [还要多少年, 前端开发才能像客户端开发那样轻松?](https://www.zhihu.com/question/22426434) - [写一个页面路由转场的管理工具](http://www.kancloud.cn/xiak/quanduan/280625) - [张鑫旭大神的 mobilebone.js](https://github.com/zhangxinxu/mobilebone) > **mobile移动端,PC桌面端页面无刷新过场JS骨架,简单、专注!。** 类似于SUI,值得参考借鉴 - [Ajax保留浏览器历史的两种解决方案(Hash&Pjax)](http://mp.weixin.qq.com/s/veJNxheh7WokkuKN4JJE-Q) - [如何让搜索引擎抓取AJAX内容?](http://www.ruanyifeng.com/blog/2013/07/how_to_make_search_engines_find_ajax_content.html) - [URL的井号 - 阮一峰的网络日志](http://www.ruanyifeng.com/blog/2011/03/url_hash.html) - [HTTP 协议入门](http://www.ruanyifeng.com/blog/2016/08/http.html?hmsr=toutiao.io&utm_medium=toutiao.io&utm_source=toutiao.io) - [浏览器同源政策及其规避方法](http://www.ruanyifeng.com/blog/2016/04/same-origin-policy.html) * * * * * - [单页应用开发权威指南 - 寸志](http://island205.github.io/Single-Page-App-Break/) > [极客搜索为什么能够快如闪电](http://mp.weixin.qq.com/s/9qviaQMoyVWm3qvR-M-Zuw) 关于单页应用,推荐一本线上的电子书 [《移动端本地 H5 秒开方案探索与实现》](https://mp.weixin.qq.com/s/0OR4HJQSDq7nEFUAaX1x5A) * * * * * ### 其他 - [花样菜场](http://m.hycaichang.com/) - [浏览器加载初探](http://www.kancloud.cn/xiak/quanduan/245636) * * * * * ### 思考 其实从简单的web1.0时代到web2.0时代,网页正变得越来越复杂,越来越像一个应用,从一个不用js阶段到少量js阶段,到使用ajax广泛使用阶段,“列表-加载更多”这种其实就有点单页的雏形了,代表人们已经向不刷新页面而更新页面部分这种尝试,以及传统网页的思维转变,但是没有大规模使用,然后就是PJAX时代,可惜很短,单页框架就成熟了。 不管什么时代,什么技术,我们都是希望我们的产品能够好,不要为了设计而设计,有时候最好的不一定是最适合的,在们满足需求的时候使用最合适的才是最好的。 [h5实现iPhone横屏下的双页模式 - Addy的网络日志](http://www.iamaddy.net/2016/11/h5-iphone-two-pages/) 中就说到了技术选型,单页是最好的,但是过于复杂,时间上不允许,所以很多时候要做一些折中和妥协,最合适的才是最好的。 [webpack + gulp 在前端中的应用 - 前端拓荒 - SegmentFault](https://segmentfault.com/a/1190000005129121) 回答中也说到了 “所以有时候不要为了优化而优化”,不要忘记最终的目的我们都是为了产品更好用,更能体现出以人文本产品设计理念。 >[danger] 对于偏执狂,强迫症,处女座开说无法忍受瑕疵,只要完美。这是个很情怀的问题,但是你的情怀只是你的,用户并不会因为你的所谓情怀的而买账,以产品好用为本,以人为本,这是初心,不能忘记,否则你就活在自己错误的世界里不断徘徊、钻牛角尖,在错误的迷途上越走越远,一去不返,一黑到底,慢慢地离光明越来越远! ``` Linus Torvalds 极度热爱技术,但并不是泛 IT 技术的追随者,他从来没有写过 web 程序、不会设置 FTP 服务器的他有着很聚焦的技术关注点。Linus 的技术兴趣很挑剔,“如果我被困在一个孤岛上,唯一逃生的机会就是写出一套漂亮的 UI,那么我死定了。所以人与人是不一样的,我不是在找借口,我只是在解释。” 但是,他并不是一根筋的洁癖开源理想者,很早他就思考了商业对开源的作用;他很开心也很感激商业公司和基金会帮他处理所有那些他不愿意处理的事情,并且可以做到完全放权、不管不问。“不同的人有不同的兴趣,擅长不同的事情”。 ----------- ### 关键点: - Linus Torvalds 极度热爱技术,但并不是泛 IT 技术的追随者。 - 他有着很聚焦的技术关注点。 - 但是,他并不是一根筋的洁癖开源理想者 - 不同的人有不同的兴趣,擅长不同的事情 ``` * * * * * >[danger] 传统页面,数据和模版大都是在服务端组装的(ajax数据只是少量数据),这样数据没出来网页也就没打开。单页页面的组装在前端,后端只提供数据(当然一个着落页是必须的),这样访问页面时经常出现的就是,页面打开了,但是在等后端返回数据。 * * * * * ### 无法逾越的体验障碍 [MUI开发注意事项 - DCloud问答](http://ask.dcloud.net.cn/article/122) **始终为button按钮添加type属性** 若button按钮没有type属性,浏览器默认按照type=submit逻辑处理,这样若将没有type的button放在form表单中,点击按钮就会执行form表单提交,**页面就会刷新,用户体验极差。** **页面跳转:抛弃href跳转** 当浏览器加载一个新页面时,若页面DOM尚未渲染完毕,**页面会先显示空白**,然后等DOM渲染完毕后,再显示具体内容,这是**WEB浏览器技术无法逾越的体验障碍**;为解决这个问题,建议使用[mui.openWindow方法](http://dev.dcloud.net.cn/mui/window/#openwindow)打开一个新的webview,mui会自动监听新页面的loaded事件,若加载完毕,再自动显示新页面; 扩展阅读: * [hello mui中的无等待窗体切换是如何实现的](http://ask.dcloud.net.cn/article/106) * [提示HTML5的性能体验系列之一 避免切页白屏](http://ask.dcloud.net.cn/article/25) * * * * * ### 相关阅读 [《Web App和HTML5给Web前端带来的变化 - 我们的html5游戏平台之旅》](http://www.open-open.com/doc/view/aad511b71b6e4fe48c5db67df65dcca2) 《Web App和HTML5给Web前端带来的变化》by 曹刘阳(阿当) ![img](http://cdn.aipin100.cn/18-1-12/81610607.jpg) [DHH 谈混合移动应用开发 | | 酷 壳 - CoolShell](https://coolshell.cn/articles/12225.html) [微信 WeixinJSBridge 原理_百度搜索](https://www.baidu.com/s?ie=utf-8&f=8&rsv_bp=1&tn=baidu&wd=%E5%BE%AE%E4%BF%A1%20WeixinJSBridge%20%E5%8E%9F%E7%90%86&oq=%25E5%25BE%25AE%25E4%25BF%25A1%2520js%2520api%2520%25E5%258E%259F%25E7%2590%2586&rsv_pq=e7cfa3c300064f46&rsv_t=6cdbOFrl6IyiDj7e1DHuxfR8s%2FXl7TaUOxAlHgumWODPKprTa8DfIIur6eU&rqlang=cn&rsv_enter=1&rsv_sug3=4&rsv_n=2&rsv_sug2=0&inputT=7743&rsv_sug4=7830) [微信小程序底层的实现原理是怎样的? - 知乎](https://www.zhihu.com/question/50920642?sort=created) [微信 JSBridge 原理_百度搜索](https://www.baidu.com/s?ie=utf-8&f=8&rsv_bp=1&tn=baidu&wd=%E5%BE%AE%E4%BF%A1%20JSBridge%20%20%E5%8E%9F%E7%90%86&oq=%25E5%25BE%25AE%25E4%25BF%25A1%2520%25E8%25B0%2583%25E7%2594%25A8%2520js%2520%25E5%258E%259F%25E7%2590%2586&rsv_pq=d3e70a150005daf6&rsv_t=121awpDYouAiGSEJR3hl3%2FzU%2BF263F1%2BCwER9UXq7BQitbCIHvn9RJiM8FE&rqlang=cn&rsv_enter=0&inputT=2810&rsv_sug3=13&rsv_n=2&rsv_sug4=2816) [Android JSBridge的原理与实现 - 阿里云](https://www.aliyun.com/jiaocheng/69342.html) > 首先我们来了解一下为什么要使用JSBridge,在开发中,为了追求开发的效率以及移植的便利性,一些展示性强的页面我们会偏向于使用h5来完成,功能性强的页面我们会偏向于使用native来完成,而一旦使用了h5,为了在h5中尽可能的得到native的体验,我们native层需要暴露一些方法给js调用,比如,弹Toast提醒,弹Dialog,分享等等,有时候甚至把h5的网络请求放着native去完成,而JSBridge做得好的一个典型就是微信,微信给开发者提供了JSSDK,该SDK中暴露了很多微信native层的方法,比如支付,定位等。 [用最简单易懂的道理告诉你,为什么JavaScript在现代引擎(V8,JavaScriptCore)下,能表现出卓越性能! - 前端基础知识 - SegmentFault 思否](https://segmentfault.com/a/1190000005148418) [如何区别一个 App 是 Native App, Web App 还是 Hybrid app? - 知乎](https://www.zhihu.com/question/23622875) [移动混合开发中的 JSBridge - CSDN博客](http://blog.csdn.net/lovenjoe/article/details/78423616) > 关于 JSBridge,绝大多数同学最早遇到的是微信的 WeiXinJSBridge(现在被封装成 JSSDK),各种 Web 页面可以通过 Bridge 调用微信提供的一些原生功能,为用户提供相关的功能。 [初探微信 JSBridge · Ruby China](https://ruby-china.org/topics/28981) [微信小程序weapp的底层实现原理 - CSDN博客](http://blog.csdn.net/ListenToSennTyou/article/details/53258163) [JavaScriptCore全面解析 (上篇) - SegmentFault 思否](https://segmentfault.com/p/1210000009199944) [深挖微信小程序!你需要先了解这三个内核 - SegmentFault 思否](https://segmentfault.com/p/1210000007318105) [我所理解的前端](https://mp.weixin.qq.com/s/wa-ih9szKVZJVw2PAfCbqA) > 前端是所有端,一切端,所有的产品都会以前端的形式展现给用户(普通用户,MySQL这种产品没有界面),APP,网页,小程序,不管是以哪种方式展示,都是产品功能的对外、对用户的展现,它承载着产品的功能,所以对用户来说,**产品 = 前端**。 > > 如果把把这种关系和后端做个比喻,那就是相当于说, **后端是一个黑色的钱包,前端可以随时从钱包里面拿钱,拿到的钱可以买各种各样的东西。** 这样就形成了各式各样的产品,前端永远不会拘泥于某一种形式,而是灵活的,多种多样的。用户只关心这些买到的东西,而不关心后端钱包里面有多少钱。所以,前端是无限的,只要有足够的钱,就能满足用户的任何需求。 > 后端对用户是不可见的,前端是无形而胜有形的,是万变的,是变幻无穷的。对用户来说,前端即产品。只要后端提供了强大的接口功能支持,前端的能力是无限的,是可以做任何事情的,不会拘泥于任何东西,是无远弗届的。 [如何打造一款优秀的小程序](https://mp.weixin.qq.com/s/2G7UWNsC77lL1RlwQlu3Mw) > 前端不拘泥于任何形势,服务就是用完即走的。 [趣图:他居然在前端写业务逻辑!](https://mp.weixin.qq.com/s/NGF88yCF8SXw_jAZIIECdg) > 它能从客观上体现业务逻辑,但是它不代表业务逻辑。但它不是业务逻辑。(**严格意义上来说,前端其实做的是交互逻辑,视图逻辑,它并不直接等于业务逻辑,业务逻辑是在后端定义的。**) [什么是 Native、Web App、Hybrid、React Native 和 Weex?](https://mp.weixin.qq.com/s/62fz0kQ2udoXKnB7nCa9pA) [Vue 页面骨架屏注入实践](https://mp.weixin.qq.com/s/z2NpqjyG0OrzjD5SQh9eMw) 微博:m.weibo.cn/beta 饿了么:h5.ele.me/msite [深入wepy源码:wpy文件编译过程](https://mp.weixin.qq.com/s/xpXZEYsUfOTdywwxZ9JJbg) [小程序开发:用原生还是选框架](https://mp.weixin.qq.com/s/PjKSFR3pLjxbJnbdwDcFPg) * * * * * last update:2018-5-9 12:34:18