标签: TODO 前端


本文针对目前的移动端方案做基本的研究。包括: 技术栈,兼容性,优劣势,市场情况,周边生态。
当然其中也会涉及如: Vue, React 等的相互比较。

待完成!!!目前只有对每种方案都做具体实践,完成一定程度的应用编写才能体会到优劣。

移动端 web 发展

  • web 端固有优势

    • 在线
    • 及时升级
    • 多路径快速分发
    • 一次开发,多平台可用
  • 缺陷

    • 用户体验差, 相交于 Native
      • 首屏
      • 动画
    • 用户留存率低
  • 原生渲染为何比webview渲染快?

    • native: view->layout->renderNode ->合成->GPU渲染
    • webview: html->dom tree ->render tree ->render layer + 栅格化 ->合成->gpu渲染。

PWA

PWA是使用许多特定技术和标准模式开发的Web应用程序,可让他们利用Web和本机应用程序功能。PWA不依赖于单个API,而是使用各种技术来实现尽可能提供最佳网络体验的目标,不只是技术,更是一种开发理念。

国内情况:受限于手机厂商和浏览器厂商。

  • 国内较重视 iOS,而 iOS 目前还不支持 PWA。
  • 国内的 Android 实为「安卓」,不自带 Chrome 是一,可能还会有其他兼容问题。
  • 国内厂商可能并不会像三星那样对推动自家浏览器支持 PWA 那么感兴趣。
  • 依赖 GCM 推送的通知不可用,Web Push Protocol 还没有国内的推送服务实现。
  • 国内 webview 环境较为复杂(比如微信),黑科技比较多。

总结一下,PWA的对于Web App带来的影响:

  • 体验层面向原生App靠拢:离线可用,主屏图标入口,启动动画,基本上可以和原生 App的体验一致;
  • 开发模式的变革:Web开发同时考虑离线模式和体验;
  • App的安装更新机制带来运营方式的变化:url可达,应用间可链接,不仅仅依赖商场分发应用。

参考:

关键原则

  • 可发现
  • 可安装
  • 可连接
  • 网络独立
  • 渐进增强
  • 再参与
  • 响应式
  • 安全

技术点

列举下想关联的实际技术点,考虑工程化的设置。

Service workers

Service Worker 是一个特殊的 Web Worker,独立于页面主线程运行,它能够拦截和处理网络请求,并且配合 Cache Storage API,开发者可以自由的对页面发送的 HTTP 请求进行管理

  • 浏览器和网络之间的虚拟代理,主要用来解决离线装填下的缓存问题
  • 运行在一个独立的线程中,无阻塞
  • 不能获取实际的 DOM 结构
  • 在不同的上下文中进行双向的交流
  • 还有: 处理 notification、密集计算

下载.webp-20kB
sw-lifecycle.png-50.8kB

参考:

APP shell

应用程序的shell是为渐进式Web应用程序的用户界面提供动力所需的最小HTML,CSS和JavaScript,并且是确保可靠的良好性能的组件之一。它的第一个负载应该非常快,并立即缓存。“缓存”表示shell文件通过网络加载一次,然后保存到本地设备。每当用户打开应用程序时,shell文件都会从本地设备的缓存中加载,从而实现快速启动。

简单讲就是应用的基础骨架。

https://codelabs.developers.google.com/codelabs/your-first-pwapp/#2

Installable

应用可安装需要具备以下条件:

  • manifest file
    • <link rel="manifest" href="/manifest.webmanifest"> 手动部署和设置
    • 所有可配置的选项参考列表
    • 通过 name, background_color, icon 自动生成启动页(Splash screen)
      • 启动页没法完全自定义有点可惜
  • HTTPS
  • 用于设备上呈现的图标
  • A service worker registered, to make the app work offline (this is only required by Chrome for Android currently)

工程化:

  • [x] 需要
  • [x] 可以完成图形界面的工程化设置

缓存

cache 强大的缓存能力和接口。

  • 缓存文件
  • 缓存请求的数据

工程化:

  • [x] 文件类缓存可以工程化解决
  • [ ] 请求的数据需要在代码中解决,工程化可能性低

参考:

HTTPS 支持

SW 需要在 HTTPS 下运行。本地 localhost 也可运行。

API

这里说 API 指可以直接使用的,不用考虑工程化上的配置。

兼容性

浏览器对于 PWA 的各种特性支持。目前兼容性只是一个大概的范围,国内 ROM 厂商的定制化修改只是逐一实机测试。

  • manifest
  • app shell
    • 使用 SW 缓存数据,兼容性与 SW 保持一致
  • service work
  • Notification
    • IOS
      • 不支持
    • android
      • webview: 4.4 部分支持
      • chrome: 不支持
      • UC 不支持
  • Push API
    • 支持 Web Push 的成本比 App Manifest 或者 Service Worker 要高的多,它需要浏览器厂商提供消息推送服务。国内只有 UC 即将发布的 U2 内核的浏览器才支持 Web Push API,Chrome 也因为其依赖的 FCM/GCM 无法访问而导致 Web Push 无法使用。

实机测试:

  • 魅族: android 7.1.1
    • 自带浏览器: 不支持 manifest, 不支持 nofitication , 不支持 SW
    • chrome64: 支持
      • 安装提示, 桌面创建
      • 启动页 icon 和 bg 设置
      • 应用展示 display

实例参考

解决方案


React Native

用同一门语言(Javascript),同样的高层架构(Virtual DOM)和设计模式(component-based),针对不同平台分别作出最佳的用户体验。不追求一次编写,全平台运行。

cfb59019fd8ca0eca353fdbcdfe22bcc_hd.jpg-16.1kB
Learn once, write anywhere

image.png-88.8kB

React Native 整个架构分为: JS - Bridge - Native

Native:

  • 运行在主线程上(可能会有些独立的后台线程处理运算,当前讨论中可忽略)
  • iOS平台上运行Object-C/Swift代码,Android平台上运行Java/Kotlin代码
  • 负责处理UI的渲染,事件响应。

JS:

  • 运行在JS引擎的JS线程上
  • 运行JS代码
  • 负责处理业务逻辑,还包括了应该显示哪个界面,以及如何给页面加样式。

Bridge:

  • JS 和 Native 不能直接通信, Bridge做序列化和反序列化,查找模块,调用模块等各种逻辑.

参考 :

教程:

工具:

优劣

React Native的优势:相对Hybird app或者Webapp:

  • 不用Webview,彻底摆脱了Webview让人不爽的交互和性能问题
  • 有较强的扩展性,这是因为Native端提供的是基本控件,JS可以自由组合使用
  • 可以直接使用Native原生的「牛逼」动画(在FB Group这个app里面,面板滑出带一点果冻弹动,面板基于某个点展开这种动画随处可见,这种动画用Native code来做小菜一碟,但是用Web来做就难上加难)。

相对于Native app:

  • 可以通过更新远端JS,直接更新app,不过这快成为各家大型Native app的标配了…

劣势:

  • 扩展性仍然远远不如web,也远远不如直接写Native code
  • 从Native到Web,要做很多概念转换,势必造成双方都要妥协。最终web要用一套CSS的阉割版,Native要费劲地把这个阉割版转换成native原生的表达方式(比如iOS的Constraint\origin\Center等属性)

实践

https://github.com/facebook/yoga

布局

布局方案:

样式

React-Native 的样式基本上是实现了 CSS 的一个子集,并且属性名不完全一致,所以当你开始在编写 React-Native 之前,可以先简要了解一下

实际编写应用时,RN 会对属性和属性值进行验证,意味着可以及时报错。这点很好。

对于目前 RN 的 CSS 方案需要研究下。

react-navigation

react-navigation 这个组件实在太强大。

事件

  • 触摸事件
  • 事件流程

调试参考

图片请求本地地址时,必须时静态地址(在编译时就要确定地址)。这个没问题,但是按照使用二目运算符,后面的总是替换前面的,地址不生效。

    let halfRating = null;
    if (ratings <= 0.25) {
      halfRating = require('./star-empty.png')
    } else if (ratings >= 0.75) {
      halfRating = require('./star-solid.png')
    } else {
      halfRating = require('./star-half.png')
    }
    
    // halfRating 总是 require('./star-solid.png'), 这就是问题了。

Weex

Weex 的结构是解耦的,渲染引擎与语法层是分开的,也不依赖任何特定的前端框架,目前主要支持 Vue.js 和 Rax 这两个前端框架。官网介绍也只是一个 SDK。

核心理念:Write Once, Run Everywhere

Weex 只做简单介绍,目前最大的优势就是只写一次,这个理念其实对于大部分前端来说,是非常喜欢的。但其实需要对 iOS Android 原生开发有足够的了解,而对比 RN 只需在使用的地方了解下即可。这种理念下的话,性能和RN 是有一定差距。

当然 Weex 目前只是一个 SDK。可能是与阿里业务相对应,毕竟阿里系APP 不可能完全重构,但是可以以单页的形式集成到现有的 App 中。

v2-fb43dc68aab3b7a31ebeda90c1dea5f4_hd.jpg-24.9kB

另外,上面即使说了, write once: 但是比如图片下载,就需要写 android 和 iOS 两份。

发布

应用打包和发布的坑也比较多,涉及太多不复述。


小程序

  • 视图层和逻辑层分离,通过数据驱动,事件交互,不直接操作DOM

  • 视图层负责渲染页面结构,逻辑层负责逻辑处理、数据请求、接口调用等

  • 视图层与逻辑层通过数据和事件进行通信,逻辑层提供数据给视图层,视图层通过绑定/捕获事件发起交互让逻辑层处理
    视图使用WebView渲染,JS由JSCore(IOS)/X5(Android)/nwjs(DevTool)渲染解析
    JSBridge下架起上层开发与Native(系统层)的桥梁,使得小程序可通过API使用原生的功能,且部分组件为原生组件实现,从而有良好体验

  • 资源参考

  • 技术架构

  • 完整参考

  • 小程序和 weex 的完整对比

    • 构建
    • 设计指南
    • 应用接入
    • 数据
    • 开发者社区
    • IDE 集成开发环境
    • 生命周期
    • 页面跳转
    • 数据绑定
    • 列表渲染: (这条主要与性能有很大相关性)
    • 条件渲染
    • 样式
    • 组件

快应用

快应用技术架构与 weex 类似,不过是由底层手机厂商支持。

快应用是js,但不是网页,是v8+原生渲染引擎。如果你了解react native的话,快应用和react native是类似的。体验方面比pwa好很多倍。另外手机厂商会提供push,pwa的push在国内没法用。包括原生应用的push,在国内目前也都在被手机厂商控制,想要正常push,还得用手机厂商的服务。

流程:

  • 注册快应用联盟帐号
    在快应用官网申请开发者资质
  • 绑定各厂商开发者帐号
    与品牌厂商开发者帐号绑定
    一站式上架多厂商全平台入口
  • 开发快应用
    快应用官网提供开发者文档
    同时提供开发环境和必要的开发工具
  • 发布快应用
    将应用上传至快应用官网
    测试并审核后进行分发

优势:

  • 因为由厂商(小米等)直接引导、推广,在系统平台上拥有足够的支持,各类系统接口、服务完善, 也可以轻松实现和原生应用一样的功能逻辑。
  • 轻量化、免安装的模式使得不管是新用户想要体验,还是老用户想要快速点餐,都可以在很短的时间内,以极低的成本快速点餐。
  • 与厂商系统平台的紧密结合使得新应用成为原生应用、Web 应用之外一个有效、可靠的流量渠道。

实例与测试:


Hybrid 方案

  • cordova
    当中主要有3者协同工作,一个native runtime,一个js bridge,一个web view
    js bridgewebview 封装了一堆native api供调用。当你只想跑一个普普通通的网页的时候,webview提供的那些浏览器js api就够用了,你调用它们,就只和web view打交道。而如果你要调用cordova给你封装的那一堆扩展的api,这些调用就最终落实到native runtime上面来实现。

  • 设计理念。React Native 的口号是 'Learn once, write anywhere',这不同于一般的旨在跨平台的框架。这意味着我们不能简单的将代码直接运行在不同平台,而 Cordova 则是希望尽可能的重用代码。

  • 开发自由度。首先 Cordova 构建的是一个运行于手机内置浏览器中的单页 Web 应用,因此理论上我们能够使用 jQuery,Angular 等等任何 Web 技术,而 React Native 则有自己的技术栈。

  • 界面表现。Cordova 应用因为本质上是一个 Web 应用,因此某些地方会显得有些怪怪的。比如,列表滚动不像原生那么流畅,点击效果也缺少反馈。当然如果我们想让 Cordova 应用尽可能像原生应用的话,这些问题都是可以解决的,但也意味着我们需要付出额外的努力,而 React Native 在这方面就要好得多了。

  • 性能方面。Cordova 应用的性能很大程度上局限于运行它手机的 WebView 性能。比如,在 iOS 上,同一个 Web 应用,运行在默认 WebView 引擎上要明显慢于运行于 Safari 中。而 Android 也是在 4.0 之后 WebView 才换成了 Chrome 内核,因此,在老旧的 Android 机型上 Cordova 的表现会非常糟糕。进一步,由于 JavaScript 是单线程的,如果我们的 Cordova 应用同时做了很多事情,那可能就会遇到麻烦。React Native 则利用了多线程,因此 UI 渲染能够运行在独立的线程中。

  • cordova和react-native 底层的实现思路的区别是什么?

  • RN 和 cordova 对比

  • https://www.toptal.com/mobile/comparing-react-native-to-cordova

其他方案