Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Lazy load some non-critical resources on the new tab #461

Merged
merged 5 commits into from Feb 1, 2019
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
22 changes: 13 additions & 9 deletions web/src/js/components/Dashboard/DashboardComponent.js
Expand Up @@ -10,7 +10,6 @@ import MoneyRaised from 'js/components/MoneyRaised/MoneyRaisedContainer'
import UserBackgroundImage from 'js/components/User/UserBackgroundImageContainer'
import UserMenu from 'js/components/User/UserMenuContainer'
import WidgetsContainer from 'js/components/Widget/WidgetsContainer'
import CampaignBase from 'js/components/Campaign/CampaignBaseView'
import Ad from 'js/components/Ad/Ad'
import LogTab from 'js/components/Dashboard/LogTabContainer'
import LogRevenue from 'js/components/Dashboard/LogRevenueContainer'
Expand Down Expand Up @@ -54,6 +53,9 @@ import 'js/ads/ads'
const NewUserTour = lazy(() =>
import('js/components/Dashboard/NewUserTourContainer')
)
const CampaignBase = lazy(() =>
import('js/components/Campaign/CampaignBaseView')
)

class Dashboard extends React.Component {
constructor(props) {
Expand Down Expand Up @@ -276,14 +278,16 @@ class Dashboard extends React.Component {
/>
{isGlobalCampaignLive ? (
<FadeInDashboardAnimation>
<CampaignBase
onDismiss={() => {
this.setState({
hasUserDismissedCampaignRecently: true,
})
}}
showError={this.showError.bind(this)}
/>
<Suspense fallback={null}>
<CampaignBase
onDismiss={() => {
this.setState({
hasUserDismissedCampaignRecently: true,
})
}}
showError={this.showError.bind(this)}
/>
</Suspense>
</FadeInDashboardAnimation>
) : null}
{this.state.showFireworks
Expand Down
111 changes: 57 additions & 54 deletions web/src/js/components/Dashboard/__tests__/DashboardComponent.test.js
Expand Up @@ -116,70 +116,73 @@ describe('Dashboard component', () => {
expect(wrapper.find(WidgetsContainer).length).toBe(1)
})

it('renders CampaignBase component when the campaign is live and the user has not dismissed it', () => {
const DashboardComponent = require('js/components/Dashboard/DashboardComponent')
.default
const modifiedProps = cloneDeep(mockProps)
modifiedProps.app.isGlobalCampaignLive = true
hasUserDismissedCampaignRecently.mockReturnValueOnce(false)
const wrapper = shallow(<DashboardComponent {...modifiedProps} />)
expect(wrapper.find(CampaignBase).length).toBe(1)
})
// TODO: enable when Enzyme supports React.Suspense:
// https://github.com/airbnb/enzyme/issues/1917

it('does not render the CampaignBase component when the campaign is live but the user has dismissed it', () => {
const DashboardComponent = require('js/components/Dashboard/DashboardComponent')
.default
const modifiedProps = cloneDeep(mockProps)
modifiedProps.app.isGlobalCampaignLive = true
hasUserDismissedCampaignRecently.mockReturnValueOnce(true)
const wrapper = shallow(<DashboardComponent {...modifiedProps} />)
expect(wrapper.find(CampaignBase).length).toBe(0)
})
// it('renders CampaignBase component when the campaign is live and the user has not dismissed it', () => {
// const DashboardComponent = require('js/components/Dashboard/DashboardComponent')
// .default
// const modifiedProps = cloneDeep(mockProps)
// modifiedProps.app.isGlobalCampaignLive = true
// hasUserDismissedCampaignRecently.mockReturnValueOnce(false)
// const wrapper = shallow(<DashboardComponent {...modifiedProps} />)
// expect(wrapper.find(CampaignBase).length).toBe(1)
// })

it('does not render CampaignBase component when the campaign is not live', () => {
const DashboardComponent = require('js/components/Dashboard/DashboardComponent')
.default
const modifiedProps = cloneDeep(mockProps)
modifiedProps.app.isGlobalCampaignLive = false
hasUserDismissedCampaignRecently.mockReturnValueOnce(false)
const wrapper = shallow(<DashboardComponent {...modifiedProps} />)
expect(wrapper.find(CampaignBase).length).toBe(0)
})
// it('does not render the CampaignBase component when the campaign is live but the user has dismissed it', () => {
// const DashboardComponent = require('js/components/Dashboard/DashboardComponent')
// .default
// const modifiedProps = cloneDeep(mockProps)
// modifiedProps.app.isGlobalCampaignLive = true
// hasUserDismissedCampaignRecently.mockReturnValueOnce(true)
// const wrapper = shallow(<DashboardComponent {...modifiedProps} />)
// expect(wrapper.find(CampaignBase).length).toBe(0)
// })

it('hides the campaign when the onDismiss callback is called', () => {
const DashboardComponent = require('js/components/Dashboard/DashboardComponent')
.default
const modifiedProps = cloneDeep(mockProps)
modifiedProps.app.isGlobalCampaignLive = true
hasUserDismissedCampaignRecently.mockReturnValueOnce(false)
const wrapper = shallow(<DashboardComponent {...modifiedProps} />)
// it('does not render CampaignBase component when the campaign is not live', () => {
// const DashboardComponent = require('js/components/Dashboard/DashboardComponent')
// .default
// const modifiedProps = cloneDeep(mockProps)
// modifiedProps.app.isGlobalCampaignLive = false
// hasUserDismissedCampaignRecently.mockReturnValueOnce(false)
// const wrapper = shallow(<DashboardComponent {...modifiedProps} />)
// expect(wrapper.find(CampaignBase).length).toBe(0)
// })

// Campaign should be visible.
expect(wrapper.find(CampaignBase).length).toBe(1)
// it('hides the campaign when the onDismiss callback is called', () => {
// const DashboardComponent = require('js/components/Dashboard/DashboardComponent')
// .default
// const modifiedProps = cloneDeep(mockProps)
// modifiedProps.app.isGlobalCampaignLive = true
// hasUserDismissedCampaignRecently.mockReturnValueOnce(false)
// const wrapper = shallow(<DashboardComponent {...modifiedProps} />)

// Mock that the user dismisses the notification.
wrapper.find(CampaignBase).prop('onDismiss')()
// // Campaign should be visible.
// expect(wrapper.find(CampaignBase).length).toBe(1)

// Notification should be gone.
expect(wrapper.find(CampaignBase).length).toBe(0)
})
// // Mock that the user dismisses the notification.
// wrapper.find(CampaignBase).prop('onDismiss')()

it('changes the value of the isCampaignLive passed to widgets when the campaign is dismissed', () => {
const DashboardComponent = require('js/components/Dashboard/DashboardComponent')
.default
const modifiedProps = cloneDeep(mockProps)
modifiedProps.app.isGlobalCampaignLive = true
hasUserDismissedCampaignRecently.mockReturnValueOnce(false)
const wrapper = shallow(<DashboardComponent {...modifiedProps} />)
// // Notification should be gone.
// expect(wrapper.find(CampaignBase).length).toBe(0)
// })

expect(wrapper.find(WidgetsContainer).prop('isCampaignLive')).toBe(true)
// it('changes the value of the isCampaignLive passed to widgets when the campaign is dismissed', () => {
// const DashboardComponent = require('js/components/Dashboard/DashboardComponent')
// .default
// const modifiedProps = cloneDeep(mockProps)
// modifiedProps.app.isGlobalCampaignLive = true
// hasUserDismissedCampaignRecently.mockReturnValueOnce(false)
// const wrapper = shallow(<DashboardComponent {...modifiedProps} />)

// Mock that the user dismisses the notification.
wrapper.find(CampaignBase).prop('onDismiss')()
// expect(wrapper.find(WidgetsContainer).prop('isCampaignLive')).toBe(true)

// Prop should change.
expect(wrapper.find(WidgetsContainer).prop('isCampaignLive')).toBe(false)
})
// // Mock that the user dismisses the notification.
// wrapper.find(CampaignBase).prop('onDismiss')()

// // Prop should change.
// expect(wrapper.find(WidgetsContainer).prop('isCampaignLive')).toBe(false)
// })

it('does not render any ad components when 0 ads are enabled', () => {
getNumberOfAdsToShow.mockReturnValue(0)
Expand Down
3 changes: 3 additions & 0 deletions web/src/js/components/Donate/DonateHeartsControlsComponent.js
Expand Up @@ -28,6 +28,9 @@ const styles = theme => ({
},
})

// TODO: may want to lazy-load the "thanks" dialog to avoid
// loading it on every new tab when a HeartDonationCampaign
// is active.
class DonateHeartsControls extends React.Component {
constructor(props) {
super(props)
Expand Down
22 changes: 12 additions & 10 deletions web/src/js/components/MoneyRaised/MoneyRaisedComponent.js
@@ -1,16 +1,16 @@
import React from 'react'
import React, { Suspense, lazy } from 'react'
import PropTypes from 'prop-types'
import { commaFormatted, currencyFormatted } from 'js/utils/utils'
import DashboardPopover from 'js/components/Dashboard/DashboardPopover'
import RaisedButton from 'material-ui/RaisedButton'
import { goToInviteFriends } from 'js/navigation/navigation'
import Sparkle from 'react-sparkle'

import appTheme, {
dashboardIconActiveColor,
dashboardIconInactiveColor,
} from 'js/theme/default'

const Sparkle = lazy(() => import('react-sparkle'))

class MoneyRaised extends React.Component {
constructor(props) {
super(props)
Expand Down Expand Up @@ -150,13 +150,15 @@ class MoneyRaised extends React.Component {
>
<span style={textStyle}>{amountDonated}</span>
{celebrateMilestone ? (
<Sparkle
color={milestoneMoneyRaisedColor}
count={18}
fadeOutSpeed={40}
overflowPx={14}
flicker={false}
/>
<Suspense fallback={null}>
<Sparkle
color={milestoneMoneyRaisedColor}
count={18}
fadeOutSpeed={40}
overflowPx={14}
flicker={false}
/>
</Suspense>
) : null}
<DashboardPopover
style={popoverStyle}
Expand Down
42 changes: 24 additions & 18 deletions web/src/js/components/Widget/Widgets/Bookmarks/BookmarkChip.js
@@ -1,10 +1,8 @@
/* eslint-disable no-useless-escape */

import React from 'react'
import React, { Suspense, lazy } from 'react'
import PropTypes from 'prop-types'
import Paper from 'material-ui/Paper'
import EditIcon from 'material-ui/svg-icons/editor/mode-edit'
import EditBookmarkWidgetModal from 'js/components/Widget/Widgets/Bookmarks/EditBookmarkWidgetModal'
import {
dashboardTransparentBackground,
widgetEditButtonInactive,
Expand All @@ -13,6 +11,10 @@ import {
import hexToRgbA from 'hex-to-rgba'
import logger from 'js/utils/logger'

const EditBookmarkWidgetModal = lazy(() =>
import('js/components/Widget/Widgets/Bookmarks/EditBookmarkWidgetModal')
)

class BookmarkChip extends React.Component {
constructor(props) {
super(props)
Expand Down Expand Up @@ -171,21 +173,25 @@ class BookmarkChip extends React.Component {
{bookmark.name}
</span>
</Paper>
<EditBookmarkWidgetModal
ref={modal => {
this.editBookmarkModal = modal
}}
open={this.state.isEditing}
onEditCancel={this.onEditCancel.bind(this)}
onEditSave={this.onEditSave.bind(this)}
onDeleteBookmark={this.onDeleteBookmark.bind(this)}
currentBookmarkName={bookmark.name}
currentBookmarkLink={bookmark.link}
currentBookmarkColor={bookmarkHex}
onReorderMoveUp={this.onReorderMoveUp.bind(this)}
onReorderMoveDown={this.onReorderMoveDown.bind(this)}
setTemporaryColor={this.setTemporaryColor.bind(this)}
/>
{this.state.isEditing ? (
<Suspense fallback={null}>
<EditBookmarkWidgetModal
ref={modal => {
this.editBookmarkModal = modal
}}
open={this.state.isEditing}
onEditCancel={this.onEditCancel.bind(this)}
onEditSave={this.onEditSave.bind(this)}
onDeleteBookmark={this.onDeleteBookmark.bind(this)}
currentBookmarkName={bookmark.name}
currentBookmarkLink={bookmark.link}
currentBookmarkColor={bookmarkHex}
onReorderMoveUp={this.onReorderMoveUp.bind(this)}
onReorderMoveDown={this.onReorderMoveDown.bind(this)}
setTemporaryColor={this.setTemporaryColor.bind(this)}
/>
</Suspense>
) : null}
</span>
)
}
Expand Down