Upgrade to Pro — share decks privately, control downloads, hide ads and more …

Fetch Web Streams

WM
November 04, 2017

Fetch Web Streams

JSDC 2017

WM

November 04, 2017
Tweet

More Decks by WM

Other Decks in Technology

Transcript

  1. Node.JS Stream A stream is an abstract interface for working

    with streaming data in Node.js. Streams can be readable, writable, or both. All streams are instances of EventEmitter. Buffer: handle pieces of data I/O data: consume less memory, save more resources Gulp uses streams ” 4
  2. Types of Node.JS Streams Source => Buffer => Sink •

    Readable • fs.createReadStream() • Writable • fs.createWriteStream() • Duplex • net.Socket • Transform • zlib.createDeflate() 5
  3. ReactDOMServer.renderToNodeStream pipe(res) React 16 Server Side Rendering app.get('/', (req, res)

    => { ( <Html initialData={JSON.stringify(initialData)}> <App /> </Html> ). ; }); 7
  4. Web Streams This specification provides APIs for creating, composing, and

    consuming streams of data that map efficiently to low-level I/O primitives. only two types of streams , readable and writable streams https://streams.spec.whatwg.org/ ” 9
  5. start pull cancel ReadableStream const readableStream = new ReadableStream({ (controller)

    {}, (controller) {},// called when stream's buffer isn't full (reason) {} }, queuingStrategy); console.log(readableStream.constructor.prototype); 10
  6. ReadableStreamDefaultController • controller.enqueue(chunk) // queue data in buffer • controller.close()

    • controller.error(e) • controller.desiredSize // the amount of buffer remaining https://jsbin.com/fahavoz/edit?js,console 11
  7. getReader() ReadableStreamDefaultReader const reader = readableStream. ; reader.closed.then(() => {console.log('reader

    closed');}); console.log(await reader.read()); // 1 console.log(await reader.read()); // 2 console.log(await reader.read()); // done • reader.cancel() • reader.releaseLock() 14
  8. locked releaseLock() locked const readableStream = new ReadableStream(); console.log(readableStream. );

    // false const reader = readableStream.getReader(); console.log(readableStream.locked); // true reader. ; console.log(readableStream.locked); // false 15
  9. tee To fork a stream is to obtain two new

    readable streams const teed = stream.tee(); console.log(teed[0]); console.log(teed[1]); 16
  10. start write abort close WritableStream const writableStream = new WritableStream({

    (controller) {}, // controller.error() (chunk, controller) {}, (reason) {}, (controller) {} }, queuingStrategy); 17
  11. getWriter() WritableStreamDefaultWriter const defaultWriter = writableStream. ; • defaultWriter.abort() •

    defaultWriter.close() • defaultWriter.releaseLock() • defaultWriter.write() • defaultWriter.desiredSize • defaultWriter.ready.then() • defaultWriter.closed.then() 18
  12. desiredSize await desiredSize const strategy = new CountQueuingStrategy({highWaterMark: 2}); const

    writer = (new WritableStream({}, strategy)).getWriter(); console.log(writer. ); // 2 writer.write('1'); console.log(writer.desiredSize); // 1 writer.write('1'); writer.write('1'); // desiredSize = 0 writer.write('1'); // Notice the await keyword console.log(writer.desiredSize); // 2 20
  13. backpressure Flow control • desiredSize • can be negative, if

    the queue is over-full • writer.ready • Returns a Promise that resolves when the desired size of the stream's internal queue transitions from non-positive to positive, signaling that it is no longer applying backpressure. 22
  14. getReader() read() value Uint8Array done Response fetch(url).then(response => { //

    response.body is stream const reader = response.body. ; return reader. .then(function processResult(result) { console.log(result. ); // chunk content, if (result. ) return console.log("Fetch complete"); return reader.read().then(processResult); // read more }} http://jsbin.com/vuqasa/edit?js,console 24
  15. Cancelling A stream can be cancelled using stream.cancel() • response.body.cancel()

    • reader.cancel() https://jsbin.com/gameboy/edit?js,console 25
  16. 'fetch' respondWith Service Worker self.addEventListener( , event => { event.

    (new Response(stream, { headers: {'Content-Type': 'text/html'} }));}) https://glitch.com/edit/#!/html-sw-stream?path=public/sw.js:1:0 https://jakearchibald.github.io/isserviceworkerready/demos/simple-stream/ 26
  17. async for await chunk of response.body Async iterators function getResponseSize(url)

    { const response = await fetch(url); let total = 0; (const ) { total += chunk.length; } return total;} 27
  18. response.headers.get('Content-Length') value: {length} chunk.value.length / parseInt(contentLength, 10) Downloading progress const

    response = await fetch(url); const reader = response.body.getReader(); const contentLength = ; const { = {}, done} = await reader.read(); 28
  19. Browsers Support • ReadableStream / WritableStream • Firefox 57+ (not

    enabled yet) • Service Worker respondWith stream • Firefox 58+ • Async iterators: • Chrome 63+ / Firefox 57+ 30
  20. Recap • Streams handle sources of data in a memory

    efficient way • Web Streams is available with Fetch API • Handle Web Stream in Service Worker • Better performance for Progressive Web App 31
  21. Thanks! @kidwm Ref: • 2016 - the year of web

    streams by Jake Archibald • A Guide to Faster Web App I/O and Data Operations with Streams by Umar Hansa 32