fix slow re-renders when toggling content languages

Use local state copy for content language toggles so the UI stays
responsive, deferring the expensive langPrefs update to the next frame
via requestAnimationFrame.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
Samuel Newman
2026-03-25 16:15:02 +02:00
parent cc5580848c
commit 4d45c037ec
+21 -4
View File
@@ -34,6 +34,23 @@ export function LanguageSettingsScreen({}: Props) {
const langPrefs = useLanguagePrefs() const langPrefs = useLanguagePrefs()
const setLangPrefs = useLanguagePrefsApi() const setLangPrefs = useLanguagePrefsApi()
// changing langPrefs causes a slow re-render, so we use a local state copy
// and update that first to drive the UI on this screen to keep it snappy
const [contentLanguages, _setContentLanguages] = useState(
langPrefs.contentLanguages,
)
const setContentLanguages = useCallback(
(languages: string[]) => {
_setContentLanguages(languages)
// TODO: try using startTransition/useOptimistic when we switch to New Arch
// Old arch doesn't support concurrent react features so use rAF instead
requestAnimationFrame(() => {
setLangPrefs.setContentLanguages(languages)
})
},
[setLangPrefs],
)
const contentLanguagePrefsControl = useDialogControl() const contentLanguagePrefsControl = useDialogControl()
const onChangePrimaryLanguage = useCallback( const onChangePrimaryLanguage = useCallback(
@@ -167,7 +184,7 @@ export function LanguageSettingsScreen({}: Props) {
</Trans> </Trans>
</Text> </Text>
{langPrefs.contentLanguages.length === 0 && ( {contentLanguages.length === 0 && (
<Admonition type="info"> <Admonition type="info">
<Trans>All languages will be shown in your feeds.</Trans> <Trans>All languages will be shown in your feeds.</Trans>
</Admonition> </Admonition>
@@ -176,8 +193,8 @@ export function LanguageSettingsScreen({}: Props) {
<View style={[a.w_full, web({maxWidth: 400})]}> <View style={[a.w_full, web({maxWidth: 400})]}>
<Toggle.Group <Toggle.Group
label={_(msg`Select content languages`)} label={_(msg`Select content languages`)}
values={langPrefs.contentLanguages} values={contentLanguages}
onChange={setLangPrefs.setContentLanguages}> onChange={setContentLanguages}>
<Toggle.PanelGroup> <Toggle.PanelGroup>
{possibleLanguages.map((language, index) => { {possibleLanguages.map((language, index) => {
const name = languageName(language, langPrefs.appLanguage) const name = languageName(language, langPrefs.appLanguage)
@@ -222,7 +239,7 @@ export function LanguageSettingsScreen({}: Props) {
} }
currentLanguages={langPrefs.contentLanguages} currentLanguages={langPrefs.contentLanguages}
onSelectLanguages={languages => { onSelectLanguages={languages => {
setLangPrefs.setContentLanguages(languages) setContentLanguages(languages)
setRecentLanguages(recent => [ setRecentLanguages(recent => [
...new Set([...recent, ...languages]), ...new Set([...recent, ...languages]),
]) ])