0
0
Fork 0

feat: Cache status height to avoid expensive renders (#4439)

* feat: Cache status height to avoid expensive renders

* feat: Escape content and emojify in reducers

* fix(css): Remove backface-visibility: hidden from .scrollable

* fix(statuses): Avoid creating DOMParses inside a loop
This commit is contained in:
Sorin Davidoi 2017-08-07 20:32:03 +02:00 committed by Eugen Rochko
parent 5942347407
commit 8eb6d171e6
15 changed files with 83 additions and 57 deletions

View file

@ -13,6 +13,8 @@ import {
CONTEXT_FETCH_SUCCESS,
STATUS_MUTE_SUCCESS,
STATUS_UNMUTE_SUCCESS,
STATUS_SET_HEIGHT,
STATUSES_CLEAR_HEIGHT,
} from '../actions/statuses';
import {
TIMELINE_REFRESH_SUCCESS,
@ -33,7 +35,11 @@ import {
FAVOURITED_STATUSES_EXPAND_SUCCESS,
} from '../actions/favourites';
import { SEARCH_FETCH_SUCCESS } from '../actions/search';
import emojify from '../emoji';
import { Map as ImmutableMap, fromJS } from 'immutable';
import escapeTextContentForBrowser from 'escape-html';
const domParser = new DOMParser();
const normalizeStatus = (state, status) => {
if (!status) {
@ -49,7 +55,9 @@ const normalizeStatus = (state, status) => {
}
const searchContent = [status.spoiler_text, status.content].join(' ').replace(/<br \/>/g, '\n').replace(/<\/p><p>/g, '\n\n');
normalStatus.search_index = new DOMParser().parseFromString(searchContent, 'text/html').documentElement.textContent;
normalStatus.search_index = domParser.parseFromString(searchContent, 'text/html').documentElement.textContent;
normalStatus.contentHtml = emojify(normalStatus.content);
normalStatus.spoilerHtml = emojify(escapeTextContentForBrowser(normalStatus.spoiler_text || ''));
return state.update(status.id, ImmutableMap(), map => map.mergeDeep(fromJS(normalStatus)));
};
@ -82,6 +90,18 @@ const filterStatuses = (state, relationship) => {
return state;
};
const setHeight = (state, id, height) => {
return state.update(id, ImmutableMap(), map => map.set('height', height));
};
const clearHeights = (state) => {
state.forEach(status => {
state = state.deleteIn([status.get('id'), 'height']);
});
return state;
};
const initialState = ImmutableMap();
export default function statuses(state = initialState, action) {
@ -120,6 +140,10 @@ export default function statuses(state = initialState, action) {
return deleteStatus(state, action.id, action.references);
case ACCOUNT_BLOCK_SUCCESS:
return filterStatuses(state, action.relationship);
case STATUS_SET_HEIGHT:
return setHeight(state, action.id, action.height);
case STATUSES_CLEAR_HEIGHT:
return clearHeights(state);
default:
return state;
}