浏览代码

updated documentation

Oleksandr Kucherenko 6 年前
父节点
当前提交
e6c59ca1b6
共有 1 个文件被更改,包括 75 次插入0 次删除
  1. 75
    0
      README.md

+ 75
- 0
README.md 查看文件

@@ -174,6 +174,81 @@ Model tested: iPhone 6 (iOS), Nexus 5 (Android).
174 174
 3. Component itself lacks platform support.
175 175
 4. But you can just use the react-native-maps snapshot function: https://github.com/airbnb/react-native-maps#take-snapshot-of-map
176 176
 
177
+## Performance Optimization
178
+
179
+During profiling captured several things that influence on performance:
180
+1) (de-)allocation of memory for bitmap
181
+2) (de-)allocation of memory for Base64 output buffer
182
+3) compression of bitmap to different image formats: PNG, JPG
183
+
184
+To solve that in code introduced several new approaches:
185
+- reusable images, that reduce load on GC;
186
+- reusable arrays/buffers that also reduce load on GC;
187
+- RAW image format for avoiding expensive compression;
188
+- ZIP deflate compression for RAW data, that works faster in compare to `Bitmap.compress`
189
+
190
+more details and code snippet are below.
191
+
192
+### RAW Images
193
+
194
+Introduced a new image format RAW. it correspond a ARGB array of pixels.
195
+
196
+Advantages:
197
+- no compression, so its supper quick. Screenshot taking is less than 16ms;
198
+
199
+RAW format supported for `zip-base64`, `base64` and `tmpfile` result types.
200
+
201
+RAW file on disk saved in format: `${width}:${height}|${base64}` string.
202
+
203
+### zip-base64
204
+
205
+In compare to BASE64 result string this format fast try to apply zip/deflate compression on screenshot results
206
+and only after that convert results to base64 string. In combination zip-base64 + raw we got a super fast
207
+approach for capturing screen views and deliver them to the react side.
208
+
209
+### How to work with zip-base64 and RAW format?
210
+
211
+```js
212
+const fs = require('fs')
213
+const zlib = require('zlib')
214
+const PNG = require('pngjs').PNG
215
+const Buffer = require('buffer').Buffer
216
+
217
+const format = Platform.OS === 'android' ? 'raw' : 'png'
218
+const result = Platform.OS === 'android' ? 'zip-base64' : 'base64'
219
+
220
+captureRef(this.ref, { result, format }).then(data => {
221
+    // expected pattern 'width:height|', example: '1080:1731|'
222
+    const resolution = /^(\d+):(\d+)\|/g.exec(data)
223
+    const width = (resolution || ['', 0, 0])[1]
224
+    const height = (resolution || ['', 0, 0])[2]
225
+    const base64 = data.substr((resolution || [''])[0].length || 0)
226
+
227
+    // convert from base64 to Buffer
228
+    const buffer = Buffer.from(base64, 'base64')
229
+    // un-compress data
230
+    const inflated = zlib.inflateSync(buffer)
231
+    // compose PNG
232
+    const png = new PNG({ width, height })
233
+    png.data = inflated
234
+    const pngData = PNG.sync.write(png)
235
+    // save composed PNG
236
+    fs.writeFileSync(output, pngData)
237
+})
238
+```
239
+
240
+Keep in mind that packaging PNG data is a CPU consuming operation as a `zlib.inflate`.
241
+
242
+Hint: use `process.fork()` approach for converting raw data into PNGs.
243
+
244
+> Note: code is tested in large commercial project.
245
+
246
+> Note #2: Don't forget to add packages into your project:
247
+> ```js
248
+> yarn add pngjs
249
+> yarn add zlib
250
+> ```
251
+
177 252
 ## Troubleshooting / FAQ
178 253
 
179 254
 ### Saving to a file?