Compartilhar via


Carregamento dinâmico de pacotes na Estrutura do SharePoint

Ao criar componentes de Estrutura do SharePoint, é comum fazer referência a bibliotecas de terceiros, como Office UI Fabric reagir a controles de interface de usuário ou momento.js. Cada uma dessas bibliotecas adicionará o tamanho do arquivo de JavaScript empacotado para o componente. Como exemplo, o Moment.js soma aproximadamente 250 KB ao pacote resultante!

Observação

Um pacote de JavaScript é um arquivo JavaScript que combina um ou mais arquivos ou folhas de estilo do JavaScript. Quando você empacota uma solução SPFx, por padrão, todo o código e as bibliotecas que você importa para o projeto são empacotados em um arquivo *.js . Dividir um pacote é a operação de gerar vários arquivos *.js em vez de um, para que eles possam ser carregados individualmente.

Dependendo do componente, essas bibliotecas de terceiros podem ou não ser usadas em todas as partes do ciclo de vida dos componentes. Talvez elas sejam usadas apenas no modo de edição ou no painel de propriedades, ou talvez sejam necessárias quando um usuário clica em um link ou em um botão no componente.

Se o componente SPFx parece-se mais com um SPA (aplicativo de página única), otimizar o tamanho talvez não seja importante, mas se é uma Web Part adicionada a uma página ou até mesmo usada várias vezes em uma página, assim como uma Web Part de pesquisa, reduzir a quantidade de script carregada e a quantidade de script sendo executada em uma página faz diferença para o tempo de carregamento da página. Isso pode ter um impacto significativo nas experiências móveis.

Para melhorar a velocidade em que um componente SPFx carrega uma página, é possível aproveitar a separação de um pacote em várias partes de JavaScript, mas carregar dinamicamente esses pacotes agrupados individualmente, conforme necessário.

Separar várias Web Parts a serem carregadas individualmente

Um projeto SPFx com várias Web Parts ou extensões contém o arquivo ./config/config.JSON semelhante ao seguinte:

{
  "$schema": "https://developer.microsoft.com/json-schemas/spfx-build/config.2.0.schema.json",
  "version": "2.0",
  "bundles": {
    "my-spfx": {
      "components": [
        {
          "entrypoint": "./lib/webparts/part1/part1.js",
          "manifest": "./src/webparts/part1/part1.manifest.json"
        },
        {
          "entrypoint": "./lib/webparts/part2/part2.js",
          "manifest": "./src/webparts/part2/part2.manifest.json"
        }
      ]
    }
  },
  "externals": {},
  "localizedResources": {}
}

Na configuração acima, ambas as Web Parts são incluídas no mesmo arquivo ou pacote JavaScript. Isso significa que, se um usuário adiciona uma das Web Parts a uma página, ambas são carregadas. Em situações em que as duas Web Parts estão na mesma página ao mesmo tempo, isso é tão importante quanto tempo de carregamento baixando um arquivo, em vez de dois.

No entanto, se as Web Parts forem usadas separadamente, é melhor tê-las divididas em dois arquivos para reduzir o que a página precisa baixar para executar apenas uma delas.

Isso pode ser conseguido por meio da modificação config/config.json, para que as Web Parts sejam agrupadas como um arquivo JavaScript separado:

{
  "$schema": "https://developer.microsoft.com/json-schemas/spfx-build/config.2.0.schema.json",
  "version": "2.0",
  "bundles": {
    "my-spfx-1": {
      "components": [
        {
          "entrypoint": "./lib/webparts/part1/part1.js",
          "manifest": "./src/webparts/part1/part1.manifest.json"
        }
      ]
    },
    "my-spfx-2": {
      "components": [
        {
          "entrypoint": "./lib/webparts/part2/part2.js",
          "manifest": "./src/webparts/part2/part2.manifest.json"
        }
      ]
    }
  },
  "externals": {},
  "localizedResources": {}
}

Analisar o pacote

Para obter uma visão geral de onde começar, otimize, consulte o artigo Otimizar Estrutura do SharePoint builds para produção, que ilustra como você pode obter um mapa visual de qual parte do código ou biblioteca de terceiros ocupa espaço em seu pacote.

Carregar componentes de terceiros dinamicamente

Quando uma solução da Estrutura do SharePoint é empacotada, a cadeia de ferramentas do Build usa o webpack para gerar os pacotes. Um dos recursos webpack é a capacidade para importar dinamicamente partes de um aplicativo. Você pode implementá-la nos projetos da Estrutura do SharePoint com uma refatoração secundária.

Importação normal

No código a seguir, a biblioteca Moment.js será incluída pacote JavaScript da solução. Esse código sempre será carregado na página, mesmo que o método GetTime() nunca seja chamado.

import * as moment from moment

export default class MyClass {
  public GetTime(dateString:string){
    return moment(dateString).format("LL");
  }
}

Importação dinâmica

No entanto, no código a seguir, a biblioteca Moment.js é carregada de forma assíncrona quando o método GetTime() é chamado, o que reduz a carga inicial e o tempo de execução. Observe o comentário do código adicional de webpackChuckName

export default class MyClass {
  public async GetTime(dateString:string) {
    const moment = await import(
      /* webpackChunkName: 'my-moment' */
      'moment'
    );
    return moment(dateString).format("LL");
  }
}

Observação

Se o arquivo config/tsconfig.json tiver "module": "commonjs" e não "module": "esnext", você precisará do seguinte procedimento para que a biblioteca dinâmica seja dividida no pacote.

declare var System: any;

export default class MyClass {
  public async GetTime(dateString:string){
    const moment = await System.import(
      /* webpackChunkName: 'my-moment' */
      'moment'
    );
    return moment(dateString).format("LL");
  }
}

Verificar a separação de código e a importação dinâmica

Para verificar se a importação dinâmica está acontecendo, abra a pasta ./dist após executar a tarefa pacote gulp e procure a biblioteca carregada dinamicamente como um arquivo JavaScript separado. Na imagem a seguir, a biblioteca Moment.js está dividida no próprio arquivo.

Vários pacotes

Nem todo arquivo ou biblioteca precisa ser importado dinamicamente. Em vez disso, considere agrupar como blocos de código juntos para determinados cenários ou recursos em um único pacote.

Por exemplo, crie um arquivo **MyStuff.ts, que faz referência a um número de bibliotecas e carregue MyStuff dinamicamente. Nesse caso, as bibliotecas de terceiros e de terceiros serão agrupadas em My-Stuff.js.

// MyStuff.ts

import { Something } from 'third-party;'
import * as Foo from 'left-party';

// Other file
await import(
  /* webpackChunkName: 'my-stuff' */
  './MyStuff'
);

Carregamento dinâmico do painel de propriedades especiais

Outro caso de uso para esse recurso é importar um código dinamicamente que só é usado no painel de propriedade. Nesse caso, você só deve baixar esse código no navegador quando o painel de propriedades da Web Part estiver ativo.

No arquivo de Web Part principal, crie um método chamado loadPropertyPaneResources(). Esse método será executado antes do painel de propriedades de uma Web Part ser exibido. Isso permite o carregamento dinâmico de recursos necessários apenas para o painel de propriedades.

  1. Criar um arquivo HelloWorldWebPartPropertyPaneStuff.ts
  2. Mover todo o código relacionado ao painel de propriedades para esse arquivo
  3. Criar o método a seguir na classe da Web Part principal
protected loadPropertyPaneResources(): Promise<void> {
  return import(
    /* webpackChunkName: 'HelloWorldWebPartPropertyPaneStuff' */
    './HelloWorldWebPartPropertyPaneStuff'
  ).then(component => {
    this._propertyPaneHelper = new component.HelloWorldWebPartPropertyPaneStuff(this);
  });
}

Resumo

Ao criar soluções de SPFx com vários componentes ou se você estiver usando bibliotecas de terceiros, considere importações dinâmicas. Primeiro, analise o tamanho do conjunto resultante e use as estratégias contornadas nesta página para dividir o código em vários agrupamentos em que cada um deles só será carregado quando necessário. Isso reduzirá o tempo necessário para que um usuário final carregue e execute a página.