Importar no padrão de interação (Parte 1)

Link para o original





O padrão consiste em carregamento lento de recursos, ou seja, apenas quando o usuário precisa de alguma parte da interface.





Nossa página pode conter dados ou componentes que não são necessários no momento. Por exemplo, pode ser uma parte da interface que o usuário não verá, a menos que clique nela ou role até ela.





Essas partes da interface podem ser reprodutores de vídeo, bate-papos ou uma parte da interface que aparece com um clique.





O carregamento ativo desses recursos, se pesarem muito, pode bloquear o thread principal e aumentar o tempo antes de interagir com a página.





Isso pode afetar negativamente métricas como:





  • FID (primeiro atraso de entrada)





  • TBT (Tempo Total de Bloqueio)





  • TTI (Time To Interactive)





Em vez de carregar todos os recursos imediatamente, você pode carregá-los em momentos mais apropriados, por exemplo:





  • O usuário clica no componente pela primeira vez





  • O componente está na janela de visualização





  • Ou adie o download do componente até que o navegador fique ocioso (via requestIdleCallback )





Várias opções de como podemos carregar recursos:





  • Imediatamente - a maneira usual de carregar scripts





  • Lazy (para roteador) - carrega quando o usuário visita as 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

Existem várias maneiras de implementar esse padrão. Um deles é importar dinamicamente o EmojiPicker. Quando você precisar renderizá-lo, o vue carregará dinamicamente o trecho necessário.





Com v-if = "show" podemos controlar a exibição do componente EmojiPicker clicando no botão:





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

      
      



Esse padrão pode ser usado com a maioria das estruturas que suportam carregamento dinâmico de componentes, incluindo Angular .





Continua...








All Articles