Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- document.addEventListener('DOMContentLoaded', function () {
- var DEBUG = false; // true = exibe logs no console
- var DEPTH = 2; // profundidade do prefetch (1 = só links da página atual, 2 = links dos links, etc.)
- var DOMAIN = window.location.origin;
- var prefetched = new Set([window.location.href]);
- // Mapeamento de seletores para o valor correto do atributo 'as'
- // usado no <link rel="prefetch"> — informa ao browser o tipo do recurso
- var RESOURCE_SELECTORS = [
- { selector: 'link[rel="stylesheet"][href]', as: 'style' },
- { selector: 'script[src]', as: 'script' },
- { selector: 'img[src]', as: 'image' },
- ];
- // -------------------------------------------------------------------------
- // Injeta um <link rel="prefetch"> no <head> para páginas internas (same-origin)
- // O browser trata com prioridade Idle, não compete com recursos ativos,
- // e respeita corretamente os headers de cache HTTP.
- // -------------------------------------------------------------------------
- function prefetchOne(url) {
- if (prefetched.has(url)) return;
- prefetched.add(url);
- var link = document.createElement('link');
- link.rel = 'prefetch';
- link.href = url;
- link.as = 'document';
- document.head.appendChild(link);
- if (DEBUG) console.log('[prefetch:internal] ' + url);
- }
- // -------------------------------------------------------------------------
- // Injeta um <link rel="prefetch"> para recursos externos (CSS, fontes, scripts)
- // Sem o atributo 'as' para recursos cujo tipo o browser não consegue inferir
- // (ex: Google Fonts), ou com 'as' correto quando identificado.
- // -------------------------------------------------------------------------
- function prefetchResource(url, as) {
- if (prefetched.has(url)) return;
- prefetched.add(url);
- var link = document.createElement('link');
- link.rel = 'prefetch';
- link.href = url;
- if (as) link.as = as;
- document.head.appendChild(link);
- if (DEBUG) console.log('[prefetch:resource] ' + url);
- }
- // -------------------------------------------------------------------------
- // Percorre o DOM de uma página já parseada e faz prefetch de todos os
- // recursos estáticos encontrados (CSS, scripts, imagens, fontes externas)
- // -------------------------------------------------------------------------
- function prefetchResources(doc, baseUrl) {
- RESOURCE_SELECTORS.forEach(function (def) {
- doc.querySelectorAll(def.selector).forEach(function (el) {
- try {
- var attr = el.href || el.src;
- var resolved = new URL(attr, baseUrl).href;
- prefetchResource(resolved, def.as);
- } catch (_) {}
- });
- });
- }
- // -------------------------------------------------------------------------
- // Busca o HTML de uma URL, extrai links internos (recursivo até DEPTH)
- // e faz prefetch de todos os recursos estáticos da página.
- // Usa DOMParser para evitar execução de scripts do HTML remoto.
- // -------------------------------------------------------------------------
- function prefetchDeep(url, depth) {
- if (depth === 0 || prefetched.has(url)) return;
- prefetchOne(url);
- if (depth <= 1) return;
- fetch(url)
- .then(function (response) {
- if (!response.ok) throw new Error('Status ' + response.status);
- return response.text();
- })
- .then(function (html) {
- var parser = new DOMParser();
- var doc = parser.parseFromString(html, 'text/html');
- // Recursos estáticos da página (CSS, fontes, scripts, imagens)
- prefetchResources(doc, url);
- // Links internos — continua a recursão
- doc.querySelectorAll('a[href]').forEach(function (a) {
- try {
- var resolved = new URL(a.getAttribute('href'), url).href;
- if (resolved.startsWith(DOMAIN)) {
- prefetchDeep(resolved, depth - 1);
- }
- } catch (_) {
- // href inválido (javascript:, mailto: etc.) — ignora
- }
- });
- })
- .catch(function (error) {
- if (DEBUG) console.warn('[prefetch] falha em ' + url, error);
- });
- }
- // -------------------------------------------------------------------------
- // Ponto de entrada: percorre todos os links da página atual
- // -------------------------------------------------------------------------
- document.querySelectorAll('a[href]').forEach(function (a) {
- try {
- var resolved = new URL(a.getAttribute('href'), DOMAIN).href;
- if (resolved.startsWith(DOMAIN)) {
- prefetchDeep(resolved, DEPTH);
- }
- } catch (_) {
- // ignora hrefs inválidos
- }
- });
- });
Advertisement
Add Comment
Please, Sign In to add comment