mirror of
https://github.com/mattermost/mattermost.git
synced 2025-02-25 18:55:24 -06:00
[MM-54493] Allow a user to disable the webapp prefetch (#24389)
* allow a user to disable the webapp prefetch if they are experiencing degraded performance on initial load --------- Co-authored-by: Mattermost Build <build@mattermost.com>
This commit is contained in:
parent
460fa05eb9
commit
9bbdca7240
@ -68,6 +68,8 @@ describe('/components/data_prefetch', () => {
|
||||
last_post_at: 1235,
|
||||
last_root_post_at: 1235,
|
||||
})],
|
||||
disableWebappPrefetchAllowed: false,
|
||||
dataPrefetchEnabled: true,
|
||||
};
|
||||
|
||||
beforeEach(() => {
|
||||
|
@ -21,6 +21,9 @@ type Props = {
|
||||
sidebarLoaded: boolean;
|
||||
|
||||
unreadChannels: Channel[];
|
||||
|
||||
disableWebappPrefetchAllowed: boolean;
|
||||
dataPrefetchEnabled: boolean;
|
||||
actions: {
|
||||
prefetchChannelPosts: (channelId: string, delay?: number) => Promise<any>;
|
||||
trackPreloadedChannels: (prefetchQueueObj: Record<string, string[]>) => void;
|
||||
@ -52,15 +55,20 @@ export default class DataPrefetch extends React.PureComponent<Props> {
|
||||
private prefetchTimeout?: number;
|
||||
|
||||
async componentDidUpdate(prevProps: Props) {
|
||||
const {currentChannelId, prefetchQueueObj, sidebarLoaded} = this.props;
|
||||
const {currentChannelId, prefetchQueueObj, sidebarLoaded, disableWebappPrefetchAllowed, dataPrefetchEnabled} = this.props;
|
||||
const enablePrefetch = (!disableWebappPrefetchAllowed) || (disableWebappPrefetchAllowed && dataPrefetchEnabled);
|
||||
if (currentChannelId && sidebarLoaded && (!prevProps.currentChannelId || !prevProps.sidebarLoaded)) {
|
||||
queue.add(async () => this.prefetchPosts(currentChannelId));
|
||||
await loadProfilesForSidebar();
|
||||
this.prefetchData();
|
||||
if (enablePrefetch) {
|
||||
this.prefetchData();
|
||||
}
|
||||
} else if (prevProps.prefetchQueueObj !== prefetchQueueObj) {
|
||||
clearTimeout(this.prefetchTimeout);
|
||||
await queue.clear();
|
||||
this.prefetchData();
|
||||
if (enablePrefetch) {
|
||||
this.prefetchData();
|
||||
}
|
||||
}
|
||||
|
||||
if (currentChannelId && sidebarLoaded && (!prevProps.currentChannelId || !prevProps.sidebarLoaded)) {
|
||||
|
@ -9,9 +9,11 @@ import type {Channel, ChannelMembership} from '@mattermost/types/channels';
|
||||
import type {PostList} from '@mattermost/types/posts';
|
||||
import type {RelationOneToOne} from '@mattermost/types/utilities';
|
||||
|
||||
import {Preferences} from 'mattermost-redux/constants';
|
||||
import {getCurrentChannelId, getUnreadChannels} from 'mattermost-redux/selectors/entities/channels';
|
||||
import {getMyChannelMemberships} from 'mattermost-redux/selectors/entities/common';
|
||||
import {isCollapsedThreadsEnabled} from 'mattermost-redux/selectors/entities/preferences';
|
||||
import {isPerformanceDebuggingEnabled} from 'mattermost-redux/selectors/entities/general';
|
||||
import {getBool, isCollapsedThreadsEnabled} from 'mattermost-redux/selectors/entities/preferences';
|
||||
import {isChannelMuted} from 'mattermost-redux/utils/channel_utils';
|
||||
import {memoizeResult} from 'mattermost-redux/utils/helpers';
|
||||
|
||||
@ -82,6 +84,7 @@ function mapStateToProps(state: GlobalState) {
|
||||
const unreadChannels = getUnreadChannels(state, lastUnreadChannel);
|
||||
const prefetchQueueObj = prefetchQueue(unreadChannels, memberships, isCollapsedThreadsEnabled(state));
|
||||
const prefetchRequestStatus = state.views.channel.channelPrefetchStatus;
|
||||
const disableWebappPrefetchAllowed = isPerformanceDebuggingEnabled(state);
|
||||
|
||||
return {
|
||||
currentChannelId: getCurrentChannelId(state),
|
||||
@ -89,6 +92,8 @@ function mapStateToProps(state: GlobalState) {
|
||||
prefetchRequestStatus,
|
||||
sidebarLoaded: isSidebarLoaded(state),
|
||||
unreadChannels,
|
||||
disableWebappPrefetchAllowed,
|
||||
dataPrefetchEnabled: getBool(state, Preferences.CATEGORY_ADVANCED_SETTINGS, Preferences.ADVANCED_DATA_PREFETCH, true),
|
||||
};
|
||||
}
|
||||
|
||||
|
@ -7,7 +7,7 @@ import type {ActionCreatorsMapObject, Dispatch} from 'redux';
|
||||
|
||||
import {savePreferences} from 'mattermost-redux/actions/preferences';
|
||||
import {updateUserActive, revokeAllSessionsForUser} from 'mattermost-redux/actions/users';
|
||||
import {getConfig} from 'mattermost-redux/selectors/entities/general';
|
||||
import {getConfig, isPerformanceDebuggingEnabled} from 'mattermost-redux/selectors/entities/general';
|
||||
import {get, getUnreadScrollPositionPreference, makeGetCategory, syncedDraftsAreAllowed} from 'mattermost-redux/selectors/entities/preferences';
|
||||
import {getCurrentUser} from 'mattermost-redux/selectors/entities/users';
|
||||
import type {ActionFunc} from 'mattermost-redux/types/actions';
|
||||
@ -27,6 +27,7 @@ function makeMapStateToProps() {
|
||||
|
||||
const enablePreviewFeatures = config.EnablePreviewFeatures === 'true';
|
||||
const enableUserDeactivation = config.EnableUserDeactivation === 'true';
|
||||
const disableWebappPrefetchAllowed = isPerformanceDebuggingEnabled(state);
|
||||
const enableJoinLeaveMessage = config.EnableJoinLeaveMessageByDefault === 'true';
|
||||
|
||||
return {
|
||||
@ -41,6 +42,8 @@ function makeMapStateToProps() {
|
||||
enablePreviewFeatures,
|
||||
enableUserDeactivation,
|
||||
syncedDraftsAreAllowed: syncedDraftsAreAllowed(state),
|
||||
disableWebappPrefetchAllowed,
|
||||
dataPrefetchEnabled: get(state, Preferences.CATEGORY_ADVANCED_SETTINGS, 'data_prefetch', 'true'),
|
||||
};
|
||||
};
|
||||
}
|
||||
|
@ -47,6 +47,8 @@ describe('components/user_settings/display/UserSettingsDisplay', () => {
|
||||
enablePreviewFeatures: false,
|
||||
enableUserDeactivation: false,
|
||||
syncedDraftsAreAllowed: true,
|
||||
disableWebappPrefetchAllowed: false,
|
||||
dataPrefetchEnabled: 'true',
|
||||
};
|
||||
|
||||
test('should have called handleSubmit', async () => {
|
||||
|
@ -36,6 +36,7 @@ type Settings = {
|
||||
formatting: Props['formatting'];
|
||||
join_leave: Props['joinLeave'];
|
||||
sync_drafts: Props['syncDrafts'];
|
||||
data_prefetch: Props['dataPrefetchEnabled'];
|
||||
};
|
||||
|
||||
export type Props = {
|
||||
@ -54,6 +55,8 @@ export type Props = {
|
||||
enablePreviewFeatures: boolean;
|
||||
enableUserDeactivation: boolean;
|
||||
syncedDraftsAreAllowed: boolean;
|
||||
disableWebappPrefetchAllowed: boolean;
|
||||
dataPrefetchEnabled: string;
|
||||
actions: {
|
||||
savePreferences: (userId: string, preferences: PreferenceType[]) => Promise<ActionResult>;
|
||||
updateUserActive: (userId: string, active: boolean) => Promise<ActionResult>;
|
||||
@ -87,6 +90,7 @@ export default class AdvancedSettingsDisplay extends React.PureComponent<Props,
|
||||
formatting: this.props.formatting,
|
||||
join_leave: this.props.joinLeave,
|
||||
sync_drafts: this.props.syncDrafts,
|
||||
data_prefetch: this.props.dataPrefetchEnabled,
|
||||
[Preferences.UNREAD_SCROLL_POSITION]: this.props.unreadScrollPosition,
|
||||
};
|
||||
|
||||
@ -575,6 +579,93 @@ export default class AdvancedSettingsDisplay extends React.PureComponent<Props,
|
||||
);
|
||||
};
|
||||
|
||||
renderDataPrefetchSection = () => {
|
||||
const active = this.props.activeSection === AdvancedSections.DATA_PREFETCH;
|
||||
let max = null;
|
||||
if (active) {
|
||||
max = (
|
||||
<SettingItemMax
|
||||
title={
|
||||
<FormattedMessage
|
||||
id='user.settings.advance.dataPrefetch.Title'
|
||||
defaultMessage='Allow Mattermost to prefetch channel posts'
|
||||
/>
|
||||
}
|
||||
inputs={[
|
||||
<fieldset key='syncDraftsSetting'>
|
||||
<legend className='form-legend hidden-label'>
|
||||
<FormattedMessage
|
||||
id='user.settings.advance.dataPrefetch.Title'
|
||||
defaultMessage='Allow Mattermost to prefetch channel posts'
|
||||
/>
|
||||
</legend>
|
||||
<div className='radio'>
|
||||
<label>
|
||||
<input
|
||||
id='dataPrefetchOn'
|
||||
type='radio'
|
||||
name='dataPrefetch'
|
||||
checked={this.state.settings.data_prefetch !== 'false'}
|
||||
onChange={this.updateSetting.bind(this, 'data_prefetch', 'true')}
|
||||
/>
|
||||
<FormattedMessage
|
||||
id='user.settings.advance.on'
|
||||
defaultMessage='On'
|
||||
/>
|
||||
</label>
|
||||
<br/>
|
||||
</div>
|
||||
<div className='radio'>
|
||||
<label>
|
||||
<input
|
||||
id='dataPrefetchOff'
|
||||
type='radio'
|
||||
name='dataPrefetch'
|
||||
checked={this.state.settings.data_prefetch === 'false'}
|
||||
onChange={this.updateSetting.bind(this, 'data_prefetch', 'false')}
|
||||
/>
|
||||
<FormattedMessage
|
||||
id='user.settings.advance.off'
|
||||
defaultMessage='Off'
|
||||
/>
|
||||
</label>
|
||||
<br/>
|
||||
</div>
|
||||
<div className='mt-5'>
|
||||
<FormattedMessage
|
||||
id='user.settings.advance.dataPrefetch.Desc'
|
||||
defaultMessage='When disabled, messages and user information will be fetched on each channel load instead of being pre-fetched on startup. Disabling prefetch is recommended for users with a high unread channel count in order to improve application performance.'
|
||||
/>
|
||||
</div>
|
||||
</fieldset>,
|
||||
]}
|
||||
setting={AdvancedSections.DATA_PREFETCH}
|
||||
submit={this.handleSubmit.bind(this, ['data_prefetch'])}
|
||||
saving={this.state.isSaving}
|
||||
serverError={this.state.serverError}
|
||||
updateSection={this.handleUpdateSection}
|
||||
/>
|
||||
);
|
||||
}
|
||||
|
||||
return (
|
||||
<SettingItem
|
||||
active={active}
|
||||
areAllSectionsInactive={this.props.activeSection === ''}
|
||||
title={
|
||||
<FormattedMessage
|
||||
id='user.settings.advance.dataPrefetch.Title'
|
||||
defaultMessage='Allow Mattermost to prefetch channel posts'
|
||||
/>
|
||||
}
|
||||
describe={this.renderOnOffLabel(this.state.settings.data_prefetch)}
|
||||
section={AdvancedSections.DATA_PREFETCH}
|
||||
updateSection={this.handleUpdateSection}
|
||||
max={max}
|
||||
/>
|
||||
);
|
||||
};
|
||||
|
||||
renderFeatureLabel(feature: string): ReactNode {
|
||||
switch (feature) {
|
||||
case 'MARKDOWN_PREVIEW':
|
||||
@ -895,6 +986,15 @@ export default class AdvancedSettingsDisplay extends React.PureComponent<Props,
|
||||
}
|
||||
}
|
||||
|
||||
let dataPrefetchSection = null;
|
||||
let dataPrefetchSectionDivider = null;
|
||||
if (this.props.disableWebappPrefetchAllowed) {
|
||||
dataPrefetchSection = this.renderDataPrefetchSection();
|
||||
if (syncDraftsSection) {
|
||||
dataPrefetchSectionDivider = <div className='divider-light'/>;
|
||||
}
|
||||
}
|
||||
|
||||
return (
|
||||
<div>
|
||||
<div className='modal-header'>
|
||||
@ -953,6 +1053,8 @@ export default class AdvancedSettingsDisplay extends React.PureComponent<Props,
|
||||
{unreadScrollPositionSection}
|
||||
{syncDraftsSectionDivider}
|
||||
{syncDraftsSection}
|
||||
{dataPrefetchSectionDivider}
|
||||
{dataPrefetchSection}
|
||||
<div className='divider-dark'/>
|
||||
{makeConfirmationModal}
|
||||
</div>
|
||||
|
@ -5208,6 +5208,8 @@
|
||||
"user_profile.send.dm.yourself": "Send yourself a message",
|
||||
"user.settings.advance.confirmDeactivateAccountTitle": "Confirm Deactivation",
|
||||
"user.settings.advance.confirmDeactivateDesc": "Are you sure you want to deactivate your account? This can only be reversed by your System Administrator.",
|
||||
"user.settings.advance.dataPrefetch.Desc": "When disabled, messages and user information will be fetched on each channel load instead of being pre-fetched on startup. Disabling prefetch is recommended for users with a high unread channel count in order to improve application performance.",
|
||||
"user.settings.advance.dataPrefetch.Title": "Allow Mattermost to prefetch channel posts",
|
||||
"user.settings.advance.deactivate_member_modal.deactivateButton": "Yes, deactivate my account",
|
||||
"user.settings.advance.deactivateAccountTitle": "Deactivate Account",
|
||||
"user.settings.advance.deactivateDesc": "Deactivating your account removes your ability to log in to this server and disables all email and mobile notifications. To reactivate your account, contact your System Administrator.",
|
||||
|
@ -55,6 +55,7 @@ const Preferences = {
|
||||
ADVANCED_CODE_BLOCK_ON_CTRL_ENTER: 'code_block_ctrl_enter',
|
||||
ADVANCED_SEND_ON_CTRL_ENTER: 'send_on_ctrl_enter',
|
||||
ADVANCED_SYNC_DRAFTS: 'sync_drafts',
|
||||
ADVANCED_DATA_PREFETCH: 'data_prefetch',
|
||||
CATEGORY_WHATS_NEW_MODAL: 'whats_new_modal',
|
||||
HAS_SEEN_SIDEBAR_WHATS_NEW_MODAL: 'has_seen_sidebar_whats_new_modal',
|
||||
|
||||
|
@ -1014,6 +1014,7 @@ export const AdvancedSections = {
|
||||
PREVIEW_FEATURES: 'advancedPreviewFeatures',
|
||||
PERFORMANCE_DEBUGGING: 'performanceDebugging',
|
||||
SYNC_DRAFTS: 'syncDrafts',
|
||||
DATA_PREFETCH: 'dataPrefetch',
|
||||
};
|
||||
|
||||
export const RHSStates = {
|
||||
|
Loading…
Reference in New Issue
Block a user