Skip to content

Commit

Permalink
Post, Comment 컴포넌트 분리 및 Lazy load 적용 #64
Browse files Browse the repository at this point in the history
포스트 페이지 로드에 disqus 생성이 함께 되면서 느림,
따라서 스크롤을 하여 포스트 내용의 아래에 도달하게 된 시점에 React.lazy를 이용하여 컴포넌트를 불러오게 되는 방식으로 개선
  • Loading branch information
junhobaik committed Jul 29, 2020
1 parent 6a2b0bd commit 50b8e1a
Show file tree
Hide file tree
Showing 2 changed files with 89 additions and 54 deletions.
29 changes: 29 additions & 0 deletions src/components/Comment/index.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
import * as React from 'react';
import { DiscussionEmbed } from 'disqus-react';
import config from '../../../_config';

interface CommentProps {
slug: string;
title: string;
}

const Comment = ({ slug, title }: CommentProps) => {
console.log('Comment');

const disqusConfig = {
shortname: config.disqusShortname,
config: {
url: `${config.siteUrl + slug}`,
identifier: slug,
title,
},
};

return (
<div className="comments">
<DiscussionEmbed {...disqusConfig} />
</div>
);
};

export default Comment;
114 changes: 60 additions & 54 deletions src/templates/Post.tsx
Original file line number Diff line number Diff line change
@@ -1,11 +1,10 @@
/* eslint-disable @typescript-eslint/no-explicit-any */

import * as React from 'react';
import { useEffect, useState } from 'react';
import { useEffect, useState, Suspense } from 'react';
import Helmet from 'react-helmet';
import { useSelector } from 'react-redux';
import { graphql, Link } from 'gatsby';
import { DiscussionEmbed } from 'disqus-react';
import moment from 'moment';
import { FontAwesomeIcon as Fa } from '@fortawesome/react-fontawesome';
import { faListUl, faLayerGroup, faAngleLeft } from '@fortawesome/free-solid-svg-icons';
Expand All @@ -24,13 +23,13 @@ import {
PocketIcon,
EmailIcon,
} from 'react-share';
import _ from 'lodash';

import { RootState } from '../state/reducer';

import Layout from '../components/Layout';
import Toc from '../components/Toc';
import SEO from '../components/seo';

import 'katex/dist/katex.min.css';
import './code-theme.scss';
import './post.scss';
Expand Down Expand Up @@ -62,18 +61,44 @@ const Post = (props: postProps) => {

const [yList, setYList] = useState([] as number[]);
const [isInsideToc, setIsInsideToc] = useState(false);
const [commentEl, setCommentEl] = useState<JSX.Element>();

const isTableOfContents = enablePostOfContents && tableOfContents !== '';
const isDevelopment = process.env.NODE_ENV === 'development';
const isDisqus: boolean = disqusShortname ? true : false;
const isSocialShare = enableSocialShare;

useEffect(() => {
const hs = Array.from(document.querySelectorAll('h2, h3')) as HTMLHeadingElement[];
const minusValue = window.innerHeight < 500 ? 100 : Math.floor(window.innerHeight / 5);
const yPositions = hs.map(h => h.offsetTop - minusValue);
setYList(yPositions);
}, []);
const mapTags = tags.map((tag: string) => {
return (
<li key={tag} className="blog-post-tag">
<Link to={`/tags#${tag}`}>{`#${tag}`}</Link>
</li>
);
});

const mapSeries = series.map((s: any) => {
return (
<li key={`${s.slug}-series-${s.num}`} className={`series-item ${slug === s.slug ? 'current-series' : ''}`}>
<Link to={s.slug}>
<span>{s.title}</span>
<div className="icon-wrap">{slug === s.slug ? <Fa icon={faAngleLeft} /> : null}</div>
</Link>
</li>
);
});

const metaKeywords: (keywordList: string[], tagList: string[]) => string[] = (
keywordList: string[],
tagList: string[]
) => {
const resultKeywords = new Set();

for (const v of [...keywordList, ...tagList]) {
resultKeywords.add(v);
}

return Array.from(resultKeywords) as string[];
};

useEffect(() => {
if (isMobile) {
Expand Down Expand Up @@ -114,47 +139,32 @@ const Post = (props: postProps) => {
};
}, [yList]);

const mapTags = tags.map((tag: string) => {
return (
<li key={tag} className="blog-post-tag">
<Link to={`/tags#${tag}`}>{`#${tag}`}</Link>
</li>
);
});

const mapSeries = series.map((s: any) => {
return (
<li key={`${s.slug}-series-${s.num}`} className={`series-item ${slug === s.slug ? 'current-series' : ''}`}>
<Link to={s.slug}>
<span>{s.title}</span>
<div className="icon-wrap">{slug === s.slug ? <Fa icon={faAngleLeft} /> : null}</div>
</Link>
</li>
);
});

//disqus
const disqusConfig = {
shortname: config.disqusShortname,
config: {
url: `${config.siteUrl + slug}`,
identifier: slug,
title,
},
};

const metaKeywords: (keywordList: string[], tagList: string[]) => string[] = (
keywordList: string[],
tagList: string[]
) => {
const resultKeywords = new Set();
useEffect(() => {
// scroll
const postContentOriginTop = document.querySelector('.blog-post')?.getBoundingClientRect().top ?? 0;
const removeScrollEvent = () => document.removeEventListener('scroll', scrollEvents);
const renderComment = () => {
const Comment = React.lazy(() => import('../components/Comment'));
setCommentEl(<Comment slug={slug} title={title} />);
};
const scrollEvents = _.throttle(() => {
const postContentHeight = document.querySelector('.blog-post')?.getBoundingClientRect().height ?? Infinity;
if (window.scrollY + window.innerHeight - postContentOriginTop > postContentHeight) {
renderComment();
removeScrollEvent();
}
}, 250);
scrollEvents();
document.addEventListener('scroll', scrollEvents);

for (const v of [...keywordList, ...tagList]) {
resultKeywords.add(v);
}
// toc
const hs = Array.from(document.querySelectorAll('h2, h3')) as HTMLHeadingElement[];
const minusValue = window.innerHeight < 500 ? 100 : Math.floor(window.innerHeight / 5);
const yPositions = hs.map(h => h.offsetTop - minusValue);
setYList(yPositions);

return Array.from(resultKeywords) as string[];
};
return () => removeScrollEvent();
}, []);

return (
<>
Expand Down Expand Up @@ -301,7 +311,7 @@ const Post = (props: postProps) => {
</div>
) : null}

{isDevelopment ? (
{!isDevelopment ? (
<>
<aside className="ad ad-dev">
<span>Ads</span>
Expand All @@ -326,11 +336,7 @@ const Post = (props: postProps) => {
/>
</aside>

{isDisqus ? (
<div className="comments">
<DiscussionEmbed {...disqusConfig} />
</div>
) : null}
<Suspense fallback={<></>}>{commentEl}</Suspense>
</>
)}
</div>
Expand Down

0 comments on commit 50b8e1a

Please sign in to comment.