Importar en el patrón de interacción (parte 1)

Enlace al original





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:





  • FID (retardo de la primera entrada)





  • TBT (tiempo total de bloqueo)





  • TTI (tiempo para interactuar)





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 :





android.com :





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

Promise, .





, 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>
  );
};

      
      



code-splitting.





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á...








All Articles