/** * The examples provided by Facebook are for non-commercial testing and * evaluation purposes only. * * Facebook reserves all rights not expressly granted. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NON INFRINGEMENT. IN NO EVENT SHALL * FACEBOOK BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. * * @providesModule IncrementalExample * @flow */ 'use strict'; const React = require('react'); const ReactNative = require('react-native'); const { InteractionManager, ScrollView, StyleSheet, Text, TouchableOpacity, View, } = ReactNative; const Incremental = require('Incremental'); const IncrementalGroup = require('IncrementalGroup'); const IncrementalPresenter = require('IncrementalPresenter'); const JSEventLoopWatchdog = require('JSEventLoopWatchdog'); const performanceNow = require('fbjs/lib/performanceNow'); InteractionManager.setDeadline(1000); JSEventLoopWatchdog.install({thresholdMS: 200}); let totalWidgets = 0; class SlowWidget extends React.Component { state: {ctorTimestamp: number, timeToMount: number}; constructor(props, context) { super(props, context); this.state = { ctorTimestamp: performanceNow(), timeToMount: 0, }; } render() { this.state.timeToMount === 0 && burnCPU(20); return ( {`${this.state.timeToMount || '?'} ms`} ); } componentDidMount() { const timeToMount = performanceNow() - this.state.ctorTimestamp; this.setState({timeToMount}); totalWidgets++; } } let imHandle; function startInteraction() { imHandle = InteractionManager.createInteractionHandle(); } function stopInteraction() { InteractionManager.clearInteractionHandle(imHandle); } function Block(props: Object) { const IncrementalContainer = props.stream ? IncrementalGroup : IncrementalPresenter; return ( {props.idx + ': ' + (props.stream ? 'Streaming' : 'Presented')} {props.children} ); } const Row = (props: Object) => ; class IncrementalExample extends React.Component { static title = ''; static description = 'Enables incremental rendering of complex components.'; start: number; state: {stats: ?Object}; constructor(props: mixed, context: mixed) { super(props, context); this.start = performanceNow(); this.state = { stats: null, }; (this: any)._onDone = this._onDone.bind(this); } _onDone() { const onDoneElapsed = performanceNow() - this.start; setTimeout(() => { const stats = { onDoneElapsed, totalWidgets, ...JSEventLoopWatchdog.getStats(), setTimeoutElapsed: performanceNow() - this.start, }; stats.avgStall = stats.totalStallTime / stats.stallCount; this.setState({stats}); console.log('onDone:', stats); }, 0); } render(): React.Element { return ( Press and hold on a row to pause rendering. {this.state.stats && Finished: {JSON.stringify(this.state.stats, null, 2)} } {Array(8).fill().map((_, blockIdx) => { return ( {Array(4).fill().map((_b, rowIdx) => ( {Array(14).fill().map((_c, widgetIdx) => ( ))} ))} ); })} ); } } function burnCPU(milliseconds) { const start = performanceNow(); while (performanceNow() < (start + milliseconds)) {} } var styles = StyleSheet.create({ scrollView: { margin: 10, backgroundColor: 'white', flex: 1, }, headerText: { fontSize: 20, margin: 10, }, block: { borderRadius: 6, borderWidth: 2, borderColor: '#a52a2a', padding: 14, margin: 5, backgroundColor: 'white', }, row: { flexDirection: 'row', }, widgetContainer: { backgroundColor: '#dddddd', padding: 2, margin: 2, }, widgetText: { color: 'black', fontSize: 4, }, }); module.exports = IncrementalExample;