在人們極力渴求提高JavaScript性能的情況下,WebAssembly應(yīng)運(yùn)而生,現(xiàn)已得到所有主流Web瀏覽器的支持。由于其卓越的性能和可移植性,WebAssembly也被用于Web瀏覽器之外的許多場(chǎng)景。本書圍繞WebAssembly技術(shù)棧介紹如何通過C、C++等語言編寫高性能的瀏覽器端應(yīng)用程序。你將掌握WebAssembly的基礎(chǔ)知識(shí),學(xué)習(xí)如何創(chuàng)建原生WebAssembly模塊,與JavaScript組件交互,使用WebAssembly文本格式進(jìn)行調(diào)試,并利用多線程支持機(jī)制。
1.抽絲剝繭,逐步解構(gòu) WebAssembly 的復(fù)雜生態(tài);
2.突破 JavaScript 瓶頸,讓 C/C++ 代碼快速運(yùn)行于瀏覽器端;
3.邊學(xué)邊練,配套練習(xí)答案幫你熟練掌握 WebAssembly。
WebAssembly是可移植、體積小、加載快并且兼容Web瀏覽器的全新類匯編語言格式,其具有高效、安全、開放、標(biāo)準(zhǔn)等特性。使用WebAssembly,你能夠不再依賴JavaScript編寫基于瀏覽器的高性能應(yīng)用程序。通過編譯為WebAssembly二進(jìn)制格式,你的C/C++代碼或Rust代碼都可以在瀏覽器中以接近原生的速度運(yùn)行。
本書介紹如何使用C/C++語言和Emscripten工具包編寫并運(yùn)行高性能的Web應(yīng)用程序。你將學(xué)習(xí)如何創(chuàng)建原生WebAssembly模塊、如何與JavaScript組件交互,以及如何使用Web worker和pthread最大限度地提高性能。
●多個(gè)模塊在運(yùn)行時(shí)的動(dòng)態(tài)鏈接
●模塊與JavaScript之間的通信
●利用WebAssembly文本格式進(jìn)行調(diào)試
●利用Web worker和pthread進(jìn)行多線程編程
C.杰勒德·加倫特(C. Gerard Gallant),微軟認(rèn)證專家,Dovico公司高級(jí)軟件工程師,DZone技術(shù)網(wǎng)站專欄作者。
【譯者簡(jiǎn)介】
計(jì)算機(jī)專業(yè)碩士,軟件工程師,現(xiàn)居于上海,另譯有《你不知道的JavaScript》(中卷和下卷)。
第 一部分 起步
第 1 章 初識(shí)WebAssembly 2
1.1 WebAssembly是什么 2
1.1.1 WebAssembly的先驅(qū):asm.js 3
1.1.2 從asm.js到MVP 3
1.2 WebAssembly解決了哪些問題 4
1.2.1 性能改進(jìn) 4
1.2.2 比JavaScript更快的啟動(dòng)速度 5
1.2.3 可以在瀏覽器中使用JavaScript之外的語言 5
1.2.4 代碼復(fù)用的機(jī)會(huì) 5
1.3 WebAssembly的工作原理 6
1.3.1 編譯器工作原理概覽 6
1.3.2 模塊的加載、編譯和實(shí)例化 8
1.4 WebAssembly 模塊的結(jié)構(gòu) 9
1.4.1 前導(dǎo) 10
1.4.2 已知段 10
1.4.3 自定義段 10
1.5 WebAssembly文本格式 10
1.6 WebAssembly如何獲得安全性 11
1.7 哪些語言可用來創(chuàng)建WebAssembly模塊 11
1.8 我的模塊可以用在何處 12
1.9 小結(jié) 13
第 2 章 初探WebAssembly模塊內(nèi)部 14
2.1 已知段 15
2.2 自定義段 18
2.3 小結(jié) 19
第 3 章 創(chuàng)建自己的第 一個(gè)WebAssembly模塊 20
3.1 Emscripten工具包 20
3.2 WebAssembly模塊 21
3.3 Emscripten輸出選項(xiàng) 23
3.4 用Emscripten編譯C/C++并使用HTML模板 24
3.5 讓Emscripten生成JavaScript plumbing代碼 29
3.5.1 用Emscripten生成的JavaScript編譯C/C++ 30
3.5.2 創(chuàng)建一個(gè)供瀏覽器使用的基本HTML網(wǎng)頁 32
3.6 讓Emscripten只生成WebAssembly文件 35
3.6.1 用Emscripten將C/C++編譯為副模塊 36
3.6.2 瀏覽器中的加載與實(shí)例化 38
3.7 功能檢測(cè):如何測(cè)試WebAssembly是否可用 44
3.8 現(xiàn)實(shí)用例 45
3.9 練習(xí) 46
3.10 小結(jié) 46
第二部分 使用模塊
第 4 章 復(fù)用現(xiàn)有C++代碼庫(kù) 48
4.1 用C/C++創(chuàng)建帶Emscripten plumbing的模塊 50
4.1.1 修改C++代碼 50
4.1.2 將代碼編譯為WebAssembly模塊 55
4.1.3 創(chuàng)建網(wǎng)頁 56
4.1.4 創(chuàng)建與模塊交互的JavaScript代碼 57
4.1.5 查看結(jié)果 62
4.2 用C/C++創(chuàng)建不使用Emscripten的模塊 63
4.2.1 修改C++代碼 64
4.2.2 將代碼編譯為WebAssembly模塊 69
4.2.3 創(chuàng)建與模塊交互的JavaScript代碼 69
4.2.4 查看結(jié)果 74
4.3 現(xiàn)實(shí)用例 74
4.4 練習(xí) 74
4.5 小結(jié) 75
第 5 章 創(chuàng)建調(diào)用JavaScript的WebAssembly模塊 76
5.1 用C/C++創(chuàng)建帶Emscripten plumbing的模塊 78
5.1.1 調(diào)整C++代碼 79
5.1.2 創(chuàng)建將要包含到Emscripten生成的JavaScript文件中的JavaScript代碼 81
5.1.3 將代碼編譯為WebAssembly模塊 82
5.1.4 調(diào)整網(wǎng)頁的JavaScript代碼 83
5.1.5 查看結(jié)果 86
5.2 用C/C++創(chuàng)建不帶Emscripten plumbing的模塊 86
5.2.1 C++修改 88
5.2.2 將代碼編譯為WebAssembly模塊 89
5.2.3 調(diào)整將與模塊交互的JavaScript代碼 90
5.2.4 查看結(jié)果 92
5.3 現(xiàn)實(shí)用例 93
5.4 練習(xí) 93
5.5 小結(jié) 93
第 6 章 創(chuàng)建通過函數(shù)指針與JavaScript交流的WebAssembly模塊 95
6.1 用C/C++創(chuàng)建帶Emscripten plumbing的模塊 96
6.1.1 使用JavaScript傳給模塊的函數(shù)指針 96
6.1.2 調(diào)整C++代碼 97
6.1.3 將代碼編譯為WebAssembly模塊 101
6.1.4 調(diào)整網(wǎng)頁JavaScript代碼 102
6.1.5 查看結(jié)果 107
6.2 用C/C++創(chuàng)建不帶Emscriptenplumbing的模塊 108
6.2.1 使用JavaScript傳給模塊的函數(shù)指針 109
6.2.2 修改C++代碼 109
6.2.3 將代碼編譯為WebAssembly模塊 110
6.2.4 調(diào)整與模塊交互的JavaScript 111
6.2.5 查看結(jié)果 119
6.3 現(xiàn)實(shí)用例 119
6.4 練習(xí) 120
6.5 小結(jié) 120
第三部分 高級(jí)主題
第 7 章 動(dòng)態(tài)鏈接:基礎(chǔ) 122
7.1 動(dòng)態(tài)鏈接:優(yōu)點(diǎn)與缺點(diǎn) 123
7.2 動(dòng)態(tài)鏈接選項(xiàng) 123
7.2.1 副模塊與主模塊 124
7.2.2 動(dòng)態(tài)鏈接:dlopen 125
7.2.3 動(dòng)態(tài)鏈接:dynamicLibraries 133
7.2.4 動(dòng)態(tài)鏈接:WebAssembly JavaScript API 137
7.3 動(dòng)態(tài)鏈接回顧 143
7.4 現(xiàn)實(shí)用例 144
7.5 練習(xí) 144
7.6 小結(jié) 144
第 8 章 動(dòng)態(tài)鏈接:實(shí)現(xiàn) 145
8.1 創(chuàng)建WebAssembly模塊 147
8.1.1 將文件validate.cpp中的邏輯分割為兩個(gè)文件 149
8.1.2 為Place Order表邏輯創(chuàng)建新的C++文件 151
8.1.3 用Emscripten生成WebAssembly副模塊 154
8.1.4 定義一個(gè)JavaScript函數(shù)來處理驗(yàn)證問題 158
8.1.5 用Emscripten生成WebAssembly主模塊 158
8.2 調(diào)整網(wǎng)頁 160
8.2.1 調(diào)整網(wǎng)頁的JavaScript代碼 163
8.2.2 查看結(jié)果 171
8.3 現(xiàn)實(shí)用例 172
8.4 練習(xí) 172
8.5 小結(jié) 173
第9 章 線程:Web worker與pthread 174
9.1 Web worker的好處 175
9.2 使用Web worker的考量 176
9.3 用Web worker預(yù)取WebAssembly模塊 176
9.3.1 調(diào)整calculate_primes邏輯 178
9.3.2 用Emscripten生成WebAssembly文件 180
9.3.3 復(fù)制文件到正確位置 180
9.3.4 為網(wǎng)頁創(chuàng)建HTML 文件 181
9.3.5 為網(wǎng)頁創(chuàng)建JavaScript文件 182
9.3.6 創(chuàng)建Web worker的JavaScript文件 184
9.3.7 查看結(jié)果 185
9.4 使用pthread 186
9.4.1 調(diào)整calculate_primes邏輯以創(chuàng)建并使用4個(gè)pthread線程 187
9.4.2 用Emscripten生成WebAssembly文件 190
9.4.3 查看結(jié)果 191
9.5 現(xiàn)實(shí)用例 193
9.6 練習(xí) 194
9.7 小結(jié) 194
第 10 章 Node.js中的WebAssembly模塊 195
10.1 回顧前面所學(xué)內(nèi)容 196
10.2 服務(wù)器端驗(yàn)證 196
10.3 使用Emscripten創(chuàng)建模塊 197
10.3.1 加載WebAssembly模塊 198
10.3.2 調(diào)用WebAssembly模塊內(nèi)函數(shù) 199
10.3.3 調(diào)入JavaScript代碼 202
10.3.4 調(diào)用JavaScript函數(shù)指針 204
10.4 使用WebAssembly JavaScript API 206
10.4.1 加載并實(shí)例化WebAssembly模塊 207
10.4.2 調(diào)用WebAssembly模塊內(nèi)函數(shù) 208
10.4.3 WebAssembly模塊調(diào)入JavaScript代碼 212
10.4.4 WebAssembly模塊調(diào)用JavaScript函數(shù)指針 215
10.5 現(xiàn)實(shí)用例 218
10.6 練習(xí) 219
10.7 小結(jié) 219
第四部分 調(diào)試與測(cè)試
第 11 章 WebAssembly文本格式 222
11.1 用WebAssembly文本格式創(chuàng)建游戲的核心邏輯 225
11.1.1 模塊段 225
11.1.2 注釋 227
11.1.3 函數(shù)簽名 227
11.1.4 module節(jié)點(diǎn) 228
11.1.5 import節(jié)點(diǎn) 229
11.1.6 global節(jié)點(diǎn) 232
11.1.7 export節(jié)點(diǎn) 233
11.1.8 start節(jié)點(diǎn) 234
11.1.9 code節(jié)點(diǎn) 235
11.1.10 type節(jié)點(diǎn) 252
11.1.11 data節(jié)點(diǎn) 254
11.2 從文本格式生成WebAssembly模塊 255
11.3 Emscripten生成模塊 256
11.3.1 創(chuàng)建C++文件 256
11.3.2 生成WebAssembly模塊 257
11.4 創(chuàng)建HTML和JavaScript文件 258
11.4.1 修改HTML文件 258
11.4.2 創(chuàng)建JavaScript文件 260
11.5 查看結(jié)果 265
11.6 現(xiàn)實(shí)用例 265
11.7 練習(xí) 265
11.8 小結(jié) 266
第 12 章 調(diào)試 267
12.1 擴(kuò)展游戲 268
12.2 調(diào)整HTML代碼 269
12.3 顯示試驗(yàn)次數(shù) 270
12.3.1 JavaScript函數(shù)generateCards 271
12.3.2 調(diào)整文本格式 272
12.3.3 生成Wasm文件 272
12.3.4 測(cè)試修改 274
12.4 增加試驗(yàn)次數(shù) 275
12.4.1 JavaScript函數(shù)updateTriesTotal 276
12.4.2 調(diào)整文本格式 277
12.4.3 生成Wasm文件 278
12.4.4 測(cè)試修改 279
12.5 更新總結(jié)屏幕 286
12.5.1 JavaScript函數(shù)levelComplete 287
12.5.2 調(diào)整文本格式 288
12.5.3 生成Wasm文件 289
12.5.4 測(cè)試修改 290
12.6 練習(xí) 290
12.7 小結(jié) 291
第 13 章 測(cè)試——然后呢 292
13.1 安裝JavaScript測(cè)試框架 293
13.1.1 文件package.json 294
13.1.2 安裝Mocha和Chai 295
13.2 創(chuàng)建并運(yùn)行測(cè)試 295
13.2.1 編寫測(cè)試 296
13.2.2 從命令行運(yùn)行測(cè)試 299
13.2.3 加載測(cè)試的HTML頁面 300
13.2.4 從瀏覽器運(yùn)行測(cè)試 302
13.2.5 讓測(cè)試通過 303
13.3 下一步是什么 304
13.4 練習(xí) 304
13.5 小結(jié) 304
附錄A 安裝與工具設(shè)置 306
附錄B ccall、cwrap以及直接函數(shù)調(diào)用 314
附錄C Emscripten宏 320
附錄D 練習(xí)答案 335
附錄E 文本格式進(jìn)階 354