aguarde...

15 de abril de 2019

Inline SVG… em cache

Inline SVG… em cache

Começando com SVG embutido

Como isso…





  Inline SVG

  ...
 
  

É muito fácil jogar texto no cache do navegador como um arquivo

No HTML acima, o seletor .icon-alarmnos buscará a parte inteira desse ícone.

const iconHTML = document.querySelector(".icon-alarm").outerHTML;

Então, podemos inserir no cache do navegador assim:

if ("caches" in window) {
  caches.open('static').then(function(cache) {
    cache.put("/icons/icon-wheelchair.svg", new Response(
      iconHTML,
      { headers: {'Content-Type': 'image/svg+xml'} }
    ));
  }
}

Veja o caminho do arquivo /icons/icon-wheelchair.svg? Isso é meio que apenas inventado. Mas realmente será colocado no cache naquele local.#Vamos nos certificar de que o navegador extraia esse arquivo do cache quando solicitado

Vamos registrar um Service Worker em nossas páginas:

if (navigator.serviceWorker) {   
  navigator.serviceWorker.register('/sw.js', {
    scope: '/'
  });
}

O próprio service worker será bem pequeno, apenas um correspondente de cache:

self.addEventListener("fetch", event => {
  let request = event.request;

  event.respondWith(
    caches.match(request).then(response => {
      return response || fetch(request);
    })
  );
});

#Mas … nós nunca pedimos esse arquivo, porque nossos ícones são inline.

Verdade. Mas e se outras páginas se beneficiassem desse cache? Por exemplo, um ícone SVG poderia ser colocado na página assim:

Uma vez que /icons/icon-alarm.svgestá pronto para ser colocado em cache, o navegador ficará feliz em removê-lo do cache e exibi-lo.

(Fiquei espantado com o fato de isso funcionar. O Edge não gosta de elementos que se ligam a arquivos, mas isso acabará em breve.)

E mesmo que o arquivo não esteja no cache, presumindo que nós realmente jogamos esse arquivo no sistema de arquivos, provavelmente o resultado de algum tipo de “include” (usei o Nunjucks na demo).

Mas … e SVG embutido não são exatamente os mesmos

Verdade. O que eu gosto sobre o acima é que ele está fazendo uso do cache e os ícones devem renderizar perto de imediatamente. E há algumas coisas que você pode estilizar dessa maneira – por exemplo, definir o preenchimento no ícone pai deve passar pelo DOM de sombra que cria e colorir os elementos SVG dentro dele.

Ainda assim, não é o mesmo. A sombra DOM é uma grande barreira em comparação com o SVG embutido.

Então, aprimore-os! Poderíamos carregar de forma assíncrona um script que encontre cada ícone SVG, Ajaxs para o SVG necessário e substitua o material …

const icons = document.querySelectorAll("svg.icon");

icons.forEach(icon => {
  const url = icon.querySelector("use").getAttribute("xlink:href"); // Might wanna look for href also
  fetch(url)
    .then(response => response.text())
    .then(data => {
      // This is probably a bit layout-thrashy. Someone smarter than me could probably fix that up.

      // Replace the  with inline SVG
      const newEl = document.createElement("span");
      newEl.innerHTML = data;
      icon.parentNode.replaceChild(newEl, icon);

      // Remove the s
      const parent = newEl.parentNode;
      while (newEl.firstChild) parent.insertBefore(newEl.firstChild, newEl);
      parent.removeChild(newEl);
    });
});

Agora, supondo que esse JavaScript seja executado corretamente, essa página tem o SVG embutido disponível da mesma forma que a página original.

Posted in Blog
Write a comment