Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

report: gzip treemap data #12519

Merged
merged 35 commits into from
May 27, 2021
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
Show all changes
35 commits
Select commit Hold shift + click to select a range
d5123ca
report: encode data even if very large
connorjclark May 19, 2021
267d578
ok
connorjclark May 19, 2021
d7281c0
rm
connorjclark May 20, 2021
ff0bfd1
no btoa lol
connorjclark May 20, 2021
c417fcb
benchmark
connorjclark May 20, 2021
8ac3a39
lol
connorjclark May 20, 2021
720c427
test
connorjclark May 20, 2021
f0e8949
pako
connorjclark May 20, 2021
6d6e453
fixtest
connorjclark May 20, 2021
ef3e69e
test
connorjclark May 20, 2021
c9c60df
minify
connorjclark May 20, 2021
585bfa0
Merge remote-tracking branch 'origin/master' into treemap-encode
connorjclark May 20, 2021
a638270
tweak
connorjclark May 20, 2021
9eb78f6
dont use minified
connorjclark May 20, 2021
d985f61
gzip optional
connorjclark May 20, 2021
13a4671
upgrade puppeteer for compression stream
connorjclark May 20, 2021
07e3c8d
revert puppeteer upgrade
connorjclark May 21, 2021
ea226a6
Merge remote-tracking branch 'origin/master' into treemap-encode
connorjclark May 21, 2021
5365e53
update
connorjclark May 21, 2021
a6ff9bb
yay
connorjclark May 21, 2021
b473636
pr
connorjclark May 21, 2021
50ff2f1
names
connorjclark May 24, 2021
ca16fff
deprecate postmessage
connorjclark May 24, 2021
5b2f7d3
rename
connorjclark May 25, 2021
b8e6b84
tweak
connorjclark May 25, 2021
c6dafbd
pr
connorjclark May 25, 2021
56a55e0
rename
connorjclark May 25, 2021
363022e
comment
connorjclark May 25, 2021
e33568a
rename
connorjclark May 25, 2021
941cadb
tweak
connorjclark May 26, 2021
d55f819
Update types/html-renderer.d.ts
connorjclark May 26, 2021
b8d8aff
edit
connorjclark May 27, 2021
f757094
connorjclark May 27, 2021
f0a38c0
Merge remote-tracking branch 'origin/master' into treemap-encode
connorjclark May 27, 2021
d45dc4b
merge
connorjclark May 27, 2021
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions build/build-treemap.js
Original file line number Diff line number Diff line change
Expand Up @@ -57,6 +57,7 @@ async function run() {
/* eslint-enable max-len */
buildStrings(),
{path: '../../lighthouse-core/report/html/renderer/i18n.js'},
{path: '../../lighthouse-core/report/html/renderer/base64.js'},
{path: 'src/**/*'},
],
assets: [
Expand Down
1 change: 1 addition & 0 deletions lighthouse-core/report/html/html-report-assets.js
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@ const REPORT_JAVASCRIPT = [
fs.readFileSync(__dirname + '/renderer/pwa-category-renderer.js', 'utf8'),
fs.readFileSync(__dirname + '/renderer/report-renderer.js', 'utf8'),
fs.readFileSync(__dirname + '/renderer/i18n.js', 'utf8'),
fs.readFileSync(__dirname + '/renderer/base64.js', 'utf8'),
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🚲 🏠 felt a bit weird to open the base64 file and see compression streams

encoding
text-encoder
text-encoding

any of those feel better to you?

Copy link
Collaborator Author

@connorjclark connorjclark May 21, 2021

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

i thought about renaming it, but the end result is base64'd, it's just that the acceptable input is more than just ascii, so...

idk 👍(rename) 👎 (keep) vote :)

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

File names are about more than just the format of the functions' return types IMO :)

Perhaps I'm alone though...

image

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

i also think the name of the file is a bit odd. +1 to text-encoder

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

TextEncoder.{encode,decode} also has its oddities, and we can't name the global object TextEncoder because that exists :)

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

oh right, globals! lol. text-encoding then.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yeah, -1 to text-encoder for that reason.

I don't care much what it is though. base64 is fine to me because we are hopefully not going to grow our encodings collection :) text-encoding works too

].join(';\n');
const REPORT_CSS = fs.readFileSync(__dirname + '/report-styles.css', 'utf8');
const REPORT_TEMPLATES = fs.readFileSync(__dirname + '/templates.html', 'utf8');
Expand Down
68 changes: 68 additions & 0 deletions lighthouse-core/report/html/renderer/base64.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,68 @@
/**
* @license Copyright 2020 The Lighthouse Authors. All Rights Reserved.
* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0
* Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License.
*/
'use strict';

/* global self btoa atob */

const encode = typeof btoa !== 'undefined' ?
btoa :
/** @param {string} str */
(str) => Buffer.from(str).toString('base64');
const decode = typeof btoa !== 'undefined' ?
connorjclark marked this conversation as resolved.
Show resolved Hide resolved
atob :
/** @param {string} str */
(str) => Buffer.from(str, 'base64').toString();

/**
* @param {string} string
*/
function toBinary(string) {
// const codePoints = [...string].map(c => c.codePointAt(0) || 0);
// return encode(String.fromCharCode(...new Uint8Array(codePoints)));

const chunkSize = 10000;
let str = '';
for (let i = 0; i < string.length; i += chunkSize) {
const codeUnits = new Uint16Array(Math.min(chunkSize, string.length - i));
for (let i = 0; i < codeUnits.length; i++) {
codeUnits[i] = string.charCodeAt(i);
}
str += String.fromCharCode(...new Uint8Array(codeUnits.buffer));
}

return encode(str);
}

/**
* @param {string} encoded
*/
function fromBinary(encoded) {
// const binary = decode(encoded);
// const bytes = new Uint8Array(binary.length);
// for (let i = 0; i < bytes.length; i++) {
// bytes[i] = binary.charCodeAt(i);
// }
// return String.fromCodePoint(...new Uint16Array(bytes.buffer));

const chunkSize = 10000;
let str = '';
const decoded = decode(encoded);
for (let i = 0; i < decoded.length; i += chunkSize) {
const bytes = new Uint8Array(Math.min(chunkSize, decoded.length - i));
for (let j = 0; j < bytes.length; j++) {
bytes[j] = decoded.charCodeAt(i + j);
}
str += String.fromCharCode(...new Uint16Array(bytes.buffer));
}

return str;
}

if (typeof module !== 'undefined' && module.exports) {
module.exports = {toBinary, fromBinary};
} else {
self.Base64 = {toBinary, fromBinary};
}
19 changes: 3 additions & 16 deletions lighthouse-core/report/html/renderer/report-ui-features.js
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@
* the report.
*/

/* globals getFilenamePrefix Util ElementScreenshotRenderer */
/* globals getFilenamePrefix Util Base64 ElementScreenshotRenderer */

/** @typedef {import('./dom')} DOM */

Expand Down Expand Up @@ -573,6 +573,7 @@ class ReportUIFeatures {
const url = getAppsOrigin() + '/treemap/';
const windowName = `treemap-${json.requestedUrl}`;

method= 'url';
if (method === 'postMessage') {
ReportUIFeatures.openTabAndSendData(treemapOptions, url, windowName);
} else {
Expand Down Expand Up @@ -603,7 +604,6 @@ class ReportUIFeatures {
}
});

// The popup's window.name is keyed by version+url+fetchTime, so we reuse/select tabs correctly
const popup = window.open(url, windowName);
}

Expand All @@ -616,21 +616,8 @@ class ReportUIFeatures {
*/
static openTabWithUrlData(data, url_, windowName) {
const url = new URL(url_);
url.hash = toBinary(JSON.stringify(data));

// The popup's window.name is keyed by version+url+fetchTime, so we reuse/select tabs correctly
url.hash = Base64.toBinary(JSON.stringify(data));
window.open(url.toString(), windowName);

/**
* @param {string} string
*/
function toBinary(string) {
const codeUnits = new Uint16Array(string.length);
for (let i = 0; i < codeUnits.length; i++) {
codeUnits[i] = string.charCodeAt(i);
}
return btoa(String.fromCharCode(...new Uint8Array(codeUnits.buffer)));
}
}

/**
Expand Down
29 changes: 29 additions & 0 deletions lighthouse-core/test/report/html/renderer/base64-test.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
/**
* @license Copyright 2021 The Lighthouse Authors. All Rights Reserved.
* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0
* Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License.
*/
'use strict';

const Base64 = require('../../../../report/html/renderer/base64.js');

/* eslint-env jest */

describe('base64', () => {
/** @type {string} */
function test(str) {
const roundtrip = Base64.fromBinary(Base64.toBinary(str));
expect(roundtrip.length).toEqual(str.length);
expect(roundtrip).toEqual(str);
}

it('works', () => {
test('');
test('hello');
test('{åß∂œ∑´}');
test('Some examples of emoji are 😃, 🧘🏻‍♂️, 🌍, 🍞, 🚗, 📞, 🎉, ♥️, 🍆, and 🏁.');
test('.'.repeat(125183));
test('😃'.repeat(125183));
test(JSON.stringify(require('../../../../../lighthouse-treemap/app/debug.json')));
connorjclark marked this conversation as resolved.
Show resolved Hide resolved
});
});
16 changes: 2 additions & 14 deletions lighthouse-treemap/app/src/main.js
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@

/* eslint-env browser */

/* globals I18n webtreemap strings TreemapUtil Tabulator Cell Row */
/* globals I18n webtreemap strings TreemapUtil Base64 Tabulator Cell Row */

const DUPLICATED_MODULES_IGNORE_THRESHOLD = 1024;
const DUPLICATED_MODULES_IGNORE_ROOT_RATIO = 0.01;
Expand Down Expand Up @@ -734,24 +734,12 @@ function showError(message) {
document.body.textContent = message;
}

/**
* @param {string} encoded
*/
function fromBinary(encoded) {
const binary = atob(encoded);
const bytes = new Uint8Array(binary.length);
for (let i = 0; i < bytes.length; i++) {
bytes[i] = binary.charCodeAt(i);
}
return String.fromCharCode(...new Uint16Array(bytes.buffer));
}

async function main() {
/** @type {Record<string, any>} */
let params = {};
if (Object.fromEntries) {
const queryParams = new URLSearchParams(window.location.search);
const hashParams = location.hash ? JSON.parse(fromBinary(location.hash.substr(1))) : {};
const hashParams = location.hash ? JSON.parse(Base64.fromBinary(location.hash.substr(1))) : {};
params = {
...Object.fromEntries(queryParams.entries()),
...hashParams,
Expand Down
2 changes: 2 additions & 0 deletions lighthouse-treemap/types/treemap.d.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import _TreemapUtil = require('../app/src/util.js');
import _Base64 = require('../../lighthouse-core/report/html/renderer/base64.js');

export type Strings = Record<LH.Locale, import('../../lighthouse-core/lib/i18n/locales').LhlMessages>;

Expand Down Expand Up @@ -33,6 +34,7 @@ declare global {
sort(data: any): void;
};
var TreemapUtil: typeof _TreemapUtil;
var Base64: typeof _Base64;
var strings: Strings;

interface Window {
Expand Down
2 changes: 2 additions & 0 deletions types/html-renderer.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ import _PwaCategoryRenderer = require('../lighthouse-core/report/html/renderer/p
import _ReportRenderer = require('../lighthouse-core/report/html/renderer/report-renderer.js');
import _ReportUIFeatures = require('../lighthouse-core/report/html/renderer/report-ui-features.js');
import _Util = require('../lighthouse-core/report/html/renderer/util.js');
import _Base64 = require('../lighthouse-core/report/html/renderer/base64.js');
import _prepareLabData = require('../lighthouse-core/report/html/renderer/psi.js');
import _FileNamer = require('../lighthouse-core/lib/file-namer.js');

Expand All @@ -33,6 +34,7 @@ declare global {
var ReportRenderer: typeof _ReportRenderer;
var ReportUIFeatures: typeof _ReportUIFeatures;
var Util: typeof _Util;
var Base64: typeof _Base64;
var prepareLabData: typeof _prepareLabData;

interface Window {
Expand Down