micro decoder library dilemma

Pagina: 1
Acties:

Onderwerpen

Vraag


Acties:
  • +1 Henk 'm!

  • HugoSmits
  • Registratie: April 2009
  • Laatst online: 18-08-2023
Voor een aantal projecten wil ik graag afbeeldingen weergeven in formaten die niet standaard
door de browsers worden ondersteund. Op internet zijn er wel een aantal oplossingen te vinden
in de vorm van javascript libraries, echter zijn deze allemaal >30kb.

Dat vind ik een beetje zonde. Vandaar dat ik heb besloten om een aantal micro decoders te schrijven. Als voorbeeld mijn micro decoder voor 24/32bit TGA afbeeldingen (slechts 869 bytes groot!): http://www.hugosmits.nl/microjs/tga/index.html

Nu zit ik echter met een paar dilemma's waar ik graag jullie mening over zou willen horen:

Error handling

Momenteel roep ik een harde ‘return’ aan op het moment dat het bestand fouten bevat.
Normaal zou ik liever ook console.error() statement aanroepen, echter nemen die veel bytes in beslag.

De errors in dit geval zijn eigenlijk allemaal voor de hand liggende dingen (denk aan een 8bit TGA bestand als input, terwijl de decoder alleen 24/32bit ondersteund). Dit soort dingen kunnen ook op de website/handleiding uitgelegd worden.

Wat vinden jullie? Script size klein houden, of een extra 100~200 bytes besteden aan goede error handling?

Formaat specificaties

Een aantal formaten hebben geen maximum voor parameters zoals bijvoorbeeld resolutie.
Dit zorgt voor veiligheids risico’s. Zal ik die zelf dichten (door zelf een maximum in te stellen?).

Als ik deze dicht, kan het echter wel voorkomen dat correcte afbeeldingen niet getoond worden (omdat mijn decoder de resolutie bijvoorbeeld te groot vind).

Wat vinden jullie? Dichten of niet?


Andere tips om het script nog kleiner te maken zijn altijd welkom!

Alle reacties


Acties:
  • 0 Henk 'm!

  • !GN!T!ON
  • Registratie: September 2006
  • Laatst online: 06-09 18:39
Ik zou zelf voor de error handling gaan, dat maakt debuggen makkelijker, en inderdaad zelf max value's op je inputs zetten.

Acties:
  • 0 Henk 'm!

  • Tuxie
  • Registratie: Augustus 2003
  • Laatst online: 06-09 23:33

Tuxie

En WeL nU!

Het is moeilijk om zonder context afwegingen te maken. Waarom wil je per se de size zo klein houden, is daar een specifieke reden voor? Wat is nu 30KB op een browserapplicatie deze dagen? Nu moet je elke keer het wiel opnieuw uitvinden, of is dit puur een hobbyproject?

Andere gedachtengang: API service bouwen met fatsoenlijke monitoring, logging en foutafhandeling zodat de client-side call heel klein kan zijn. Of er moet een hele specifieke reden zijn om dit per se client-side te willen doen.....

Acties:
  • 0 Henk 'm!

  • HugoSmits
  • Registratie: April 2009
  • Laatst online: 18-08-2023
Tuxie schreef op zondag 2 juni 2019 @ 15:40:
Wat is nu 30KB op een browserapplicatie deze dagen?
30KB is ontzettend veel, zeker als het ook in <1KB kan. Steeds vaker zie je dat grote partijen bezig zijn om hun footprint te verkleinen en laadtijden omlaag te krijgen. Zie hier bijvoorbeeld hoe Netflix 300KB aan javascript te veel vond: https://medium.com/dev-ch...e-case-study-c0bcde26a9d9
Tuxie schreef op zondag 2 juni 2019 @ 15:40:
Andere gedachtengang: API service bouwen met fatsoenlijke monitoring, logging en foutafhandeling zodat de client-side call heel klein kan zijn. Of er moet een hele specifieke reden zijn om dit per se client-side te willen doen.....
Decoderen aan de serverside zorgt juist voor een grote client-side call. Een belangrijke stap in het decodeer process is immers het decomprimeren van het bestand. Gevolg is dat het resultaat bijna altijd vele malen groter zal zijn dat het gecomprimeerde bestand.

Acties:
  • 0 Henk 'm!

  • Klaasvaak
  • Registratie: Maart 2010
  • Laatst online: 31-08 10:04
Je moet nog eens naar je variabele kijken. De meeste worden als globaal gedeclareerd,

Acties:
  • 0 Henk 'm!

  • HugoSmits
  • Registratie: April 2009
  • Laatst online: 18-08-2023
Klaasvaak schreef op zondag 2 juni 2019 @ 21:57:
Je moet nog eens naar je variabele kijken. De meeste worden als globaal gedeclareerd,
Goede tip! Had het met opzet weggelaten omdat het veel bytes scheelt. Maar is beter om dit terug te draaien als ik het ooit wil releasen.

Acties:
  • 0 Henk 'm!

  • Tuxie
  • Registratie: Augustus 2003
  • Laatst online: 06-09 23:33

Tuxie

En WeL nU!

HugoSmits schreef op zondag 2 juni 2019 @ 16:23:
[...]
30KB is ontzettend veel, zeker als het ook in <1KB kan. Steeds vaker zie je dat grote partijen bezig zijn om hun footprint te verkleinen en laadtijden omlaag te krijgen. Zie hier bijvoorbeeld hoe Netflix 300KB aan javascript te veel vond: https://medium.com/dev-ch...e-case-study-c0bcde26a9d9
Oh zeker mee eens hoor. Als je Netflix schaal hebt en iedere 100ms je potentieel tienduizenden klanten kost (want dat doet het, zie dat verhaal met de signup button). Maar vandaar ook mijn vraag wat de context is, wat maakt jouw usecase zo uniek dat je op de ms. wil optimaliseren, afgezien van het feit dat het leuk is. No offence, ik ben gewoon benieuwd :)
HugoSmits schreef op zondag 2 juni 2019 @ 16:23:
[...]
Decoderen aan de serverside zorgt juist voor een grote client-side call. Een belangrijke stap in het decodeer process is immers het decomprimeren van het bestand. Gevolg is dat het resultaat bijna altijd vele malen groter zal zijn dat het gecomprimeerde bestand.
Dat klopt, je moet meer data oversturen dan wanneer je het ge-encodeerde bestand lokaal decodeert. Je browser hoeft echter ook minder te rekenen, ook al zijn dit simpele bewerkingen. Wederom de vraag: waarom wil je dit allemaal zo? :Y

Acties:
  • 0 Henk 'm!

  • HugoSmits
  • Registratie: April 2009
  • Laatst online: 18-08-2023
Tuxie schreef op zondag 2 juni 2019 @ 22:58:
Oh zeker mee eens hoor. Als je Netflix schaal hebt en iedere 100ms je potentieel tienduizenden klanten kost (want dat doet het, zie dat verhaal met de signup button). Maar vandaar ook mijn vraag wat de context is, wat maakt jouw usecase zo uniek dat je op de ms. wil optimaliseren, afgezien van het feit dat het leuk is. No offence, ik ben gewoon benieuwd :)
Ik ben momenteel bezig met research naar (experimentele) codecs voor het web. Uiteindelijk zal dit worden meegenomen in de ontwikkeling van codecs voor grote partijen.

De micro decoders zijn voornamelijk voor de lol. Het is de bedoeling dat ik even los kom uit mijn vaste denkpatroon. Ik merk dat het niet alleen helpt met stoom afblazen, kleinere projecten lenen zich vaak voor nieuwe creatieve aanpakken. Dit zorgt voor een fris perspectief, wat weer van pas komt bij het serieuzere werk.
Tuxie schreef op zondag 2 juni 2019 @ 22:58:
Dat klopt, je moet meer data oversturen dan wanneer je het ge-encodeerde bestand lokaal decodeert. Je browser hoeft echter ook minder te rekenen, ook al zijn dit simpele bewerkingen. Wederom de vraag: waarom wil je dit allemaal zo? :Y
Uiteindelijk is het de bedoeling dat gebruikers een snellere ervaring hebben. Het decoderen op de client-side kent veel voordelen; minder data versturen, minder belasting op de server en snellere feedback voor gebruikers (denk grafische bewerking applicatie in de browser).

De rekenkracht die nodig is voor het decoderen van afbeeldingen valt reuze mee, uiteraard is dat ook afhankelijk van het formaat. Het zal bijvoorbeeld anders worden als je een MPEG film softwarematig gaat decoderen in de browser.

Acties:
  • 0 Henk 'm!

  • epic007
  • Registratie: Februari 2004
  • Laatst online: 25-08 11:27
HugoSmits schreef op maandag 3 juni 2019 @ 01:41:

...


Uiteindelijk is het de bedoeling dat gebruikers een snellere ervaring hebben. Het decoderen op de client-side kent veel voordelen; minder data versturen, minder belasting op de server en snellere feedback voor gebruikers (denk grafische bewerking applicatie in de browser).

...
Waar komen de TGA files vandaan? In je voorbeeld komen die ook van de server. Uncompressed TGA files zijn toch per definitie groot (iig groter dan jpg of png). Wat is dan de winst van een micro decoder?

Verder lijkt me, als je images gaat bewerken in je browser dan blijft de bezoeker volgens mij redelijk lang op die pagina. Is dan een iets langere load niet acceptabel? Ik denk even aan een applicatie als google docs etc.

Acties:
  • 0 Henk 'm!

  • Sissors
  • Registratie: Mei 2005
  • Niet online
Ik vind het mooi te zien hoe iemand daadwerkelijk kijkt naar efficientie. Internetsnelheden zijn geexplodeerd, maar laadsnelheden van sites zijn nog steeds duidelijk merkbaar omdat ze alsmaar groter worden. Dan wel weer erg jammer dat de helft van de reacties effectief eruit bestaan dat wat extra laadtijd prima is.

Nu valt dit een beetje buiten mijn expertise gebied, maar kan je niet gewoon return codes mee geven als error handling? Zou nauwelijks extra ruimte moeten kosten, maar een gebruiker kan wel zien waarom hij het niet doet.

Wat betreft veiligheid, op welke manier is het nu een veiligheidsrisico? Ik kan me voorstellen als de opgegeven resolutie groter is dan die in het bestand, je een gevaar hebt, maar dat staat los van de maximum resolutie. Als iemand graag een 10 gigapixel foto van de melkweg wil tonen, wil je dan dat jouw decoder erop stopt? Ik zou zeggen dat hij gewoon zijn werk moet doen, decoden.

Acties:
  • 0 Henk 'm!

  • HugoSmits
  • Registratie: April 2009
  • Laatst online: 18-08-2023
epic007 schreef op donderdag 6 juni 2019 @ 09:52:
Waar komen de TGA files vandaan? In je voorbeeld komen die ook van de server. Uncompressed TGA files zijn toch per definitie groot (iig groter dan jpg of png). Wat is dan de winst van een micro decoder?
Het TGA formaat beschikt over compressie (RLE). Hierdoor zijn TGA bestanden een stuk kleiner dan ongecomprimeerde data.
epic007 schreef op donderdag 6 juni 2019 @ 09:52:
Verder lijkt me, als je images gaat bewerken in je browser dan blijft de bezoeker volgens mij redelijk lang op die pagina. Is dan een iets langere load niet acceptabel? Ik denk even aan een applicatie als google docs etc.
Zoals eerder aangegeven is de TGA micro decoder slechts onderdeel van een research project; de uiteindelijk micro decoder zal werken met een modern formaat, waarvan de compressie aanzienlijk beter is. Hierdoor hebben ongecomprimeerde bestanden een grote impact op de laadtijd.

Acties:
  • 0 Henk 'm!

  • HugoSmits
  • Registratie: April 2009
  • Laatst online: 18-08-2023
Sissors schreef op zaterdag 8 juni 2019 @ 19:20:
Ik vind het mooi te zien hoe iemand daadwerkelijk kijkt naar efficientie. Internetsnelheden zijn geexplodeerd, maar laadsnelheden van sites zijn nog steeds duidelijk merkbaar omdat ze alsmaar groter worden. Dan wel weer erg jammer dat de helft van de reacties effectief eruit bestaan dat wat extra laadtijd prima is.

Nu valt dit een beetje buiten mijn expertise gebied, maar kan je niet gewoon return codes mee geven als error handling? Zou nauwelijks extra ruimte moeten kosten, maar een gebruiker kan wel zien waarom hij het niet doet.
Thanks! :) en heb de code inmiddels aangepast met return statements:
https://github.com/HugoSmits86/microtga
Sissors schreef op zaterdag 8 juni 2019 @ 19:20:

Wat betreft veiligheid, op welke manier is het nu een veiligheidsrisico? Ik kan me voorstellen als de opgegeven resolutie groter is dan die in het bestand, je een gevaar hebt, maar dat staat los van de maximum resolutie. Als iemand graag een 10 gigapixel foto van de melkweg wil tonen, wil je dan dat jouw decoder erop stopt? Ik zou zeggen dat hij gewoon zijn werk moet doen, decoden.
Dat is een gedachten die ook door mijn hoofd spookte. Aan de andere kant is dat natuurlijk ook wel erg makkelijk gedacht. Het is voor kwaadwillende op deze manier makkelijk om een website te slopen terwijl oprechte 10 gigapixel afbeeldingen (in dit bestandsformaat) vrijwel nooit voorkomen.

Het is door compressie vaak lastig om op voorhand te bepalen of de resolutie matched met de data. Terwijl je wel alvast een buffer wil alloceren in het RAM geheugen, voor de ongecomprimeerde data. In een dergelijk geval wil je kunnen vertrouwen op de parameters.

Acties:
  • 0 Henk 'm!

Verwijderd

Altijd debug code en nooit vroeg optimaliseren.

Als het écht klein moet kun je debug code altijd nog optioneel maken. Via een wrapper-class / façade / proxy. Of via een pre-processor die een minimale en een debug variant 'build'.

Stille fouten zijn een gemene 'bitch'... Zeker als het niet voor de hand ligt wat de oorzaak is, zoals in dit geval: "library is voor format x... afbeelding is format x... het doet niks... ??!?" Een jpeg library die stil faalt op een bmp. Of iets dat stil faalt op een URL die een 404 geeft. Die zijn nog redelijk eenvoudig te debuggen in een development omgeving.

Acties:
  • 0 Henk 'm!

  • HugoSmits
  • Registratie: April 2009
  • Laatst online: 18-08-2023
Verwijderd schreef op maandag 10 juni 2019 @ 02:07:
Altijd debug code en nooit vroeg optimaliseren.

Als het écht klein moet kun je debug code altijd nog optioneel maken. Via een wrapper-class / façade / proxy. Of via een pre-processor die een minimale en een debug variant 'build'.

Stille fouten zijn een gemene 'bitch'... Zeker als het niet voor de hand ligt wat de oorzaak is, zoals in dit geval: "library is voor format x... afbeelding is format x... het doet niks... ??!?" Een jpeg library die stil faalt op een bmp. Of iets dat stil faalt op een URL die een 404 geeft. Die zijn nog redelijk eenvoudig te debuggen in een development omgeving.
Dat is ook mijn denkwijze; alleen zijn alle fouten, waarvoor een melding gemaakt kan worden, voor de handliggend in dit geval (en daardoor in mijn ogen overbodig).

Inmiddels heb ik twee foutmeldingen verwerkt in de code; Eentje voor een empty request response van XMLHttpRequest, en een andere generieke melding als er een afbeelding niet voldoet aan de eisen van de decoder (not a 24/32 bit image).

Acties:
  • 0 Henk 'm!

  • Mijzelf
  • Registratie: September 2004
  • Niet online
HugoSmits schreef op zondag 2 juni 2019 @ 15:20:
Andere tips om het script nog kleiner te maken zijn altijd welkom!
Je definieert 2 functies. Die omzetten naar arrow functions spaart weer een paar bytes.
JavaScript:
1
e=function(e){console.error(e);}
wordt
JavaScript:
1
e=(e)=>{console.error(e);}


Overigens zou ik geneigd zijn deze decoder op te splitsen naar 2 functies. Strikt genomen is dit geen decoder, maar een loader/decoder. Wanneer je een tga file op een andere manier beschikbaar zou hebben dan als file op een server, kun je er niets mee.

Acties:
  • 0 Henk 'm!

  • HugoSmits
  • Registratie: April 2009
  • Laatst online: 18-08-2023
Mijzelf schreef op maandag 10 juni 2019 @ 10:09:
[...]
Je definieert 2 functies. Die omzetten naar arrow functions spaart weer een paar bytes.
Thanks! Goed gespot :)
Mijzelf schreef op maandag 10 juni 2019 @ 10:09:
Overigens zou ik geneigd zijn deze decoder op te splitsen naar 2 functies. Strikt genomen is dit geen decoder, maar een loader/decoder. Wanneer je een tga file op een andere manier beschikbaar zou hebben dan als file op een server, kun je er niets mee.
Een makkelijkere fix is om de functie te hernoemen naar openTGA ;)

Opsplitsen in twee functies is mij te veel werk; het is een klein research project wat inmiddels zijn doel al ruim voorbij is geschoten.

Acties:
  • 0 Henk 'm!

  • Mijzelf
  • Registratie: September 2004
  • Niet online
HugoSmits schreef op maandag 10 juni 2019 @ 11:58:
[Een makkelijkere fix is om de functie te hernoemen naar openTGA ;)
En hoppa! Weer 2 bytes minder!

Acties:
  • 0 Henk 'm!

  • DJMaze
  • Registratie: Juni 2002
  • Niet online
HugoSmits schreef op zondag 2 juni 2019 @ 15:20:
Script size klein houden, of een extra 100~200 bytes besteden aan goede error handling?
Ik kan hier zinnig antwoord opgeven, maar aangezien je zelf volledig wil optimaliseren geef ik je liever een aanleiding voor onderzoek: MTU

Kijk dan vooral naar de grootte van Ethernet pakketjes (rond de 1400 bytes) en bedenk dan of optimaliseren nut heeft ;)

Maak je niet druk, dat doet de compressor maar


Acties:
  • 0 Henk 'm!

  • Mijzelf
  • Registratie: September 2004
  • Niet online
Aangezien de http respons header gemiddeld 700 tot 800 bytes is (bron), kan die 100 tot 200 bytes hem inderdaad 'over de rand' duwen.

Acties:
  • 0 Henk 'm!

  • HugoSmits
  • Registratie: April 2009
  • Laatst online: 18-08-2023
DJMaze schreef op dinsdag 11 juni 2019 @ 11:30:
Kijk dan vooral naar de grootte van Ethernet pakketjes (rond de 1400 bytes) en bedenk dan of optimaliseren nut heeft ;)
Naast de HTTP response hebben we ook nog te maken met TCP packet fragmentatie.
Je kunt er niet zomaar vanuit gaan dat alles tussen het start- en eindpunt bestaat uit ethernet.

Ik heb inmiddels ook de PCX decoder online gezet op Github:
https://github.com/HugoSmits86/micropcx

Acties:
  • 0 Henk 'm!

  • R4gnax
  • Registratie: Maart 2009
  • Laatst online: 06-09 17:51
De performance die je hier wint door een heel compacte decoder te schrijven gooi je meteen weer weg door het resultaat als base64 URL te encoderen en dat dynamisch aan de src van een img element te hangen.

Dit vernietigt de mogelijkheid van browsers om middels lookahead parsing optimisch images te downloaden en vernietigt de mogelijkheid van browsers om images native async te decoderen. (Jouw software decoder bezet de UI thread; grote no-no.) Daarnaast is het ook nog eens zo dat het decoderen van base64 URIs bewezen enorm vertragend is voor mobile browsers met minder krachtige CPUs.

Met andere woorden; ophouden voortijdig te optimaliseren. Gewoon eenmalig aan de serverzijde je plaatjes omzetten naar een gangbaar formaat; a/h einde v/d rit schaalt dat echt veel beter.


Als je dit bij wijze van experiment toch voort wilt zetten, zal ik je een hint geven: service workers.

[ Voor 9% gewijzigd door R4gnax op 17-06-2019 19:57 ]


Acties:
  • 0 Henk 'm!

  • HugoSmits
  • Registratie: April 2009
  • Laatst online: 18-08-2023
R4gnax schreef op maandag 17 juni 2019 @ 19:54:
Met andere woorden; ophouden voortijdig te optimaliseren. Gewoon eenmalig aan de serverzijde je plaatjes omzetten naar een gangbaar formaat; a/h einde v/d rit schaalt dat echt veel beter.
Zoals eerder gezegd is dit een klein research project. De daadwerkelijke decoder is gebouwd voor een modern formaat, wat niet ondersteund wordt door de huidige browsers. Het is niet mogelijk om dit moderne formaat te converteren naar een gangbaar formaat zonder dat informatie verloren gaat.

Daarnaast zijn er applicaties waarbij meer controle over de data een vereiste is, hiervoor biedt zelf decoderen de (enige?) uitkomst. Denk bijvoorbeeld aan het bewerken van individuele frames van een animatie.

[ Voor 30% gewijzigd door HugoSmits op 18-06-2019 13:51 ]


Acties:
  • 0 Henk 'm!

  • R4gnax
  • Registratie: Maart 2009
  • Laatst online: 06-09 17:51
HugoSmits schreef op dinsdag 18 juni 2019 @ 13:49:
[...]


Zoals eerder gezegd is dit een klein research project. De daadwerkelijke decoder is gebouwd voor een modern formaat, wat niet ondersteund wordt door de huidige browsers. Het is niet mogelijk om dit moderne formaat te converteren naar een gangbaar formaat zonder dat informatie verloren gaat.

Daarnaast zijn er applicaties waarbij meer controle over de data een vereiste is, hiervoor biedt zelf decoderen de (enige?) uitkomst. Denk bijvoorbeeld aan het bewerken van individuele frames van een animatie.
Goed; je hebt dus speciale behoeftes hiermee, waarmee een eenmalige server-side conversie niet mogelijk is.


Ik zou alsnog adviseren om dan via een service-worker te gaan werken, waar dat ondersteund is.

Gebruik de service-worker om verzoeken naar je plaatjes te onderscheppen. Pak daarvan de bytes; start vanaf de service-worker een extra web-worker thread op en gooi de bytes op die aparte thread door de decoder heen die er een rauwe 32-bit BMP van maakt; hevel dat terug naar de service worker en stuur die respons met een gewijzigd content type naar de pagina-context terug.

Je kunt de URLs van je plaatjes dan direct in de src van een img element zetten, en de hele operatie is non-blocking.

Acties:
  • 0 Henk 'm!

  • HugoSmits
  • Registratie: April 2009
  • Laatst online: 18-08-2023
R4gnax schreef op dinsdag 18 juni 2019 @ 19:49:
[...]
Ik zou alsnog adviseren om dan via een service-worker te gaan werken, waar dat ondersteund is.
Service-worker is een goede tip! d:)b Had er zelf al naar gekeken voor de ‘grote’ decoder.
Voor deze kleine research projecten vond ik het te veel van het goede ;)
Pagina: 1