Open
Description
系列说明
嗯,要想成为一个专业的前端,不懂交互动画可不行。所以借着做项目,顺便好好研究一下这个方向,希望能给团队带来一些提升。
本篇要解决的问题
如果你用react+webpack做过单页面应用,那么你一定遇到过bundle.js太大导致首次加载时白屏时间过长,解决办法有几个方向。
- 从较少bundle.js体积大小入手
- 从服务端渲染入手
- 从加载中动画入手
首次尝试
一开始我是这么想的:既然bundle.js还没加载完,那么我就把动画的DOM和CSS写在index.html里面就好了。
// index.html
<style>
// 加载中的动画样式
</style>
<div id='root'>
// 添加一些加载中的动画DOM元素
</div>
结果:
- 在bundle.js加载完成之前确实会显示动画。
- 但是,一旦bundle.js加载完成,动画会瞬间消失,毫无过渡。
究其原因,无非是react在首次渲染真实DOM元素之前,会清空root里面的DOM元素。
再次尝试
找到原因之后我转换了一下思路:我能不能捕获到react即将渲染真实DOM元素,然后在那之前进行处理呢?比如这样子
// 顶层的container
componentWillMount:function(){
// 给Index.html里面的动画元素提供淡出动画
}
事实证明此方法不可行。在执行到这儿的时候,我根本找不到让react组件延时挂在到真实DOM的入口,也就是如何在WillMount和Mount之前设置一个setTimeout,我找不到方法。
再接再厉
后来忽然想到一种方法,那就是把动画元素放在root之外,这样react就能自由地控制了。
// index.html
<style>
// 加载中的动画样式
</style>
<div id='root'></div>
<div id='loading'>
// 添加一些加载中的动画DOM元素
// 这些DOM元素是绝对定位的,覆盖了root
</div>
然后,在componentDidMount之后给loading添加消退动画,这样子就可以实现了。
而且,通过这种方法,你可以精确地控制loading遮罩层的消退时机。实际上我在应用的时候不是在componentDidMount的时候就消退的。因为我里面有数据请求,而这个数据请求至关重要,没有数据展示该页面根本没有意义。所以我索性将消退时机推迟到数据返回成功。这样做的好处有两个。
- 用户正式进入应用的时候应用已经是可用的状态了
- 不需要再进入应用之后再做数据加载中的动画