起点海外版 Hybrid App-内嵌页优化实践

本文作者:刘文涛

原创声明:本文为阅文前端团队 YFE 成员出品,请尊重原创,转载请联系公众号 (id: yuewen_YFE) 获取授权,并注明作者、出处和链接。

今年年初我司开启了起点品牌的海外之旅,名为「 Webnovel 」。

目前 PC / M站 / App 三端都在快速的迭代中。而其中起点海外版 App 是基于 Hybird 技术进行开发的。作为起点海外 Hybird App 中内嵌页的前端开发,从 1.0.0 版本的陌生,到最近发布的 2.0.0 版本的娴熟,海外版内嵌页的开发方式一直都在改进,力求最大程度的接近 Native App 的页面性能和用户体验。

Webnovel App 页面截图

在开始讲解起点海外版 App 中内嵌页的具体实现以及优化之前,让我们先来了解下整个 Hybird App 实现的具体方案。

一、Hybrid App 实现方案

1. 什么是 Hybrid App ?

Hybrid App(混合模式移动应用)是指介于 WebApp 、Native-App 这两者之间的 App,兼具「 Native App 良好用户交互体验的优势 」和「 Web App 跨平台开发的优势 」。

2. 为什么选择 Hybrid App

  1. Web 实现相对简单,一套代码,两端兼容;
  2. 产品还在快速迭代,变数大,而 Native App 开发,成本偏高;
  3. Web 开发时间较短,减少成本,可以应付产品的快速迭代;
  4. Hybrid App 的开发方式在公司其他项目上已经有了很好的运用,技术方案已有沉淀;

以上几点,是促使海外版 App 使用 Hybird 模式进行开发的主要原因。

二、整体架构

Hybird App 的开发方案的总体架构图

1. Hybird 实现方案

Hybird App 是使用 iOS 原生 、 Andoird 原生 、Web 页面 「 内置于 App 中的页面,既内嵌页 」一起实现的方式进行开发。

2. 完整的SDK工具

  1. 离线包:Web 页面资源以离线包的形式内嵌在 App 本地存储中。当访问页面的时候,WebView 对于本地存储的资源无须额外发起的网络请求,直接读取。而剩下的请求中,就只剩下 Ajax 拉取的 Json 动态数据,和渲染这部分数据时携带的图片资源,以及一些必要的埋点请求。这使 Web 页面即是在弱网的情况下也可以很快的打开;

  2. 完善的JSSDK:使用 JSSDK 与 App 进行交互,透明且跨平台地使用客户端的能力,形成交互闭环,给用户良好的交互体验;

  3. 离线包打包工具:自动化打包工具能快速的产出离线包。没有了人工干预,App 离线包正确性也能得以保证;

  4. 完善的热更新机制:App 客户端监测到离线包更新之后,客户端静默更新(用户无感知),解决了 Native App 页面不能补丁更新,只能发版修复 Bug 的问题;

3. 完善的后台系统平台

  1. 一键打包:内嵌页离线包打包工具可视化,实现一键打包产出离线包;

  2. 降级融灾:快速回退至之前版本,如有问题,快速下线新版本功能;

  3. 数据采集:完善的数据采集平台,通过数据分析优化用户体验;

  4. 灰度更新:支持根据配置进行灰度更新;

  5. 持续集成:系统平台目前还在持续集成当中,为提供更好的开发流程;

三、内嵌页的优化

我们起点海外 App 大部分页面都采用 Hybird 实现的,对于最大程度的接近 Native App 的页面性能和用户体验这两个点,我着重讲解下面两个部分:

  1. 内嵌页全局优化-接口页面并行加载;
  2. 详情页加载优化- localStorage ;

1. 内嵌页全局优化-接口页面并行加载

之前内嵌页的开发方式,是在 JS 中发出 Ajax 请求拉取数据,然后使用模版引擎拼接模版,插入到页面中,再由 WebView 进行页面渲染。

之前内嵌页的加载流程

从上图我们可以看到,虽然页面很快就有了占位显示,但是整个操作是串行的,需要等到 Ajax 数据返回之后才能看到页面。而这个从 WebView 到发起 Ajax 请求之间的时间是被浪费掉了的。

如果当 WebView 启动的时候就能发送当前页面的 Ajax 请求,我们的数据就可以提前拿到了,而这样从启动 WebView 到 Ajax 发请求的之间的空闲时间,就被我们利用上了。此时上面的流程就变成了如下的样子:

优化之后内嵌页的加载流程

当 WebView 启动的时候,App 根据 Url 地址获取相应的 Ajax 请求的地址,从而提前发出请求,等到页面本身请求发出的时候,拦截 Ajax 并判断是否是已经提前请求过的数据。如果是则基于提前请求的 Ajax 返回的数据渲染页面,如果不是则继续发送 Ajax,等到数据返回之后,再进行页面渲染。

上述做法,我们充分利用了 App WebView 的启动到 Ajax 发送获取数据之间的时间。接口请求与页面并行加载,加快了页面显示。

iOS 端书籍详情页加载对比结果

根据上组数据我们会发现页面显示的平均时间几乎快了 300ms 。在不影响页面正常加载流程的情况下,把串行操作变成并行操作,充分利用空余时间,大大缩短内嵌页白屏时间,让用户更快的看到了我们起点海外 App 的页面内容,效果显著。

2. 详情页加载优化- localStorage

采用接口与页面资源并行加载的方式,使内嵌页呈现的速度快了很多,但是由于海外用户区域广泛,接口加载时长的不确定,页面还是会有白屏的情况,接下来我们要做的就是特定页面,特殊处理。

再整个起点海外 App 页面中,详情页访问量相对较大,也是整个站点中比较重要的页面,所以其页面呈现的速度至关重要。因此本次迭代我们主要针对详情页做了特殊处理。

首先,我们先分析一下详情页的业务形态。书详情页数据相对比较稳定,并不会频繁变化,但接口数据返回需要时间,那我们是不是可以让书详情页的数据先本地存储,以求达到快速显示的效果,并同时发出 Ajax 接口,等到数据返回时再纠正页面上旧的数据。

关于本地存储,我们引入 localStorage 来进行本地存储,原因如下:

  1. localStorage 可以存储的数据容量大;
  2. localStorage 属于永久性存储;
  3. localStorage 目前移动端浏览器支持度良好;

详情页引入localStorage后的加载流程

从上图我们可以看到,当用户第一次访问书详情页时,localStorage 中没有相应书籍数据页面按正常逻辑显示,但这时我们会把这份数据缓存到 localStorage 中。当用户第二次访问同一本书的详情页时,我们根据 bookId 的 Key 值在 localStorage 中快速找到相应书详情页信息数据,并基于该缓存数据拼接模版,渲染页面。同时继续发出 Ajax 请求,待数据返回时,与 localStorage 的数据基于 Diff 算法进行对比。如果数据一致,则不做任何处理,不一致则页面基于新数据重新渲染,并且更新 localStorage 中的数据为新的 Ajax 返回数据。具体效果对比图如下,左边是未做二次加速的,右边是使用了二次加速的效果:

引入 localStorage 后的页面加载对比

详情页首屏所有数据包括书封显示时间

可以看到页面第一次展示的时候,依然能够明显看到占位图,但是当页面二次打开就直接呈现,效果很明显。

结尾~~

做了半年多的 Hybird 页面的前端开发,针对海外版 App 做了很多的优化,为的是给用户带来更好的体验。但对于 Hybird 技术自身的瓶颈,我们也无能为力。所以目前我们团队在尝试从 Hybird 到 React Native 的技术转型,以求能够在用户体验上更进一步。

同样延续上一次的分享:一个细节的优化是可以决定产品的好坏的,良好的用户体验,会吸引跟多的用户,获得更多的称赞。

以下是起点海外版的访问地址,请使劲戳戳戳~~~?

起点海外版 App下载:
请前往 Google play / App Store [ 美区 ] 下载

起点海外版web站:
https://www.webnovel.com

起点海外版m站:
https://m.webnovel.com

更多分享,请关注YFE:

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/366931.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

aix 卸载mysql_AIX 删除数据库及集群软件

一、 删除数据库1、用dbca自动删库在CRT上无法打开dbca图形界面,要安装一个Xmanage软件,用Xstart连接终端,并修改oracle用户的.profile,加上“export DISPLAY192.168.8.120:0.0”Xstart配置信息如下:2、手工删除数据库…

如何在github中的readme.md加入项目截图

1. 先在之前的本地项目文件夹里创建一个存放截图的文件夹。(如img文件夹) 2. 将新增的内容通过github desktop上传到github中 3. 在github中立马能看到刚刚上传的图片,打开图片,点击Download 4. 直接复制地址栏的网址 5. 最后在RE…

记表格设计规范整理与页面可视化生成工具开发

前言 公司有一个项目在维护,大概有300左右,其中表单与表格的页面占比大概百分之五六十,为了节省开发时间,避免多人协作时,出现多套冗余代码,我们尝试写了一下表单和表格的生成工具,从梳理到规范…

java仿qq空间音乐播放_完美实现仿QQ空间评论回复特效

评论回复是个很常见的东西,但是各大网站实现的方式却不尽相同。大体上有两种方式1.像优酷这种最常见,在输入框中要回复的人,这种方式下,用www.cppcns.com户可以修改。新浪微博则是在这个基础上,弹出好友菜单。这种方式…

使用签名保护基于HTTP的API

我在EMC上的一个平台上可以构建SaaS解决方案。 与越来越多的其他应用程序一样,该平台具有基于RESTful HTTP的API。 使用像JAX-RS这样的开发框架,构建这样的API相对容易。 但是, 正确构建它们并不容易。 建立基于HTTP的API的问题 问题不仅…

Python开发【模块】:Celery 分布式异步消息任务队列

前言: Celery 是一个 基于python开发的分布式异步消息任务队列,通过它可以轻松的实现任务的异步处理, 如果你的业务场景中需要用到异步任务,就可以考虑使用celery, 举几个实例场景中可用的例子: 你想对100台机器执行一…

iOS开发者的一些前端感悟

很多前端工程师会把自己比作“魔法师”,而对于JavaScript这门语言,我也想把它唤作一门“有魔力的语言”。因为这群有无限想法的人,真的在用它创造各种让你惊叹的事物。 Web三件套一、前言 几年前,笔者还是一名初涉编程的学生&…

windows下github 出现Permission denied (publickey)

github教科书传送门:http://www.liaoxuefeng.com/wiki/0013739516305929606dd18361248578c67b8067c8c017b000 再学习到"添加远程仓库"的时候遇到了 Permission denied (publickey) 这个问题, 总结来说以前的步骤如下所示: 1、git config --glo…

[UE4]嵌套Canvas

转载于:https://www.cnblogs.com/timy/p/9090642.html

写博客的这几个月,获益良多

1.前言 也将近过年了,看了那么多人搞了年会总结。自己活跃社区这几个月,改变了不少,收获也不少。就想写下这段时间写文章的一些总结,统计下‘成绩’,说下感想,就写了这篇文章。这次总结的关键词就是&#x…

shiro 权限 URL 配置细节

转载于:https://www.cnblogs.com/hwgok/p/9100277.html

2016 年崛起的 JS 项目

本文是我对中文版 risingstars2016 的整理,而本人就是中文版的译者,首发于知乎专栏 前端周刊。共 21384 字,读完需 30 分钟,速读需 5 分钟。长江后浪推前浪,如果你能花 30 分钟读完我 6 个小时翻译的内容,相…

php 开启命令模式,如何启用PhpStorm中的命令行工具

本篇文章主要给大家介绍如何使用phpstorm中的命令行工具。PhpStorm下载地址:PhpStorm使用命令行工具,我们可以直接从IDE调用命令!在我们使用任何命令行工具之前,我们必须在设置中启用它。涉及到的步骤如下:使用命令行工…

React Native项目自动化打包发布

今天这篇文章的目的是在rn项目的构建,并不会涉及到rn框架或者使用的讲解,说起构建,特别是前端构建大家应该很快会想到webpack、Grunt、 Gulp等。而这些工具在rn项目中就显得有些鸡肋。所以在此给大家分享一下不使用构建工具实现rn项目自动化打…

Python程序员之面试必回习题

写在前面 近日恰逢学生毕业季,课程后期大家“期待苦逼”的时刻莫过于每天早上内容回顾和面试题问答部分【临近毕业每天课前用40-60分钟对之前内容回顾、提问和补充,专挑班里不爱说话就的同学回答】。 期待的是可以检验自己学习的成功;苦逼的是…

SpringMVC原理MVC设计思想

什么是MVC? MVC是一种架构模式 --- 程序分层,分工合作,既相互独立,又协同工作 MVC是一种思考方式 --- 需要将什么信息展示给用户? 如何布局? 调用哪些业务逻辑? MVC流程图如下图所示: MVC核心思…

Hbase 的javaAPI基本操作用 在idea上的实现

1.保证集群开启&#xff1a; jps有如下进程 2.pom文件中的依赖 <?xml version"1.0" encoding"UTF-8"?> <project xmlns"http://maven.apache.org/POM/4.0.0"xmlns:xsi"http://www.w3.org/2001/XMLSchema-instance"xsi:sche…

旅行报告:JavaOne 2013 –重归荣耀

我已经回来几天了&#xff0c;需要赶上过去几天一直搁置的所有事情。 对我来说&#xff0c;这是一年中最忙的时间。 JavaOne和OpenWorld在旧金山的整整一周。 一个非常简短的旅行报告。 年度ACED简报 你们中许多人都知道我是Oracle社区认可计划&#xff08;称为“ ACE计划 ”&…

ElasticSearch 数据分片

一、ElasticSearch 分片 ElasticSearch集群中有许多个节点(Node)&#xff0c;每一个节点实例就是一个实例&#xff1b;数据分布在分片之间。集群的容量和性能主要取决于分片如何在节点上如何分配。将数据分片是为了提高可处理的容量和易于进行水平扩展&#xff0c;为分片做副本…

Unity3D_(游戏)2D坦克大战 像素版

2D坦克大战 像素版 游戏规则&#xff1a;  玩家通过上、下、左、右移动坦克&#xff0c;空格键发射子弹 敌人AI出身时朝向己方大本营(未防止游戏快速结束&#xff0c;心脏上方三个单位障碍物设为刚体)    当玩家被击杀次数>3  或  心脏被子弹击穿  重新加载游戏…