Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

交互动画系列之一:解决bundle.js首次加载动画问题 #55

Open
youngwind opened this issue Apr 6, 2016 · 10 comments
Open
Labels

Comments

@youngwind
Copy link
Owner

系列说明

嗯,要想成为一个专业的前端,不懂交互动画可不行。所以借着做项目,顺便好好研究一下这个方向,希望能给团队带来一些提升。

本篇要解决的问题

如果你用react+webpack做过单页面应用,那么你一定遇到过bundle.js太大导致首次加载时白屏时间过长,解决办法有几个方向。

  1. 从较少bundle.js体积大小入手
  2. 从服务端渲染入手
  3. 从加载中动画入手

首次尝试

一开始我是这么想的:既然bundle.js还没加载完,那么我就把动画的DOM和CSS写在index.html里面就好了。

// index.html
<style>
// 加载中的动画样式
</style>

<div id='root'>
  // 添加一些加载中的动画DOM元素
</div>

结果:

  1. 在bundle.js加载完成之前确实会显示动画。
  2. 但是,一旦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的时候就消退的。因为我里面有数据请求,而这个数据请求至关重要,没有数据展示该页面根本没有意义。所以我索性将消退时机推迟到数据返回成功。这样做的好处有两个。

  1. 用户正式进入应用的时候应用已经是可用的状态了
  2. 不需要再进入应用之后再做数据加载中的动画

最后给个截图
demo

@Dbraum
Copy link

Dbraum commented Jul 8, 2016

请问有没有例子可以给看看

@youngwind
Copy link
Owner Author

@kunzhijia 完整的代码demo没有保留下来。按着思路走不能复现吗?你自己写得怎么样?能否给我看看你的demo?

@ruyaoyao
Copy link

謝謝分享,最近剛好對於這種lifecycle api有深刻的體會,看了這篇更加確定正確做法。
感激

@jun-lu
Copy link

jun-lu commented Nov 8, 2016

cool

@stoneox
Copy link

stoneox commented Jul 20, 2017

是需要在componentDidMount中获取到loading DOM吗,这样岂不是就是在react中操作dom?有更好的实现方式吗?

@youngwind
Copy link
Owner Author

的确是在 React 中操作了 DOM,但 React 操作的不是 React 渲染出来的 DOM,而是 root 以外的 DOM,所以我觉得问题并不大。 @stoneox

@huyansheng3
Copy link

很赞

@Caldis
Copy link

Caldis commented Nov 16, 2017

概括一下思路大概是:
1. 动画写在 HTML 中
2. React 组件加载完成后将 HTML 中的动画遮罩隐藏
* 动画不要写在 root 元素中

@hejueting
Copy link

6666666666666666

@bodyno
Copy link

bodyno commented Jan 31, 2018

不错 这种方式确实很好

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

No branches or pull requests

9 participants