html5手机Web单页应用实践--起点移动阅读
一开始以hybrid形式做了一个android的小说阅读客户端,叫4G阅读。而后由于业务需求,要迅速实现纯手机html5 版的,所以就直接在原先客户端内内嵌的网页进行改版,快速实现以后在优化的过程中发现越改越多越改越多…
注意此web应用只支持android及iphone内的浏览器,及PC或mac上的chrome,safari,firefox等支持html5的浏览器。IE10以上浏览器
这算是试验版了吧,以前没这么弄过..
手机访问http://crapi.4gshu.com:8096/4g-read-qd/#index
先上图,有图有真像
文件结构及路由
HTML
Index.html
整个应用框架的基础,包含了头部,尾部HTML,及主要各个页面部分的容器(content-panel)
根据hash路由通过ajax方式加载对应的内容页再添加到对应的comtent-panel内
以下是主要内容模块(内容为html片段)
Index-c.html逛
Category-c.html分类
Rank-c.htm排行
Discovery-c.html发现
Channel-c.html男频,女频...
Search-c.html搜索
Bookshelf-c.html书架
Catalog-c.html 目录
CSS
编写css时使用了less,特别是在修改时,尤其的好用
Public.css 包含了大部分的应用样式
Idangerous.swiper.css 切换插件的样式文件
内容页的样式可以在自身页面内自行添加
Javascript
Avalon.js
在此处用这个MV*框架,主要是方便处理将json数据渲染到DOM上
Jquery.js
很想使用zepto之类的轻DOM框架,但最终还是选择了jquery2.0,原因是方便扩展插件,很多插件不兼容zepto,其实JS文件的大小远没有你想象的那么影响web应用的表现,其实css的渲染影响更大,血的教训啊。关于JS文件过大的问题,其实应用基本上是在3G或wifi情况下使用,你非要在2G环境下使用,那干麻不用WAP版...
Idangerous.swiper.js
非常强大的轮播插件,其实可以实现很多东西。所以选用它来实现轮播
Mango-decoupling.js
很好用的消息插件,用于程序中解耦设计,其消息机制也非常强大
Config.js
由于将这个应用分发到不同的渠道,而不同渠道又有一些不同的配置需求,所以用了config.js来配置一些属性
Core.js
整个框架通用JS的核心,包含了本地储存,通信,通用的事件与方法
为了方便实现,及减少JS文件数,各个内容模块的JS业务逻辑都直接写在各自的html片段中。内容模块在渲染完毕后应该向框架发送一个渲染完毕的消息,或执行框架提开放的渲染完毕API,比如“page_ready”,方便框架处理loading等全局的控制
本地存储
1、离线存储cloudary.appcache,尽可能的将css,js,image,及HTML代码片段文件都离线存储至本地。初次访问时会将所有相关文件都离线到本地,以后再次访问,会优先读取离线到本地的文件
2、Localstorage存储接口数据。开发过程中明显感觉到,后台提供的数据接口的速度明显影响了整个应用的表现,所以在初次访问动态数据接口时将使用localstorage将整个接口返回的数据存储到本地,以后再次访问时先优先读取本地的数据,然后后台会静默更新数据到localstorage内,由于应用没有那么高的实时性要求,所以此方案可行。
Hash路由
整个应用的内容模块content-panel其实是由hash路由来连起来的,构成了所谓的单面应用,即不刷新整个页面。一开始使用的是popstate来实现,结果发现在chrome浏览器下一进页面就会触发一次popstate事件,比较奇葩,这个问题是在应用完成后发现的,还好popstate事件是在core.js中进行过封装的,我就在封装处将popstate事件替换成了hashchange事件,所以说对外部的API还是要抱有不信任的态度,尽量进行封装分隔,万一发生改变,改起来也快。在加载不同的内容模块时,通过wndow.history的pushState和replaceState来实现hash值的改变,在一进页面时首先得把自身页面进行一次replaceState,将自身加入history队列,否则history队列会乱(一大坑啊,反正我以前没replaceState时是遇到过,怎么也管理不好队列)。
根据UI上的设计及功能的不同,我将路由分成了两类,
主页路由:
Index 逛
Category分类
Rank 排行
Discovery 发现
子页路由:
Channel频道
category-detail 分类详情
Topic 专题
Detail 详情
Search 搜索
Bookshelf 书架
Catalog 目录
关于路由的速度优化
1、很多内容模块打开过一次后再次打开时完全是不用再请求的,所以得判断是否打开过,打开过的应用再次打开时就不再请求对应的html片段了,直接显示之前请求下来的html片段,比如index,category,rank,discovery,topic,bookshelf,search这几个内容模块
2、对于需要更新内容的模块,比如detail,channel模块,第一次请求到html片段后也可以缓存下来,以后每次请求新的内容时只需要通过JSON数据更新dom即可,即无需把dom清掉再重新创建新dom。这一点的优化对于性能比较差的mobile设备上尤其重要,这样实现后,请求数据这个动作需要在路由发生变化时发送自定义消息(如:refresh_with_new_data),接受到自定义消息时再发送数据请求,得到消息后再更新dom的内容。
3、即使对于需要更新的内容,同一个链接,连续被打开时,由于数据完全没有变化,所以也可以完全不去请求数据,即可做到所谓的“秒开”
理论上应该用但并未使用的技术
1、backbone,算是比较广泛的mvc框架了,自身提供了路由功能,但个人觉得需要写的代码量太大,如果是团队使用用来规范代码还行,如果个人使用的话,我觉得还是太重了。写一个简单的功能就一大堆代码及对应的JS文件。
2、Requirejs或seajs
本身应用中就首页这几个JS文件,写完就没了,没必要再多一个额外的JS文件请求
3、一些新的CSS3属性
某些比较好用的CSS3属性在移动端支持有限,所以没有使用,比如布局的两端对齐
4、较高的内容模块分段显示,即滚动到了后再渲染到DOM中,首先后台并未提供分断加载的API,其次,自适应的布局加大了实现的难度,最后,木有足够的时间
不足
1、开发时间过短,很多公司的通病吧
2、产品在设计时未考虑单页应用的场景,层级太深的页现在还是刷新整个页面
3、有些功能还未按以上的构架实现,比如动态接口本地存储只做了index首页等
4、比较丑,样子丑,代码实现也比胶水
No zuo no die
为何在内容模块切换过程中未添加一些像native应用切换一样的动画效果?
由于android的机型无花八门,性能参差不齐,css3动画支持力度不一,很多hybrid应用的出现正是为了弥补这样的缺点。布局用html,切换动画使用native。如果你的web应用只要求跑在iphone这等高大上的设备上的话,完全可以使用css3来实现界面切换动画,如果你要求跑在所有平台上,那么......该吃药了亲..
如果你非要尝试,那么你应该会体会到什么叫no zuo no die
结束语
优化工作是个系统性工程,得从方方面面考虑,从产品设计--》UI设计--》前端代码实现--》后台数据接口提供
现在的优化只能算是皮毛吧,不仅前端部分需要优化,而且后台数据接口速度过慢也严重导致了响应速度。
纯粹的手机web单页应用本来就做的比较少,经验太少,需要继续努力学习..
码农啊...
有看到这篇文章的同学欢迎提意见,优化方面特别是
========================================================
转载处请注明:博客园(王二狗)willian12345@126.com
html5手机Web单页应用实践--起点移动阅读的更多相关文章
- web单页应用是什么?它的好处与坏处有哪些(如何解决这些缺点)
web单页应用是什么? Web单页应用就是指只有一个Web页面作为入口的应用,在浏览器中运行期间不会重新加载页面.也就是说浏览器一开始会加载它必需的thml.css和Js,之后所有的交互操作都在一个页 ...
- 高效开发 Web 单页应用解决方案
于 2017 年初,有在 Github 建立并维护一个项目:Vue Boilerplate Template,欲成就一款开箱即用 Vue + Webpack 的脚手架模版:其目标与宗旨是:根据以往经验 ...
- 移动Web单页应用开发实践——实现Pull to Request(上/下拉请求操作)
在单页应用开发中,无论是页面结构化,还是Pull to Request,都离不开一个技术——页面局部滚动.当下的移动web技术,主要使用下面两种方式实现局部区域的滚动: 基于IScroll组件,也有很 ...
- 【转】移动Web单页应用开发实践——页面结构化
1. 前言 在开发面向现代智能手机的移动Web应用的时候,无法避免一个事实,就是需要开发单页应用(Single Page WebApp).对于不同的系统需求,单页应用的粒度会不同,可能是整个系统都使用 ...
- 移动Web单页应用开发实践——页面结构化
1. 前言 在开发面向现代智能手机的移动Web应用的时候,无法避免一个事实,就是需要开发单页应用(Single Page WebApp).对于不同的系统需求,单页应用的粒度会不同,可能是整个系统都使用 ...
- 使用require.js和backbone实现简单单页应用实践
前言 最近的任务是重做公司的触屏版,于是再园子里各种逛,想找个合适的框架做成Web App.看到了叶大(http://www.cnblogs.com/yexiaochai/)对backbone的描述和 ...
- web单页应用(1)--第一个SPA
<!doctype html> <html> <head> <title>第一个SPA</title> <style type=&qu ...
- html5手机web app <input type="file" > 只调用图库,禁止调用摄像头?
<input type="file" accept="image/*"><input type="file" accept ...
- html5手机web页面底部菜单
一.效果图 二.HTML代码 <header class="text-center">TOP</header> <div id="conte ...
随机推荐
- Privoxy
Privoxy 前沿: 这个玩意我以前都没听说过,今天在别人的帮助下试了试,只想说:谁还能阻挡我,我就是要USA....ps:在此感谢每一个帮助我的人 介绍: Privoxy是一款带过滤功能的代理服务 ...
- Delphi实现ERP单据列表栏目设置
什么都不用说了,ERP你懂的.一张报表,不同的客户都可以调死你.直接上图 通过这个设置界面,直接生成参数调整报表所用的DBGridEh.对,是DBGridEh,不是DBGrid,也不是CXGrid. ...
- wpf下使用NotifyIcon
以前在winForm下使用过NotifyIcon,到wpf找不到了,在wpf下还是直接用WinForm里的那个NotifyIcon实现最小到系统托盘 定义一个NotifyIcon成员 : Notify ...
- hdu 6400 Parentheses Matrix
题目链接 Problem Description A parentheses matrix is a matrix where every element is either '(' or ')'. ...
- sql语句左链接left join--3张表关联
表A---------------------------------关联第一张表B-----------------------关联第二张表c select * fomr 表名A left join ...
- 关于slow http attack以及apche tomcat的应对方式
HTTP 的 Slow Attack 有着悠久历史的 HTTP DOS 攻击方式,最早大约追溯到 5 年前,按理说早该修复了,但是 Apache 的默认配置中仍然没有添加相关配置,或者他们认为这是 f ...
- BZOJ4922 Karp-de-Chant Number(贪心+动态规划)
首先将每个括号序列转化为三元组(ai,bi,ci),其中ai为左括号-右括号数量,bi为前缀最小左括号-右括号数,ci为序列长度.问题变为在满足Σai=0,bi+Σaj>=0 (j<i)的 ...
- 【BZOJ1458】【洛谷4311】士兵占领(网络流)
[BZOJ1458][洛谷4311]士兵占领(网络流) 题面 BZOJ权限题,洛谷真好 Description 有一个M * N的棋盘,有的格子是障碍.现在你要选择一些格子来放置一些士兵,一个格子里最 ...
- Zookeeper(一) zookeeper基础使用
一.Zookeeper是什么 (安装的是3.4.7) ZooKeeper 是一个分布式的,开放源码的分布式应用程序协调服务,是 Google 的 Chubby 一个开源的实现.它提供了简单原始的功能, ...
- python创建多维列表
By francis_hao Mar 24,2018 "*"操作符可以用于列表,表示将列表内容重复n次.如下, 但是当列表内容是列表的时候就出问题了,如果我只是修改多 ...