From 049c9a3b9711ed203855d18a9a549e65e164ec59 Mon Sep 17 00:00:00 2001 From: Thibaut Girka Date: Sat, 9 Feb 2019 20:54:11 +0100 Subject: [PATCH] Avoid two-step rendering of statuses as much as possible Cache width shared by Video player, MediaGallery and Cards at the ScrollableList level, pass it down through StatusList and Notifications. --- .../flavours/glitch/components/media_gallery.js | 10 ++++++++-- .../flavours/glitch/components/scrollable_list.js | 12 +++++++++++- app/javascript/flavours/glitch/components/status.js | 8 ++++++++ .../notifications/components/notification.js | 12 ++++++++++++ .../glitch/features/status/components/card.js | 7 +++++-- .../flavours/glitch/features/video/index.js | 5 ++++- 6 files changed, 48 insertions(+), 6 deletions(-) diff --git a/app/javascript/flavours/glitch/components/media_gallery.js b/app/javascript/flavours/glitch/components/media_gallery.js index d0226bbbb..1fa25ee4e 100644 --- a/app/javascript/flavours/glitch/components/media_gallery.js +++ b/app/javascript/flavours/glitch/components/media_gallery.js @@ -224,6 +224,8 @@ export default class MediaGallery extends React.PureComponent { size: PropTypes.object, onOpenMedia: PropTypes.func.isRequired, intl: PropTypes.object.isRequired, + defaultWidth: PropTypes.number, + cacheWidth: PropTypes.func, }; static defaultProps = { @@ -232,6 +234,7 @@ export default class MediaGallery extends React.PureComponent { state = { visible: this.props.revealed === undefined ? (displayMedia !== 'hide_all' && !this.props.sensitive || displayMedia === 'show_all') : this.props.revealed, + width: this.props.defaultWidth, }; componentWillReceiveProps (nextProps) { @@ -259,6 +262,7 @@ export default class MediaGallery extends React.PureComponent { handleRef = (node) => { this.node = node; if (node && node.offsetWidth && node.offsetWidth != this.state.width) { + if (this.props.cacheWidth) this.props.cacheWidth(node.offsetWidth); this.setState({ width: node.offsetWidth, }); @@ -271,10 +275,12 @@ export default class MediaGallery extends React.PureComponent { } render () { - const { media, intl, sensitive, letterbox, fullwidth } = this.props; - const { width, visible } = this.state; + const { media, intl, sensitive, letterbox, fullwidth, defaultWidth } = this.props; + const { visible } = this.state; const size = media.take(4).size; + const width = this.state.width || defaultWidth; + let children; const style = {}; diff --git a/app/javascript/flavours/glitch/components/scrollable_list.js b/app/javascript/flavours/glitch/components/scrollable_list.js index 7cd0774a9..2e7c9fd6e 100644 --- a/app/javascript/flavours/glitch/components/scrollable_list.js +++ b/app/javascript/flavours/glitch/components/scrollable_list.js @@ -40,6 +40,7 @@ export default class ScrollableList extends PureComponent { state = { fullscreen: null, + cachedMediaWidth: 300, }; intersectionObserverWrapper = new IntersectionObserverWrapper(); @@ -141,6 +142,10 @@ export default class ScrollableList extends PureComponent { this.setScrollTop(newScrollTop); } + cacheMediaWidth = (width) => { + if (width && this.state.cachedMediaWidth != width) this.setState({ cachedMediaWidth: width }); + } + getSnapshotBeforeUpdate (prevProps, prevState) { const someItemInserted = React.Children.count(prevProps.children) > 0 && React.Children.count(prevProps.children) < React.Children.count(this.props.children) && @@ -252,7 +257,12 @@ export default class ScrollableList extends PureComponent { intersectionObserverWrapper={this.intersectionObserverWrapper} saveHeightKey={trackScroll ? `${this.context.router.route.location.key}:${scrollKey}` : null} > - {React.cloneElement(child, {getScrollPosition: this.getScrollPosition, updateScrollBottom: this.updateScrollBottom})} + {React.cloneElement(child, { + getScrollPosition: this.getScrollPosition, + updateScrollBottom: this.updateScrollBottom, + cachedMediaWidth: this.state.cachedMediaWidth, + cacheMediaWidth: this.cacheMediaWidth, + })} ))} diff --git a/app/javascript/flavours/glitch/components/status.js b/app/javascript/flavours/glitch/components/status.js index 80cd0f42e..68788451b 100644 --- a/app/javascript/flavours/glitch/components/status.js +++ b/app/javascript/flavours/glitch/components/status.js @@ -72,6 +72,8 @@ export default class Status extends ImmutablePureComponent { updateScrollBottom: PropTypes.func, expanded: PropTypes.bool, intl: PropTypes.object.isRequired, + cacheMediaWidth: PropTypes.func, + cachedMediaWidth: PropTypes.number, }; state = { @@ -445,6 +447,8 @@ export default class Status extends ImmutablePureComponent { fullwidth={settings.getIn(['media', 'fullwidth'])} preventPlayback={isCollapsed || !isExpanded} onOpenVideo={this.handleOpenVideo} + width={this.props.cachedMediaWidth} + cacheWidth={this.props.cacheMediaWidth} />)} ); @@ -460,6 +464,8 @@ export default class Status extends ImmutablePureComponent { fullwidth={settings.getIn(['media', 'fullwidth'])} hidden={isCollapsed || !isExpanded} onOpenMedia={this.props.onOpenMedia} + cacheWidth={this.props.cacheMediaWidth} + defaultWidth={this.props.cachedMediaWidth} /> )} @@ -476,6 +482,8 @@ export default class Status extends ImmutablePureComponent { onOpenMedia={this.props.onOpenMedia} card={status.get('card')} compact + cacheWidth={this.props.cacheMediaWidth} + defaultWidth={this.props.cachedMediaWidth} /> ); mediaIcon = 'link'; diff --git a/app/javascript/flavours/glitch/features/notifications/components/notification.js b/app/javascript/flavours/glitch/features/notifications/components/notification.js index 21c55accc..daafe3507 100644 --- a/app/javascript/flavours/glitch/features/notifications/components/notification.js +++ b/app/javascript/flavours/glitch/features/notifications/components/notification.js @@ -18,6 +18,9 @@ export default class Notification extends ImmutablePureComponent { onMention: PropTypes.func.isRequired, getScrollPosition: PropTypes.func, updateScrollBottom: PropTypes.func, + cacheMediaWidth: PropTypes.func, + cachedMediaWidth: PropTypes.number, + onUnmount: PropTypes.func, }; render () { @@ -57,6 +60,9 @@ export default class Notification extends ImmutablePureComponent { contextType='notifications' getScrollPosition={getScrollPosition} updateScrollBottom={updateScrollBottom} + cachedMediaWidth={this.props.cachedMediaWidth} + cacheMediaWidth={this.props.cacheMediaWidth} + onUnmount={this.props.onUnmount} withDismiss /> ); @@ -75,6 +81,9 @@ export default class Notification extends ImmutablePureComponent { onMention={onMention} getScrollPosition={getScrollPosition} updateScrollBottom={updateScrollBottom} + cachedMediaWidth={this.props.cachedMediaWidth} + cacheMediaWidth={this.props.cacheMediaWidth} + onUnmount={this.props.onUnmount} withDismiss /> ); @@ -93,6 +102,9 @@ export default class Notification extends ImmutablePureComponent { onMention={onMention} getScrollPosition={getScrollPosition} updateScrollBottom={updateScrollBottom} + cachedMediaWidth={this.props.cachedMediaWidth} + cacheMediaWidth={this.props.cacheMediaWidth} + onUnmount={this.props.onUnmount} withDismiss /> ); diff --git a/app/javascript/flavours/glitch/features/status/components/card.js b/app/javascript/flavours/glitch/features/status/components/card.js index 1e1604d5c..e405a5ef0 100644 --- a/app/javascript/flavours/glitch/features/status/components/card.js +++ b/app/javascript/flavours/glitch/features/status/components/card.js @@ -60,6 +60,8 @@ export default class Card extends React.PureComponent { maxDescription: PropTypes.number, onOpenMedia: PropTypes.func.isRequired, compact: PropTypes.bool, + defaultWidth: PropTypes.number, + cacheWidth: PropTypes.func, }; static defaultProps = { @@ -68,7 +70,7 @@ export default class Card extends React.PureComponent { }; state = { - width: 280, + width: this.props.defaultWidth || 280, embedded: false, }; @@ -111,6 +113,7 @@ export default class Card extends React.PureComponent { setRef = c => { if (c) { + if (this.props.cacheWidth) this.props.cacheWidth(c.offsetWidth); this.setState({ width: c.offsetWidth }); } } @@ -133,7 +136,7 @@ export default class Card extends React.PureComponent { } render () { - const { card, maxDescription, compact } = this.props; + const { card, maxDescription, compact, defaultWidth } = this.props; const { width, embedded } = this.state; if (card === null) { diff --git a/app/javascript/flavours/glitch/features/video/index.js b/app/javascript/flavours/glitch/features/video/index.js index d8e8791a7..a6f651db6 100644 --- a/app/javascript/flavours/glitch/features/video/index.js +++ b/app/javascript/flavours/glitch/features/video/index.js @@ -103,6 +103,7 @@ export default class Video extends React.PureComponent { inline: PropTypes.bool, preventPlayback: PropTypes.bool, intl: PropTypes.object.isRequired, + cacheWidth: PropTypes.func, }; state = { @@ -111,7 +112,7 @@ export default class Video extends React.PureComponent { volume: 0.5, paused: true, dragging: false, - containerWidth: false, + containerWidth: this.props.width, fullscreen: false, hovered: false, muted: false, @@ -131,6 +132,7 @@ export default class Video extends React.PureComponent { this.player = c; if (c && c.offsetWidth && c.offsetWidth != this.state.containerWidth) { + if (this.props.cacheWidth) this.props.cacheWidth(this.player.offsetWidth); this.setState({ containerWidth: c.offsetWidth, }); @@ -275,6 +277,7 @@ export default class Video extends React.PureComponent { componentDidUpdate (prevProps) { if (this.player && this.player.offsetWidth && this.player.offsetWidth != this.state.containerWidth && !this.state.fullscreen) { + if (this.props.cacheWidth) this.props.cacheWidth(this.player.offsetWidth); this.setState({ containerWidth: this.player.offsetWidth, });