前端爱好者的知识盛宴
本期推文的作者为sunderls,Line漫画的Javascript开发。
Line漫画是来自日本的火爆漫画软件,提供了流畅的漫画阅读体验。
本文将介绍如何通过Page Stack实现流畅的页面切换。
如果有任何问题欢迎留言评论。
如果你觉得IMWeb有用,欢迎转发。
请关注我,我是你的IMWeb。
下面由sunderls开讲!
写在前面
大家好,我是再LINE漫画做JavaScript开发的@sunderls。
在LINE中可以直接看漫画了,大家注意到了吗?
点击「···」> 「LINEマンガ」之后,就可以流畅的看免费漫画了
这里的画面,实际上用的是web技术。画面切换的时候,个人觉得和原生app一样的流畅,大家觉得是这样的吗? 这里是如何做到的,接下来简单的介绍一下。
Web页面的问题
想必大家平时都使用React或者Vue进行前端开发。
也许会觉得Router中加入Transition的话不就能实现上述效果了么。
确实,简单的组合的话确实会顺利显示页面切换动画,但是如果要让动画流畅,就会有以下一些课题:
「后退」按钮点击时的延迟
这是因为Router默认是对dom进行替换操作。LINE漫画的首页很长而且复杂,所以后退到首页的话会非常容易感觉到延迟。但是由于这是运行在LINE内部的应用,所以必须尽量让用户感觉不到违和感。
后退后没有恢复到上次的滚动位置
SPA应用中经常遇到这种问题。虽然可以通过JavaScript暂存滚动位置进行恢复,但是这种实现并不简单,很容易产生页面的上下跳动等不流畅的问题。另外除了垂直滚动位置之外,滚动图等水平方向上的滚动,以及无限加载等情况也会存在,这样以来JavaScript的逻辑会变得越来越复杂。
懒加载的图片会重新加载
图片在滚动到可显示位置时才予以加载,除此之外用一个placeholder来占位 - 这是一种常见的优化手段。但是在页面后退的时候,图片会重新现实一次,有些违和。
这些问题用一句话总结一下就是「在页面后退的时候,之前页面中因为滚动・点击等用户行为所产生的DOM变化如何重现」
参考IOS的实现
为了看起来像原生app,那么我们最好参考一下原生app的实现。
来看看iOS的UINavigationController:
图片出处: https://developer.apple.com/documentation/uikit/uinavigationcontroller
UINavigationController通过Navigation Stack来管理View controller,对View进行push/pop:
如果用相同的Stack方法来组装页面的话,页面跳转时将不会发生dom替换,前面提到的问题感觉能够全部解决,所以LINE漫画就直接采用了类似的实现方法,称之为Page Stack。
Page Stack的实现
HTML结构
LINE漫画采用了以下页面结构。PageStack中放置各个页面。 (顺便说一下Modal的也是通过Stack进行管理)
接下来说明下JavasScript的实现(以React和react-router为例,部分代码省略)
PageStack的实现
作为wrapper的page
作为helper的withStack
这样基本上一个stack的实现就完成了,最后来看一下使用方法。
使用示例代码
实现效果
实现Page Stack后,页面切换变得非常流畅。
慢慢滑动也是一样
写在最后
为了实现流畅的操作体验,LINE漫画做了很多很多的尝试,其中的基础就是Page Stack。
大家觉得怎么样?如果可以的话,可以在LINE中尝试一下LINE漫画看看实际效果。
本文摘自https://engineering.linecorp.com/ja/blog/detail/200
欢迎关注IMWeb!