If you know the user's printer type and brand, you can generate the content you want printed in the Page Description Language that corresponds to the user's printer.
This content can be generated server-side to eliminate the need for expensive client-side browser action.
The printer can be specified by the user via <select>
or a similar method of your choice.
For example, let's say that I wanted to print the following image in Zebra Programming Language (ZPL):

This image is 19,576 bytes, but it can be reduced to a mere 2,864 bytes of ZPL:
^XA^FO50,50^GFA,4324,4324,47,,O04001FCh03F8002,O08M07FCgP01F8N08,N0102I03F8001I04gH01L01FC,Y048001gHFC8001O08,N0204R04gH014014O088,P04N014gL08S02,P04O0401gX02,P04I018J0404Q02Y018K02,P04M020404gJ04S02,P04J06001040403gFE04L03L02,P04O0404gJ04S02,:O014O0404gJ04S02,P04O0404gJ04S02,::N0114Q04gJ04S02,K01KFCP04gJ04S02,K03KFCP04gJ04S02,::K01KFCN0802gH010401P082,P04,P04gL03,P04gL0301hN08,P04gL06018V010018K06002R0198018,003JFC004R03S0603C027FC0IFI03FFC3803807C0070067FF83FF85FF019C01807E,007JFE004K01F80FE0303FK0CJ0603C03FFE0IFI03FFC3C0381EI070067FF83FFCIFC19E0180E,00LF004K0FF01FF83IF3IFCC01806036038030EK038003E0383800478067I03I0600C19E0181C,00LF004J03F00381C3E003IFC601C06066030070CK03I03E0387I047C066I03I0401C19F01838,007JFE004J07I0700638J0C00603E060660301E0CK03I0370386I046C066I03I0407819B8187,007JFE004J0EI0600218J0C00703E06063030780CK03I033838CI0466066I02I041E01998186,001JF8004J0CI0C00318J0C0030370E0C303BC00CK03I033838C0FE467066I02I06F80199C18C07F,P04J0F800C00118J0C0030630C0C383FI0CK03I031C398FF8463866I02I07C00198E18C7FC,P04J07F00C00118J0C0038618C087F3CI0CK0301C30E399C38C61866I02I07I0198718CE1C,N0314K0FE0C001186I0C0018E18C1BFC3CI0FFCI03FFC306398038C61C67F803FC07800198319801C,L01IFCL0FCC0011FEI0C001CC1DC1F9C3FI0FFJ03FC03073B0038C60E67F803F807C001983998018,L03IFCM0CC0033EJ0CI0CC0DC1C0C3BC00CK03I0303BB0038C60I6I02I067001981D98018,L03IFEM0CE00238I01CI0FC0F8300C38E00CK03I0301FB0030C603E6I06I063C01980D98018,L03IFEL01C600618I01CI0F8078300638380CK03I0301FB0070C603E6I06I060E01980F98038,L01IFCI010078700E18I01CI0780782006381C0CK03I0300FB80F0C601E6I06I06078198079C078,M0IFCI0181E03C3C18I01CI0780386007380F0E07800383F30079C330C600E707E703C601C198038E198,P04J0FF801FF018I01CI03003860031803CIFC003IF30070FE304C00E7FFE7FFC600F1980387F18,P04J07CI018018I018I03001040031001CF8J03E003003078384C0067C0078K079980183C18,P04hS038,P04hS01,J01MF8,J0NFEO02,J0OFM04041gI04008P02,I01KFE00FM0404gJ04S02,I01CM07M0404gJ04R042,I03CM07M0404gJ04S02,01FFCM07M0404gJ04S02,07FFCM07M0404gJ04S02,0IFCM07M0404gJ04S02,1F01CM07M040404S0CN04S02,3C01CM07M0404gJ04S02,383FCM07J0110404gJ04S02,38FFCM07K020401gX02,79FFCM07I081004gL0AJ04N02,7181CM070081I0402gI01T02,7181CM07O012M07MFM040014I081K02,7181CM07408I048008gH01N081J02,7181CM07K061I01MF8M0MFCI042O02,7181CM07J0608Q04X0182I01J02,7181CM07I060CR04Y0183M02,7181CM070060CS04g0183L02,7181CM070608T05gG0182,7181CM0760CU04008Y0402,7181CM07X04gH04002I04,7181CM078W04J02W04I03808,71C1CM07X04gH04K01,71FFCM07X04gH04I01F8,39FFCM07X04gH042,38FF8M07X04gH04,3C018M07002U04L02U04,1EP07002U04L02U04I08,0F8O07002U04L01U04I08,07FFCM07002gX04I08,03FFCM07002R04Q041J0402K02I08,00FFCM07002P0202M01I0808001I08N08,I01EM07002gM0804R08,I01EM070CN07OFEJ07FF8R083808,J0EM07I02L08Y04K01J02007,J0FM0F0E008K08Y0401M0480E02,J0F8K01EI02L08Y04N01K08,J07CK03CJ09K08Y04O04J024,J03MF8J048J08Y04L0401,J01MF03E0024gJ04I0100402K038,K07KFCgQ04L041N08,N07F8003JFCI01gF8LFC0NF,^FS^XZ
You could allow the user to print the code in a new window using JavaScript:
window.open( 'data:text/plain;base64,' + window.btoa( zpl_code ), 'Print ZPL Image', 'height=100, width=500' );
The result would look like this:

Try it online!
Then if the user wants to see the images that they are printing in the browser, the images could load via AJAX as the user scrolls in the main window.
Note: The user will need to allow raw data printing in order to use this method.