一、WebAssembly 是什么?能做什么?
WebAssembly 是通过 *.wasm 文件进行存储的,这是编译好的可移植、精悍、载入迅捷的二进制格式文件,它的体积非常的小。更多查看 webassembly 官网
.wasm 文件 与 .wat 文件的区别
.wat 文件: 可读的S表达式文本文件.wasm 文件: 是 WebAssembly 的二进制格式文件
二、WebAssembly 处于编译阶段哪个环节
WebAssembly 能做到像Java 字节码一样,一次编译到处运行,具有跨平台特性。以此同时,作为中间码的WebAssembly 直接省略编译前端的步骤,而JavaScript 需要实时编译,相比之下性能优势显著
三、WebAssembly 怎么跟 js 互通
在浏览器中,提供了一个全局的
window.WebAssembly 对象,可以用于实例化WASM 模块。
四、利用 WebAssembly 解决 WKwebview 宿主 iOS Safira 不支持解析 webp 的问题
先看 ios13.2.3 safari 解码
webp 图片与不使用 webp 编码加载时间对比
demo 中webp_wasm.wasm 文件于 js胶水 文件webp_wasm.js 可通过 github 谷歌libwebp 开源项目 readme的指引编译
- 经 webp 编码的淘宝图片
- 未经 webp 编码的淘宝图片
二话不说直接上代码:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 | <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>WASM demo of WebP decoding</title> <script type="text/javascript"> var Module = { noInitialRun : true }; </script> <script type="text/javascript"> function init() { var xhr = new XMLHttpRequest(); xhr.open('GET', 'webp_wasm.wasm', true); xhr.responseType = 'arraybuffer'; xhr.onload = function() { Module.wasmBinary = xhr.response; var script = document.createElement('script'); script.src = "webp_wasm.js"; document.body.appendChild(script); }; xhr.send(null); } function decode(webp_data, canvas_id) { var result; if (Module["asm"] != undefined) { // wrapper for the function decoding a WebP into a canvas object WebpToCanvas = Module.cwrap('WebpToSDL', 'number', ['array', 'number']); // get the canvas to decode into // var canvas = document.getElementById(canvas_id); canvas = document.createElement('canvas'); if (canvas == null) return; // clear previous picture (if any) Module.canvas = canvas; ctx = canvas.getContext('2d'); ctx.clearRect(0, 0, canvas.width, canvas.height); // decode and measure timing start = new Date(); var ret = WebpToCanvas(webp_data, webp_data.length); // webp 图像像素写入canvas console.log(ret); base64 = canvas.toDataURL("image/png"); document.getElementById('decode_base64').src = base64; end = new Date(); var decode_time = end - start; result = 'decoding time: ' + decode_time +' ms.'; } else { result = "WASM module not finished loading! Please retry"; } // display timing result speed_result = document.getElementById('timing'); if (speed_result != null) { speed_result.innerHTML = '<p>'+ result + '</p>'; } } function loadfile(filename, canvas_id) { var xhr = new XMLHttpRequest(); xhr.open('GET', filename); xhr.responseType = 'arraybuffer'; xhr.onreadystatechange = function() { if (xhr.readyState == 4 && xhr.status == 200) { var webp_data = new Uint8Array(xhr.response); decode(webp_data, canvas_id); } }; xhr.send(); } function loadImage(filename,img_id,time_id){ var img = new Image(); var start = new Date(); var speed_result2 = document.getElementById(time_id); img.onload = function(){ // display timing result if (speed_result2 != null) { document.getElementById('output_webp_img').appendChild(img); var end = new Date(); var decode_time = end - start; speed_result2.innerHTML = '<p>'+time_id+' decoding time: ' + decode_time +' ms.</p>'; } } img.src = filename; } </script> </head> <body onload='init()' bgcolor='#f0f8ff'> <p> <strong>WebP demo using <a href="http://webassembly.org/">Web-Assembly</a></strong> - </p> <p> WASM version of the WebP decoder, using <a href="https://github.com/webmproject/libwebp">libwebp</a> compiled with <a href="https://github.com/kripken/emscripten/wiki">Emscripten</a>. </p> <p> <br/> Requires a <a href="https://developer.mozilla.org/en-US/docs/WebAssembly#Browser_compatibility">native-wasm enabled browser</a> (Chrome M58, WebKit) <br/> </p> <p id="image_buttons"> <input type="button" value="lossy example" name="//img.alicdn.com/bao/uploaded/i4/2549599360/O1CN01YZ4MJz2J0vkikfMTT_!!0-item_pic.jpg_.webp" onclick="loadfile(this.name, 'output_canvas')"> <input type="button" value="lossy+alpha example" name="./test2.webp" onclick="loadfile(this.name, 'output_canvas')"> <input type="button" value="lossless example" name="./test3.webp" onclick="loadfile(this.name, 'output_canvas')"> <input type="button" value="img load" onclick="loadImage(this.name,'output_webp_img','b_load_img')" name="//img.alicdn.com/bao/uploaded/i4/2549599360/O1CN01YZ4MJz2J0vkikfMTT_!!0-item_pic.jpg"> <input type="button" onclick="loadImage(this.name,'output_webp_img','b_load_webp_img')" value="img webp load" name="//img.alicdn.com/bao/uploaded/i4/2549599360/O1CN01YZ4MJz2J0vkikfMTT_!!0-item_pic.jpg_b.jpg_.webp"> </p> <p id="timing">Timing: N/A</p> <p id="load_decode_time"></p> <p id="b_load_webp_img"></p> <p id="b_load_img"></p> <div id="output_webp_img"></div> <canvas id="output_canvas">Your browser does not support canvas</canvas> <img id="decode_base64"> </body> </html> |
参考文章
- 悄悄掀起 WebAssembly 的神秘面纱
- 20分钟上手 webAssembly
- WebAssembly进阶系列三:微信小程序支持webP的WebAssembly方案
- 谷歌
libwebp 开源项目 - webassembly 的那些事