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
feat: Brotli compression support #432
base: master
Are you sure you want to change the base?
Changes from 6 commits
912aa8c
6a4a361
ec1fa85
4dfbb5c
80511a8
70d8cf1
3f183c2
b8dcd04
b71f9ae
13f00fe
db1d33d
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -18,11 +18,13 @@ import Search from './Search'; | |
import {store} from '../store'; | ||
import ModulesList from './ModulesList'; | ||
|
||
const SIZE_SWITCH_ITEMS = [ | ||
{label: 'Stat', prop: 'statSize'}, | ||
{label: 'Parsed', prop: 'parsedSize'}, | ||
{label: 'Gzipped', prop: 'gzipSize'} | ||
]; | ||
function allSizeSwitchItems() { | ||
return [ | ||
{label: 'Stat', prop: 'statSize'}, | ||
{label: 'Parsed', prop: 'parsedSize'}, | ||
{label: window.compressedSizeLabel, prop: 'gzipSize'} | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Can we change |
||
]; | ||
} | ||
|
||
@observer | ||
export default class ModulesTreemap extends Component { | ||
|
@@ -138,7 +140,7 @@ export default class ModulesTreemap extends Component { | |
renderModuleSize(module, sizeType) { | ||
const sizeProp = `${sizeType}Size`; | ||
const size = module[sizeProp]; | ||
const sizeLabel = SIZE_SWITCH_ITEMS.find(item => item.prop === sizeProp).label; | ||
const sizeLabel = allSizeSwitchItems().find(item => item.prop === sizeProp).label; | ||
const isActive = (store.activeSize === sizeProp); | ||
|
||
return (typeof size === 'number') ? | ||
|
@@ -162,7 +164,8 @@ export default class ModulesTreemap extends Component { | |
}; | ||
|
||
@computed get sizeSwitchItems() { | ||
return store.hasParsedSizes ? SIZE_SWITCH_ITEMS : SIZE_SWITCH_ITEMS.slice(0, 1); | ||
const items = allSizeSwitchItems(); | ||
return store.hasParsedSizes ? items : items.slice(0, 1); | ||
} | ||
|
||
@computed get activeSizeItem() { | ||
|
Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.
Original file line number | Diff line number | Diff line change | ||||
---|---|---|---|---|---|---|
|
@@ -2,16 +2,21 @@ const fs = require('fs'); | |||||
const path = require('path'); | ||||||
|
||||||
const _ = require('lodash'); | ||||||
const gzipSize = require('gzip-size'); | ||||||
|
||||||
const Logger = require('./Logger'); | ||||||
const Folder = require('./tree/Folder').default; | ||||||
const {parseBundle} = require('./parseUtils'); | ||||||
const {createAssetsFilter} = require('./utils'); | ||||||
const {gzipSize, brotliSize} = require('./sizeUtils'); | ||||||
|
||||||
const FILENAME_QUERY_REGEXP = /\?.*$/u; | ||||||
const FILENAME_EXTENSIONS = /\.(js|mjs)$/iu; | ||||||
|
||||||
const COMPRESSED_SIZE = { | ||||||
gzip: gzipSize, | ||||||
brotli: brotliSize | ||||||
}; | ||||||
|
||||||
module.exports = { | ||||||
getViewerData, | ||||||
readStatsFromFile | ||||||
|
@@ -20,11 +25,15 @@ module.exports = { | |||||
function getViewerData(bundleStats, bundleDir, opts) { | ||||||
const { | ||||||
logger = new Logger(), | ||||||
excludeAssets = null | ||||||
excludeAssets = null, | ||||||
compressionAlgorithm | ||||||
} = opts || {}; | ||||||
|
||||||
const isAssetIncluded = createAssetsFilter(excludeAssets); | ||||||
|
||||||
const compressedSize = COMPRESSED_SIZE[compressionAlgorithm]; | ||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Let's better call it |
||||||
if (!compressedSize) throw new Error(`Unsupported compression algorithm: ${compressionAlgorithm}.`); | ||||||
|
||||||
// Sometimes all the information is located in `children` array (e.g. problem in #10) | ||||||
if (_.isEmpty(bundleStats.assets) && !_.isEmpty(bundleStats.children)) { | ||||||
const {children} = bundleStats; | ||||||
|
@@ -102,7 +111,7 @@ function getViewerData(bundleStats, bundleDir, opts) { | |||||
|
||||||
if (assetSources) { | ||||||
asset.parsedSize = Buffer.byteLength(assetSources.src); | ||||||
asset.gzipSize = gzipSize.sync(assetSources.src); | ||||||
asset.gzipSize = compressedSize(assetSources.src); | ||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. ?
Suggested change
|
||||||
} | ||||||
|
||||||
// Picking modules from current bundle script | ||||||
|
@@ -143,7 +152,7 @@ function getViewerData(bundleStats, bundleDir, opts) { | |||||
} | ||||||
|
||||||
asset.modules = assetModules; | ||||||
asset.tree = createModulesTree(asset.modules); | ||||||
asset.tree = createModulesTree(asset.modules, {compressedSize}); | ||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
Suggested change
|
||||||
return result; | ||||||
}, {}); | ||||||
|
||||||
|
@@ -203,8 +212,8 @@ function isRuntimeModule(statModule) { | |||||
return statModule.moduleType === 'runtime'; | ||||||
} | ||||||
|
||||||
function createModulesTree(modules) { | ||||||
const root = new Folder('.'); | ||||||
function createModulesTree(modules, opts) { | ||||||
const root = new Folder('.', opts); | ||||||
|
||||||
modules.forEach(module => root.addModule(module)); | ||||||
root.mergeNestedFolders(); | ||||||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,13 @@ | ||
const zlib = require('zlib'); | ||
|
||
export function gzipSize(input) { | ||
return zlib.gzipSync(input, {level: 9}).length; | ||
} | ||
|
||
export function brotliSize(input) { | ||
if (typeof zlib.brotliCompressSync !== 'function') { | ||
throw new Error('Brotli compression requires Node.js v10.16.0 or higher.'); | ||
} | ||
dcsaszar marked this conversation as resolved.
Show resolved
Hide resolved
|
||
|
||
return zlib.brotliCompressSync(input).length; | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Can we make it so that the added option for
defaultSizes
would bebrotli
instead ofcompressed
? That way the current, default gzip usage would not have to be changed.That way we could keep the gzip-related documentation intact and only worry about adding new documentation related to the brotli options.
I could imagine that the fourth size definition documentation here could look something like this: