Lien vers du Javas­cript

Problé­ma­tique du jour : Inter­cep­ter l’ap­pel à des liens via Javas­cript.

Mon cas d’usage : J’ai des conte­nus (images, vidéos, audio, polices de carac­tères) stockés côté client (indexedDB, webSQL ou DOMS­to­rage) que je souhaite insé­rer dans mes pages.

(billet mis à jour au fur et à mesure des réponses)

Quelques solu­tions :

Data:URI

Je récu­père ma donnée, je la trans­forme en base64, et je remplace le lien stan­dard par un lien en data:uri.

Deux défauts : Je stocke N fois la donnée dans le DOM où N est le nombre d’ap­pa­ri­tion de l’image ou de la ressource dans mes pages HTML/CSS. Pour ne rien gâcher, on stocke en base64 donc avec 30% de poids en plus. De plus, même si je n’ai pas de test à montrer, on s’est déjà pris les pieds dans le tapis à cause de très mauvaises perfor­mances de pages avec beau­coup de data:uri, spécia­le­ment sur Fire­fox (proba­ble­ment sur les polices de carac­tères)

Blob + crea­teObjectURL

Je récu­père ma donnée, je créé un Blob à partir de cette donnée, je passe par URL.crea­teObjectURL pour créer une URL dédiée et j’uti­lise cette dernière quand je réfé­rence ma ressource.

On résout les problèmes du data:uri mais on se coupe de IE 9, IE mobile et iOS 5. Pas gravis­sime mais j’au­rai préféré éviter.

Par contre la solu­tion ne fonc­tion­nera de toutes façons pas pour les images ou polices de carac­tères réfé­ren­cées depuis les CSS (sauf à construire les CSS via Javas­cript mais là on entre dans des usines à gaz).

Cas spéci­fique des vidéo et audio

Les deux solu­tions me posent de toutes façons un sérieux problème pour les vidéo et les audio, qui peuvent être de gros volume. Je me vois mal sortir d’in­dexedDB des dizaines de méga­oc­tets (au mieux) pour construire un blob juste et avoir une URL dans ma balise HTML sans même savoir si l’uti­li­sa­teur tentera effec­ti­ve­ment de lire la vidéo ou le fichier audio.

Pour les vidéos et les audio (mais unique­ment ces deux types de contenu) je peux réflé­chir à mettre un lien vers une vidéo de taille quasi nulle et le chan­ger dès que la vidéo est acti­vée. J’ai toute­fois un peu peur des effets de bords. Il va falloir aussi bosser en amont pour que la première image s’af­fiche bien dans le lecteur vidéo malgré l’ab­sence de la vidéo complète.

Bidouille

Pour l’ins­tant ma solu­tion serait :

  • Pour les images et polices de carac­tères dans les CSS : data:uri. En espé­rant que la CSS ne contient pas trop de ressources inutiles ou trop de liens vers la même ressource.
    • Au pire : Géné­rer la CSS en Javas­cript avec des liens obte­nus par crea­teObjectUrl, l’in­sé­rer dans le DOM manuel­le­ment
  • Pour les images dans le code HTML : crea­teObjectURL si possible.
    • Véri­fier tout de même si le data:uri n’est pas plus simple. La diffé­rence entre les deux sera assez faible si les images ne sont pas répé­tées plusieurs fois.
  • Pour les audio et vidéo : Désac­ti­ver le preload, rensei­gner le lien via crea­teObjectURL qu’au lance­ment de la vidéo. Pour les vidéo, penser à créer une image d’at­tente avec l’at­tri­but poster.

Ça reste fran­che­ment du brico­lage je trouve, et ça va néces­si­ter plein de javas­cript pour géné­rer tout ça.

Dans mon monde idéal

Dans l’idéal j’au­rai bien aimé avoir une sorte de faux serveur web en javas­cript depuis le navi­ga­teur. Genre toute url en « local-js://xxxxx » fait appel à un objet Javas­cript qui répond ensuite ce qu’il veut.

À défaut, un URL.createObjectURL( 'text/html', function() { return bindata; } ) serait bien pratique : Le navi­ga­teur n’ap­pe­lant la fonc­tion pour récu­pé­rer le contenu que quand il cherche à accé­der au dit contenu, au lieu de lui donner tout le contenu par avance au cas où il en aurait besoin.

Quelqu’un a des pistes pour moi ?

Rejoindre la conversation

3 commentaires

  1. Ce que tu voudrais (et beaucoup d’autres aussi) est un remplaçant à AppCache. Il y a un groupe de travail au W3C pour bosser sur AppCache NG et il pourrait s’appuyer sur https://github.com/slightlyoff/ServiceWorker/blob/master/explainer.md. Mais bon, ça reste incertain et il faudra encore attendre un bout de temps avant que ça n’arrive jusqu’à nos navigateurs.

    En attendant, on peut continuer à bricoler avec les data-uri et autres File API. Pour Firefox, une piste intéressante et l’utilisation d’URL.createObjectURL pour créer une URL vers un objet stocké dans IndexedDB. Mais ça ne marchera pas pour l’ipad vu qu’il n’y a toujours pas d’IndexedDB dessus…

    Bon courage !

    1. En fait pas besoin de IndexedDB pour le createObjectURL, on peut créer le blob à la main. Ce n’est quand même qu’un bidouillage pour des contenus qui ne sont potentiellement pas affichés.

      Voir le billet plus haut que j’ai totalement réécrit pour que ce soit plus clair

Laisser un commentaire

Votre adresse de messagerie ne sera pas publiée. Les champs obligatoires sont indiqués avec *

À propos de ce site, du contenu, de l'auteur
Je poste parfois ici des humeurs ou des pensées. Parfois je change, parfois je me trompe, parfois j'apprends, et souvent le contexte lui-même évolue avec le temps. Les contenus ne sont représentatifs que de l'instant où ils ont été écrits. J'efface peu les contenus de ce site, merci de prendre du recul quand les textes sont anciens. Merci

À toutes fins utiles, ce site est hébergé par Scaleway, ONLINE SAS, joignable par téléphone au +33 (0)1 84 13 00 00 et joignable par courrier à l'adresse BP 438 - 75366 Paris Cedex 08.