由于JavaScript(以下简称JS)语言的特性,前端作用域拆分一直是前端开发中的首要关卡。从简单的全局变量分配,到RequireJS实现的AMD模块方式,browserify/webpack实现的静态引用方式。前端的业务逻辑也从一个个精心按顺序排好的CSS、JS变成了入口文件为根的有向无环图。图上的节点可能是JS方法/CSS糖/.vue单文件模块。我们的开发源文件到浏览器一般经历下图的过程:

细化拆分是前端趋势,有利于代码的分割和维护。但是现有构建工具的一揽子打包过程,会造成如下性能冲突:包打大了多页面间模块文件重复下载,时间浪费,页面加载时间也变长;包小了缓存率提高,但是HTTP请求又过多,同样影响加载时间。下图为RequireJS/webpack打包后浏览器运行的文件:

要提高Web App的性能,我们需要这样的一个工具,它能实现如下特性:

1) JS按照模块拆开缓存。

2) 每次更新通过线上combo合并成一个HTTP请求。

3) 最好缓存过程和原来技术栈分离,即插即用。

结合业内其它离线化方案,我们在业务开发中推出了LsLoader.js解决缓存问题,把模块文件缓存到浏览器localStorage中,用JS控制模块文件更新与运行。

用localStorage缓存的优劣势有哪些呢?

首先优势:

1) localStorage对于移动端兼容好,主流手机浏览器、WebView都有支持,且没有iOS UIWebView的退出进程缓存失效bug。

2) 完全JS控制,前端代码不依赖宿主环境配合。

3) 弱网情况下对加载速度提升明显,3G信号较差情况下,100K的前端代码加载block页面能达到1~3秒。

4) 对比类似的Progressive Web App(PWA)和微信小程序,localStorage可应用业务线广,环境如微信/客户端WebView/浏览器,业务形式如单页/多页Web/H5活动页。

高兼容、高效率缓存就是localStorage缓存体系的核心优势。

但是localStorage也不是万能,其劣势如下:

1) 鉴于执行机制问题,append JS代码执行速度略低于script标签运行JS文件,append解析文件内容需要额外耗费时间。

2) PC环境网络条件好,模块级别更新节省的时间收益不明显,不如不用。

为了兼容各种业务线的前端构建栈,从原始的全局作用域分块,到RequireJS的AMD格式,再到现如今的webpack1/2,LsLoader采用了3层分离式设计。

3层结构包括了:

1) 前端构建层:你业务原有的gulp、webpack构建流。

2) LsLoader处理层/编译层:通过UglifyJS或者Babylon.js,分析你JS源码里的依赖关系,提取成Lsloader能识别的格式。

3) 构建结果层:一个压缩后2K的内联脚本,定义了如何缓存/加载/更新模块文件的浏览器库,支持iOS/安卓各种浏览器、WebView,对禁用localStorage的环境,写满localStorage的情况也都做了兼容。

前端构建层和LsLoader加工层互相隔离,业务代码不需要调整模块依赖方式,只需要原来构建流程的模式上在外加个转换流程即可。LsLoader转换过程会分析源码把模块文件的依赖关系归纳成数组形式,在浏览器端缓存/加载后按顺序执行。

这种设计不同于美团移动版i.meituan.com的TruckJS或者Scrat.js等构建工具,使用前面两种构建方案需要使用它的一整套构建配置,LsLoader只做一个中间件形式的构建工具,方便从你的业务代码中接入/去除。

上面的3层结构中,前端构建流程不多赘述,对应RequireJS或者webpack的文档指南。

LsLoader处理层做的工作原理图如下:

对于RequireJS构建:首先把源文件用Babylon或者Uglify处理成语法文档树,然后找到对应的define函数和参数,递归寻找去除重复引用,最后排列成按依赖顺序的模块数组。

对于webpack构建:首先把源文件用Babylon或者Uglify处理成语法文档树,遍历入口JS的import依赖,把公用依赖的JS提取成数组传给commonChunksPlugin配置,让webpack进行文件拆分。同时依赖关系传递给LsLoader前端部分,让页面按照依赖关系加载运行webpackJSONP包。

经过处理后,对应的文件列表在浏览器端以数组的方式运行/缓存,流程如下:

每个模块文件通过/combojs/注释来分割,支持各种格式的前端包裹格式如define、webpackJSONP。

宏观效果:

美团外卖红包完全加载时间从3s下降到2s,下降30%;可交互2.2s下降到1.2s,下降了45%。

美团外卖i版首页完全加载2.8s下降到1.8s。

每天静态资源加载大小为80K*450万=343G,CDN请求大小为78G,节省流量为265G。

微观效果:

线上运行示例

https://i.waimai.meituan.com/node/demo/vue

localStorage:

我们可以看到,这个页面有1个入口文件、3个依赖包,都被分别缓存在了localStorage里面,每次更新也只有一个模块文件的下载过程。

网络请求:

3个模块文件被合并成一个请求,返回结果用注释符做切割。

通用的页面,如果我们不用拆分缓存的方案,打大包的话,结果是生成一个80K的单文件。这仅仅是个简单的Vue列表,如果多页多组件应用下载浪费会更严重。

下面我再带来个复杂点的页面:

一个Vue实现的2页面切换的单页手机界面,使用LsLoader和不使用LsLoader的区别有多大?

从上图我们可以看出,这个App依赖了4个组件文件、2个类库、3个功能JS模块、总共9个包,120K。

采用单一大包,每次上线的代价是120K;使用Lsloader,每次模块级别更新,通常迭代修改影响1~2个文件,更新代价约为10K~20K。

而且这9个文件中,6个文件可以页面间公用,包括2个类库(Vue、Zepto);3个JS模块(getURLParams、historyState、WebView API)通用的逻辑函数;1个公共Vue组件(no-data.vue)兜底页面的组件。

这些模块在用户打开此页面后同域名其他引用模块的页面也得到了提前加速页面的效果。开发保证逻辑清晰的同时也提升了整站的性能。

由于有着对各种Web构建的天生兼容,LsLoader可以自己定制扩展附加功能。比如单页应用的按需分割加载/缓存的支持。在Hybird开发中,我们可以把关键页面的资源列表生成个预加载的空页面,让客户端进入后提前打开隐藏的WebView加载这个页面,利用localStorage缓存实现预加载静态资源提升首屏H5的预加载功能。

环宇,美团外卖高级前端研发工程师。2016年加入美团外卖,负责外卖i版、外卖红包页、外卖客户端Hybird页面等用户端页面开发。对组件化开发、页面提速、页面体验提升等较为关注。主导了外卖H5页面从gulp+Requirejs到webpack 2+Vue 2+LsLoader技术栈的一步步升级迁移。希望用最小的开发代价来解决业务线性能问题,把最便捷的方案和同行分享。

LsLoader——通用移动端Web App离线化方案相关推荐

  1. 【饿了么】—— Vue2.0高仿饿了么核心模块移动端Web App项目爬坑(一)

    [饿了么]-- Vue2.0高仿饿了么核心模块&移动端Web App项目爬坑(一) 前言:学习Vue.js高仿饿了么课程过程中,总结了这个Web App项目从准备到开发完毕自己觉得很重要的知识 ...

  2. Vue2.0高仿饿了么核心模块移动端Web App项目爬坑(一)

    原文https://www.cnblogs.com/ljq66/p/9980372.html 前言:学习Vue.js高仿饿了么课程过程中,总结了这个Web App项目从准备到开发完毕自己觉得很重要的知 ...

  3. [译]介绍一下渐进式 Web App(离线) - Part 1

    Web开发多年来有了显著的发展.它允许开发人员部署网站或Web应用程序并在数分钟内为全球数百万人服务.只需一个浏览器,用户可以输入URL就可以访问Web应用程序了.随着 Progressive Web ...

  4. SAP 基于VUE的BSP OO单页移动端Web App开发

    前言 之前的一篇文章,通过传统的Page with Flow Logic形式去实现了基于Vue的One Page Application.这种做法其实存在一些设计上的问题,前端页面交互层还好说,但后端 ...

  5. 美团App插件化实践

    点击上方"公众号"可以订阅哦 背景 在Android开发行业里,插件化已经不是一门新鲜的技术了,在稍大的平台型App上早已是标配.进入2017年,Atlas.Replugin.Vi ...

  6. vue音乐笔记_基于vue全家桶的移动端音乐web app

    项目描述 这是一个基于 Vue2.x 和网易云音乐 API制作的移动端 web app 项目:由于是出于练习和实验的目的,因此并非是网易云音乐 app 的替代品,目前也没有涵盖全部的功能: 该项目主要 ...

  7. 清除浏览器缓存之后为什么还是显示旧的html页面_H5缓存机制浅析-移动端Web加载性能优化...

    1 H5缓存机制介绍 H5,即HTML5,是新一代的HTML标准,加入很多新的特性.离线存储(也可称为缓存机制)是其中一个非常重要的特性.H5引入的离线存储,这意味着 web 应用可进行缓存,并可在没 ...

  8. 从 SPA 到 PWA:Web App的下一站在哪?

    从AJAX(Asynchronous JavaScript + XML,异步JavaScript和XML)开始, 尤其是 AngularJS 推出之后,SPA(Single Page App,单页应用 ...

  9. H5缓存机制浅析-移动端Web加载性能优化

    1 H5缓存机制介绍 H5,即HTML5,是新一代的HTML标准,加入很多新的特性.离线存储(也可称为缓存机制)是其中一个非常重要的特性.H5引入的离线存储,这意味着 web 应用可进行缓存,并可在没 ...

最新文章

  1. 神经网络的学习方式网络传播和图卷积,两者到底什么关系?
  2. Linux 查看文件大小
  3. java做猜价格游戏,用java做的猜数游戏!
  4. MySQL主从原理,基于快速学习一门技术的3种方式!
  5. 降维(二)----Laplacian Eigenmaps
  6. Visio studio 2019中opencv 4.1.1运行环境配置(亲测可用)
  7. 计划订单号码范围用完导致MRP无法运行
  8. Python项目之我的第一个爬虫----爬取豆瓣图书网,统计图书数量
  9. unity fixedupdate_3D俯视角射击——用Unity还原东方弹幕(上)
  10. 支付宝支付-支付宝PC端扫码支付
  11. aws php sns,PHP中的AWS SNS HTTP订阅确认
  12. 使用jxls导出报错:Connot load XLS transformer please make sure a Transformer implementation is in classpath
  13. linux下搜狗输入法wps无法使用,搜狗输入法能在WPS下使用,但其他地方不能输入...
  14. android 嵌套分组拖动_Android ExpandableListView双层嵌套实现三级树形菜单
  15. linux系统防火墙关闭22端口,Linux系统防火墙关闭及端口开放
  16. Spring Cloud Alibaba - 27 Gateway源码解析
  17. 约书亚·布洛赫(Joshua Bloch):Bumper-Sticker API设计
  18. 安装VLC媒体播放器
  19. linux虚拟机中通过挂载iso文件安装jdk
  20. 今日头条创始人张一鸣:独特定位是我们的优势

热门文章

  1. Win8下右键“发送到”没有蓝牙选项的解决办法
  2. iOS 6 的5个新特性创建杀手级应用
  3. 看看高手做的ARM开发板
  4. 单片机的引脚,你都清楚吗?
  5. 哇、、、、C++ 实现单向链表
  6. 【速来抢】iPhone12、STM32开发板、1024元现金红包…打包免费送!!!
  7. 计算机语言学 自然语言处理程序,利用知网进行(计算机)自然语言处理
  8. mysql存储过程触发器游标_MySQL存储过程,触发器,游标
  9. PackagesNotFoundError: The following packages are not available from current channels:
  10. 三、Express 路由