diff options
author | Marcos Casagrande <marcoscvp90@gmail.com> | 2020-07-08 04:25:34 +0200 |
---|---|---|
committer | GitHub <noreply@github.com> | 2020-07-07 22:25:34 -0400 |
commit | e4899b6ba417a801ce3d9128c9769e855487682f (patch) | |
tree | e610fc41996679ed9e863cddee028a0a22c36fa8 /cli/js | |
parent | cb98a594522e44fca885ca94ffdcc181ad902603 (diff) |
perf(cli/body): improve .arrayBuffer() speed (#6669)
Diffstat (limited to 'cli/js')
-rw-r--r-- | cli/js/web/body.ts | 34 | ||||
-rw-r--r-- | cli/js/web/fetch.ts | 3 | ||||
-rw-r--r-- | cli/js/web/request.ts | 2 |
3 files changed, 25 insertions, 14 deletions
diff --git a/cli/js/web/body.ts b/cli/js/web/body.ts index 80c4b646a..3bcda0634 100644 --- a/cli/js/web/body.ts +++ b/cli/js/web/body.ts @@ -18,6 +18,11 @@ import { MultipartParser } from "./fetch/multipart.ts"; const { TextEncoder, TextDecoder } = encoding; const DenoBlob = blob.DenoBlob; +interface BodyMeta { + contentType: string; + size?: number; +} + function validateBodyType(owner: Body, bodySource: BodyInit | null): boolean { if (isTypedArray(bodySource)) { return true; @@ -40,11 +45,17 @@ function validateBodyType(owner: Body, bodySource: BodyInit | null): boolean { } async function bufferFromStream( - stream: ReadableStreamReader + stream: ReadableStreamReader, + size?: number ): Promise<ArrayBuffer> { const encoder = new TextEncoder(); const buffer = new Buffer(); + if (size) { + // grow to avoid unnecessary allocations & copies + buffer.grow(size); + } + while (true) { const { done, value } = await stream.read(); @@ -71,14 +82,13 @@ export const BodyUsedError = export class Body implements domTypes.Body { protected _stream: ReadableStreamImpl<string | ArrayBuffer> | null; - - constructor( - protected _bodySource: BodyInit | null, - readonly contentType: string - ) { + #contentType: string; + #size: number | undefined; + constructor(protected _bodySource: BodyInit | null, meta: BodyMeta) { validateBodyType(this, _bodySource); this._bodySource = _bodySource; - this.contentType = contentType; + this.#contentType = meta.contentType; + this.#size = meta.size; this._stream = null; } @@ -111,15 +121,15 @@ export class Body implements domTypes.Body { public async blob(): Promise<Blob> { return new DenoBlob([await this.arrayBuffer()], { - type: this.contentType, + type: this.#contentType, }); } // ref: https://fetch.spec.whatwg.org/#body-mixin public async formData(): Promise<FormData> { const formData = new FormData(); - if (hasHeaderValueOf(this.contentType, "multipart/form-data")) { - const params = getHeaderValueParams(this.contentType); + if (hasHeaderValueOf(this.#contentType, "multipart/form-data")) { + const params = getHeaderValueParams(this.#contentType); // ref: https://tools.ietf.org/html/rfc2046#section-5.1 const boundary = params.get("boundary")!; @@ -128,7 +138,7 @@ export class Body implements domTypes.Body { return multipartParser.parse(); } else if ( - hasHeaderValueOf(this.contentType, "application/x-www-form-urlencoded") + hasHeaderValueOf(this.#contentType, "application/x-www-form-urlencoded") ) { // From https://github.com/github/fetch/blob/master/fetch.js // Copyright (c) 2014-2016 GitHub, Inc. MIT License @@ -184,7 +194,7 @@ export class Body implements domTypes.Body { enc.encode(this._bodySource).buffer as ArrayBuffer ); } else if (this._bodySource instanceof ReadableStreamImpl) { - return bufferFromStream(this._bodySource.getReader()); + return bufferFromStream(this._bodySource.getReader(), this.#size); } else if ( this._bodySource instanceof FormData || this._bodySource instanceof URLSearchParams diff --git a/cli/js/web/fetch.ts b/cli/js/web/fetch.ts index 156c218a4..33cf12069 100644 --- a/cli/js/web/fetch.ts +++ b/cli/js/web/fetch.ts @@ -110,8 +110,9 @@ export class Response extends Body.Body implements domTypes.Response { } const contentType = headers.get("content-type") || ""; + const size = Number(headers.get("content-length")) || undefined; - super(body, contentType); + super(body, { contentType, size }); this.url = url; this.statusText = statusText; diff --git a/cli/js/web/request.ts b/cli/js/web/request.ts index a9dcce2de..7ea6a9ecd 100644 --- a/cli/js/web/request.ts +++ b/cli/js/web/request.ts @@ -71,7 +71,7 @@ export class Request extends body.Body implements domTypes.Request { } const contentType = headers.get("content-type") || ""; - super(b, contentType); + super(b, { contentType }); this.headers = headers; // readonly attribute ByteString method; |