Lazy-load comment components

## Issue
~300KB savings in `ui.js` size (production, uncompressed). Mostly coming from the emoji library.

## Notes
Most of the `Comment*` components are under `CommentsList` or `LivestreamComments`, so deferring these 2 covered most of it. The exceptions are Notification and OwnComments.
This commit is contained in:
infinite-persistence 2021-10-18 23:54:59 +08:00 committed by Thomas Zarebczan
parent 0f68bad3eb
commit ef0329e03b
6 changed files with 64 additions and 38 deletions

View file

@ -1,7 +1,9 @@
// @flow
import React from 'react';
import CommentsList from 'component/commentsList';
import Empty from 'component/common/empty';
import { lazyImport } from 'util/lazyImport';
const CommentsList = lazyImport(() => import('component/commentsList' /* webpackChunkName: "comments" */));
type Props = {
uri: string,
@ -17,7 +19,9 @@ function ChannelDiscussion(props: Props) {
}
return (
<section className="section">
<CommentsList uri={uri} linkedCommentId={linkedCommentId} commentsAreExpanded />
<React.Suspense fallback={null}>
<CommentsList uri={uri} linkedCommentId={linkedCommentId} commentsAreExpanded />
</React.Suspense>
</section>
);
}

View file

@ -2,8 +2,10 @@
import { LIVESTREAM_EMBED_URL } from 'constants/livestream';
import React from 'react';
import FileTitleSection from 'component/fileTitleSection';
import LivestreamComments from 'component/livestreamComments';
import { useIsMobile } from 'effects/use-screensize';
import { lazyImport } from 'util/lazyImport';
const LivestreamComments = lazyImport(() => import('component/livestreamComments' /* webpackChunkName: "comments" */));
type Props = {
uri: string,
@ -54,7 +56,7 @@ export default function LivestreamLayout(props: Props) {
</div>
)}
{isMobile && <LivestreamComments uri={uri} />}
<React.Suspense fallback={null}>{isMobile && <LivestreamComments uri={uri} />}</React.Suspense>
<FileTitleSection uri={uri} livestream isLive={isLive} />
</div>

View file

@ -1,4 +1,5 @@
// @flow
import { lazyImport } from 'util/lazyImport';
import { formatLbryUrlForWeb } from 'util/url';
import { Menu, MenuList, MenuButton, MenuItem } from '@reach/menu-button';
import { NavLink } from 'react-router-dom';
@ -12,9 +13,6 @@ import * as PAGES from 'constants/pages';
import Button from 'component/button';
import ChannelThumbnail from 'component/channelThumbnail';
import classnames from 'classnames';
import CommentCreate from 'component/commentCreate';
import CommentReactions from 'component/commentReactions';
import CommentsReplies from 'component/commentsReplies';
import DateTime from 'component/dateTime';
import FileThumbnail from 'component/fileThumbnail';
import Icon from 'component/common/icon';
@ -24,6 +22,10 @@ import OptimizedImage from 'component/optimizedImage';
import React from 'react';
import UriIndicator from 'component/uriIndicator';
const CommentCreate = lazyImport(() => import('component/commentCreate' /* webpackChunkName: "comments" */));
const CommentReactions = lazyImport(() => import('component/commentReactions' /* webpackChunkName: "comments" */));
const CommentsReplies = lazyImport(() => import('component/commentsReplies' /* webpackChunkName: "comments" */));
type Props = {
menuButton: boolean,
notification: WebNotification,
@ -267,16 +269,18 @@ export default function Notification(props: Props) {
</div>
{isReplying && (
<CommentCreate
isReply
uri={notificationTarget}
parentId={notification_parameters.dynamic.hash}
onDoneReplying={() => setReplying(false)}
onCancelReplying={() => setReplying(false)}
setQuickReply={setQuickReply}
supportDisabled
shouldFetchComment
/>
<React.Suspense fallback={null}>
<CommentCreate
isReply
uri={notificationTarget}
parentId={notification_parameters.dynamic.hash}
onDoneReplying={() => setReplying(false)}
onCancelReplying={() => setReplying(false)}
setQuickReply={setQuickReply}
supportDisabled
shouldFetchComment
/>
</React.Suspense>
)}
{quickReply && (

View file

@ -11,11 +11,11 @@ import FileRenderInline from 'component/fileRenderInline';
import FileRenderDownload from 'component/fileRenderDownload';
import RecommendedContent from 'component/recommendedContent';
import CollectionContent from 'component/collectionContentSidebar';
import CommentsList from 'component/commentsList';
import Button from 'component/button';
import I18nMessage from 'component/i18nMessage';
import Empty from 'component/common/empty';
const CommentsList = lazyImport(() => import('component/commentsList' /* webpackChunkName: "comments" */));
const PostViewer = lazyImport(() => import('component/postViewer' /* webpackChunkName: "postViewer" */));
export const PRIMARY_PLAYER_WRAPPER_CLASS = 'file-page__video-container';
@ -209,7 +209,9 @@ function FilePage(props: Props) {
)}
{RENDER_MODES.FLOATING_MODES.includes(renderMode) && <FileTitleSection uri={uri} />}
{commentsDisabled && <Empty text={__('The creator of this content has disabled comments.')} />}
{!commentsDisabled && <CommentsList uri={uri} linkedCommentId={linkedCommentId} />}
<React.Suspense fallback={null}>
{!commentsDisabled && <CommentsList uri={uri} linkedCommentId={linkedCommentId} />}
</React.Suspense>
</div>
{!collection && !isMarkdown && videoTheaterMode && <RecommendedContent uri={uri} />}
{collection && !isMarkdown && videoTheaterMode && <CollectionContent id={collectionId} uri={uri} />}
@ -220,7 +222,9 @@ function FilePage(props: Props) {
{!collection && !isMarkdown && !videoTheaterMode && <RecommendedContent uri={uri} />}
{isMarkdown && (
<div className="file-page__post-comments">
<CommentsList uri={uri} linkedCommentId={linkedCommentId} commentsAreExpanded />
<React.Suspense fallback={null}>
<CommentsList uri={uri} linkedCommentId={linkedCommentId} commentsAreExpanded />
</React.Suspense>
</div>
)}
</Page>

View file

@ -1,12 +1,14 @@
// @flow
import React from 'react';
import { lazyImport } from 'util/lazyImport';
import Page from 'component/page';
import LivestreamLayout from 'component/livestreamLayout';
import LivestreamComments from 'component/livestreamComments';
import analytics from 'analytics';
import Lbry from 'lbry';
import watchLivestreamStatus from '$web/src/livestreaming/long-polling';
const LivestreamComments = lazyImport(() => import('component/livestreamComments' /* webpackChunkName: "comments" */));
type Props = {
uri: string,
claim: StreamClaim,
@ -90,7 +92,13 @@ export default function LivestreamPage(props: Props) {
noFooter
livestream
chatDisabled={chatDisabled}
rightSide={!chatDisabled && <LivestreamComments uri={uri} />}
rightSide={
!chatDisabled && (
<React.Suspense fallback={null}>
<LivestreamComments uri={uri} />
</React.Suspense>
)
}
>
<LivestreamLayout uri={uri} isLive={isLive} />
</Page>

View file

@ -3,7 +3,6 @@ import React from 'react';
import Button from 'component/button';
import ChannelSelector from 'component/channelSelector';
import ClaimPreview from 'component/claimPreview';
import Comment from 'component/comment';
import Card from 'component/common/card';
import Empty from 'component/common/empty';
import Page from 'component/page';
@ -12,6 +11,9 @@ import { COMMENT_PAGE_SIZE_TOP_LEVEL } from 'constants/comment';
import * as ICONS from 'constants/icons';
import useFetched from 'effects/use-fetched';
import debounce from 'util/debounce';
import { lazyImport } from 'util/lazyImport';
const Comment = lazyImport(() => import('component/comment' /* webpackChunkName: "comments" */));
function scaleToDevicePixelRatio(value) {
const devicePixelRatio = window.devicePixelRatio || 1.0;
@ -77,21 +79,23 @@ export default function OwnComments(props: Props) {
)}
{!contentClaim && <Empty text={__('Content or channel was deleted.')} />}
</div>
<Comment
isTopLevel
hideActions
authorUri={comment.channel_url}
author={comment.channel_name}
commentId={comment.comment_id}
message={comment.comment}
timePosted={comment.timestamp * 1000}
commentIsMine
supportAmount={comment.support_amount}
numDirectReplies={0} // Don't show replies here
isModerator={comment.is_moderator}
isGlobalMod={comment.is_global_mod}
isFiat={comment.is_fiat}
/>
<React.Suspense fallback={null}>
<Comment
isTopLevel
hideActions
authorUri={comment.channel_url}
author={comment.channel_name}
commentId={comment.comment_id}
message={comment.comment}
timePosted={comment.timestamp * 1000}
commentIsMine
supportAmount={comment.support_amount}
numDirectReplies={0} // Don't show replies here
isModerator={comment.is_moderator}
isGlobalMod={comment.is_global_mod}
isFiat={comment.is_fiat}
/>
</React.Suspense>
</div>
</div>
);