解决React首屏加载白屏的问题

众所周知,在项目中如果在资源加载请求还未完成的时候,由于阻塞机制,会出现首页白屏的问题,产生很差的用户体验。本文以react为例,提供一个解决方法。

解决原理:使用  onreadystatechange  去监听 readyState,在资源加载完成之前加载一个只有框架的静态页面,页面不请求数据。当数据请求完成之后再将路由切换到真实的首页。

废话不多说,上代码:

main.js

import React from ‘react‘import ReactDom from ‘react-dom‘import {Provider} from ‘react-redux‘import {BrowserRouter as Router, Route} from ‘react-router-dom‘import configureStore from ‘./store‘import Index from ‘./containers/Index.js‘import FirstScreen from ‘./containers/FirstScreen.js‘

export const store = configureStore()

function listen () {    if (document.readyState == ‘complete‘) { // 资源加载完成        ReactDom.render(            <Provider store={store}>                <Router>                    <Route path="/" component={Index}/>                </Router>            </Provider>,            document.getElementById(‘root‘)        )    } else { // 资源加载中        ReactDom.render(            <Provider store={store}>                <Router>                    <Route path="/" component={FirstScreen}/>                </Router>            </Provider>,            document.getElementById(‘root‘)        )    }}

document.onreadystatechange = listen
其中Index.js就是你的真实首页,FirstScreen.js就是只有框架的静态页。

Index.js
import React, {Component} from ‘react‘import PropTypes from ‘prop-types‘import {connect} from ‘react-redux‘import {store} from ‘../main‘import {bindActionCreators} from ‘redux‘import {getLocalTime} from ‘../actions/localTime‘import LocalTime from ‘../components/LocalTime‘import ‘../static/css/Index.css‘

class Index extends Component {    /**     *  constructor() React组件的构造函数在挂载之前被调用。     *  在实现React.Component子类的构造函数时,     *  应该super(props)在任何其他语句之前调用。     *  否则,this.props会在构造函数中定义,这可能会导致错误。     */    constructor (props) {        super(props)        this.realTime = this.realTime.bind(this)    }

realTime () {        setInterval(() => {            store.dispatch(getLocalTime())        }, 1000)    }

/**     *  componentWillMount()会在组件render之前立即被调用,并且永远都只执行一次。     *  由于这个方法始终只执行一次,所以如果在这里定义了setState方法之后,页面永远都只会在加载前更新一次。     */    componentWillMount () {    }

/**     *  componentDidMount()在组件被装载后立即被调用。     *  在这个时候之后组件已经生成了对应的DOM结构。     *  可以在这个方法中执行setTimeout, setInterval,接口调用等。     */    componentDidMount () {        this.realTime()    }

/**     *  componentWillReceiveProps()在组件接收到一个新的prop时被执行。     *  这个方法在初始化render时不会被调用。     */    componentWillReceiveProps () {    }

/**     *  返回一个布尔值。在组件接收到新的props或者state时被执行。     *  在初始化时或者使用forceUpdate时不被执行。     *  如果shouldComponentUpdate返回false,     *   render()则会在下一个state change之前被完全跳过,componentWillUpdate和 componentDidUpdate也不会被执行     */    shouldComponentUpdate (nextProps, nextState) {        return true    }

/**     * componentWillUpdate()在组件接收到新的props或者state但还没有render时被执行。     * 在初始化时不会被执行。     */    componentWillUpdate (nextProps, nextState) {    }

/**     * componentDidUpdate()在组件完成更新后立即执行。     * 在初始化时不会被执行。一般会在组件完成更新后被使用。     * 可以用来 clearInterval。     */    componentDidUpdate (prevProps, prevState) {        clearInterval(this.realTime())    }

/**     *  render()函数应该是纯粹的,这意味着它不会修改组件状态,     *  每次调用时都会返回相同的结果,并且不会直接与浏览器交互     */    render () {        const {localTime} = this.props        return (            <div className=‘main‘>                <LocalTime localTime={localTime} getLocalTime={getLocalTime}></LocalTime>            </div>        )    }}

Index.propTypes = {    localTime: PropTypes.string,    getLocalTime: PropTypes.func}

// 将state绑定到propsconst mapStateToProps = (state, ownProps) => {    const {localTime} = state    return {        localTime: localTime.localTime    }}

// 将action绑定到props上const mapDispatchToProps = (dispatch, ownProps) => {    return {        getLocalTime: bindActionCreators(getLocalTime, dispatch)    }}

// 通过react-redux提供的connect方法将我们需要的state中的数据和actions中的方法绑定到props上export default connect(mapStateToProps, mapDispatchToProps)(Index)
FirstScreen.js
import React, {Component} from ‘react‘import {connect} from ‘react-redux‘import ‘../static/css/FirstScreen.css‘

class FirstScreen extends Component {    constructor (props) {        super(props)    }

render () {        return (            <div className=‘firstScreen‘>                我是首屏空白页            </div>        )    }}

export default connect()(FirstScreen)
示例代码托管在GitHub上:https://github.com/skillnull/TheCurrentTime
时间: 2024-07-29 09:45:33

解决React首屏加载白屏的问题的相关文章

React Native 首次加载白屏优化

RN首次加载都会有个白屏过程,一般都会有500ms+的白屏时间,原生页面开发同样的页面会能够快速显示而在RN页面中有个明显的等待过程,这个会影响用户体验. 1.使用过度页面 简单处理可以在白屏过程中加个过度页面,通过设置RCTRootView的loadingView添加默认的加载过程 /** * A view to display while the JavaScript is loading, so users aren't presented * with a blank screen. B

Vue SPA 首屏加载优化实践

写在前面 本文记录笔者在Vue SPA项目首屏加载优化过程中遇到的一些坑及优化方案! 我们以 vue-cli 工具为例,使用 vue-router 搭建SPA应用,UI框架选用 element-ui , ajax方案选用 axios, 并引入 vuex ,使用 vuex-router-sync 将 router 同步到 store ,服务器使用本地Nginx服务. 构建项目 vue-init webpack vue-spa-starter-kit cd vue-spa-starter-kit n

vue项目首屏加载优化实战

问题 单页面应用的一个问题就是首页加载东西过多,加载时间过长.特别在移动端,单页面应用的首屏加载优化更是绕不开的话题.下面我会写出我在项目中做的一些优化,希望大家能够相互讨论,共同进步. 我的项目vue-cli3构建的,vue+vue-router+vuex,UI框架选用 element-ui,ajax方案选用 axios,服务器使用Nginx.用到的这些技术都是现在用的比较广泛的,看到这篇文章,我估计你和我用的技术应该差不多. 第一步:webpack-bundle-analyzer 分析 首页

(BUG已修改,最优化)安卓ListView异步加载网络图片与缓存软引用图片,线程池,只加载当前屏之说明

原文:http://blog.csdn.net/java_jh/article/details/20068915 迟点出更新的.这个还有BUG.因为软引应不给力了.2.3之后 前几天的原文有一个线程管理与加载源过多,造成浪费流量的问题.下面对这进下改进的一些说明(红色为新加) 这两天一直在优化这个问题.google也很多种做法.但发现都是比较不全面. 比如: 一些只实现了异步加载,却没有线程池与软引用. 一些是用AsynTast的, 一些有了线程池但加载所有的图片,这样造成具大资源浪费 一些是用

jQuery 超屏加载

jQuery 超屏加载,当文档超出屏幕的高度时,加载最新下个列数据 $(window).scroll(function () { var height = $(document).height(); //页面的高度 var keheight = $(window).height(); //浏览器可视的高度 var sheight = $(document).scrollTop(); //滚动的高度 var num = $('.pro_list a').length; if (height <=

Debian 7.6 新编译内核 3.15.6 开机加载黑屏

需要手动加载 fbcon 这个模块,或者编译内核的时候,Framebuffer Console support 编译进内核(后者没测试过).加在模块只要修改/etc/default/grub文件或者/boot/grub/grub.cfg文件,添加”vga=0x0314 fb:on“.修改/etc/default/grub文件需再运行grub-mkconfig. [email protected]:~$ lsb_release -aNo LSB modules are available.Dist

滚屏加载--无刷新动态加载数据技术的应用

index.html <?php require_once('connect.php'); //连接数据库 $user = array('demo1','demo2','demo3','demo3','<de></de>mo4'); //模拟了几个用户 ?> <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtm

Android时时监测手机的旋转角度 根据旋转角度确定在什么角度加载竖屏布局 在什么时候加载横屏布局

一.场景描述: 近期开发中遇到个问题,就是我们在做横竖屏切换的功能时,横竖屏布局是操作系统去感知的,作为开发员没法确定Activity在什么时候加载横屏布局,在什么时候加载竖屏布局.因此为了找到加载横屏布局与竖屏布局的分界点,我特别监控了屏幕旋转的角度,看在什么样的角度会加载横屏布局,在什么样的角度加载竖屏布局. 二.屏幕旋转度数变化示意图 度数变化,拿着手机顺时针旋转,度数会越变越大. 三.在Activity中监听手机的旋转角度,上代码. /** * 时时监测屏幕方向是否发生改变 * @aut

滚屏加载--jQuery+PHP实现浏览更多内容

滚屏加载技术,就是使用Javascript监视滚动条的位置,每次当滚动条到达浏览器窗口底部时,触发一个Ajax请求后台PHP程序,返回相应的数据,并将返回的数据追加到页面底部,从而实现了动态加载,其实就是一个典型的Ajax应用.本文将使用jQuery,结合PHP,mysql以及JSON,为您讲解如何应用滚屏加载技术到您的项目中去.当然,阅读本文的前提是您需要有jQuery和PHP相关基础. index.php 我们默认要显示15条数据,因此,我们先从数据库取开始的15条数据显示在页面.后面新加载