El patrón consiste en la carga diferida de recursos, es decir, solo cuando el usuario necesita alguna parte de la interfaz.
Nuestra página puede contener datos o componentes que no son necesarios en este momento. Por ejemplo, puede ser una parte de la interfaz que el usuario no verá, a menos que haga clic en ella o se desplace hasta ella.
Estas partes de la interfaz pueden ser reproductores de video, chats o una parte de la interfaz que aparece con un clic.
La carga activa de estos recursos, si pesan mucho, puede bloquear el hilo principal y aumentar el tiempo antes de interactuar con la página.
Esto puede afectar negativamente a métricas como:
En lugar de cargar todos los recursos inmediatamente, puede cargarlos en momentos más apropiados, por ejemplo:
El usuario hace clic en el componente por primera vez.
El componente está en la ventana gráfica.
O posponga la descarga del componente hasta que el navegador esté inactivo (a través de requestIdleCallback )
Varias opciones sobre cómo podemos cargar recursos:
Inmediatamente: la forma habitual de cargar scripts
Lazy (para enrutador): se carga cuando el usuario visita las páginas
Lazy ( ) -
Lazy (viewport) -
Prefetch - , critical resources
Preload -
. Google Docs, 500:
- .
youtube :
JavaScript SDK. .
Calibre app 30% " ". CSS HTML, .
Postmark , help , . 314 - . UX CSS + HTML , . TTI (Time To Interactive) 7.7 3.7 .
NE Digital react-scroll . , , 7.
handleScrollToTop() {
import('react-scroll').then(scroll => {
scroll.animateScroll.scrollToTop({
})
})
}
?
JS
, lodash.sortby, .
const btn = document.querySelector('button');
btn.addEventListener('click', e => {
e.preventDefault();
import('lodash.sortby')
.then(module => module.default)
.then(sortInput()) // use the imported dependency
.catch(err => { console.log(err) });
});
:
const loginBtn = document.querySelector('#login');
loginBtn.addEventListener('click', () => {
const loader = new scriptLoader();
loader.load([
'//apis.google.com/js/client:platform.js?onload=showLoginScreen'
]).then(({length}) => {
console.log(${length} scripts loaded!);
});
});
React
, :
<MessageList>
<MessageInput>
<EmojiPicker> ( emoji-mart 98 - gzip')
, :
import MessageList from './MessageList';
import MessageInput from './MessageInput';
import EmojiPicker from './EmojiPicker';
const Channel = () => {
...
return (
<div>
<MessageList />
<MessageInput />
{emojiPickerOpen && <EmojiPicker />}
</div>
);
};
React.lazy code-splitting . React.lazy . Suspense , EmojiPicker:
import React, { lazy, Suspense } from 'react';
import MessageList from './MessageList';
import MessageInput from './MessageInput';
const EmojiPicker = lazy(
() => import('./EmojiPicker')
);
const Channel = () => {
...
return (
<div>
<MessageList />
<MessageInput />
{emojiPickerOpen && (
<Suspense fallback={<div>Loading...</div>}>
<EmojiPicker />
</Suspense>
)}
</div>
);
};
EmojiPicker <MessageInput>, :
import React, { useState, createElement } from 'react';
import MessageList from './MessageList';
import MessageInput from './MessageInput';
import ErrorBoundary from './ErrorBoundary';
const Channel = () => {
const [emojiPickerEl, setEmojiPickerEl] = useState(null);
const openEmojiPicker = () => {
import(/* webpackChunkName: "emoji-picker" */ './EmojiPicker')
.then(module => module.default)
.then(emojiPicker => {
setEmojiPickerEl(createElement(emojiPicker));
});
};
const closeEmojiPickerHandler = () => {
setEmojiPickerEl(null);
};
return (
<ErrorBoundary>
<div>
<MessageList />
<MessageInput onClick={openEmojiPicker} />
{emojiPickerEl}
</div>
</ErrorBoundary>
);
};
Vue
Hay varias formas de implementar este patrón en vue. Uno de ellos es importar dinámicamente el EmojiPicker. Cuando necesite renderizarlo, vue cargará dinámicamente el fragmento requerido.
Con v-if = "show" podemos controlar la visualización del componente EmojiPicker haciendo clic en el botón:
<template>
<div>
<button @click="show = true">Load Emoji Picker</button>
<div v-if="show">
<emojipicker></emojipicker>
</div>
</div>
</template>
<script>
export default {
data: () => ({ show: false }),
components: {
Emojipicker: () => import('./Emojipicker')
}
};
</script>
Este patrón se puede usar con la mayoría de los marcos que admiten la carga dinámica de componentes, incluido Angular .
Continuará...