Skip to content
This repository has been archived by the owner on Nov 28, 2022. It is now read-only.

perf: oas-form bloat reduction and bundle overhauls #1179

Merged
merged 20 commits into from
Feb 19, 2021

Conversation

erunion
Copy link
Member

@erunion erunion commented Feb 9, 2021

☁️   CI App 🎫 RM-354

🧰 What's being changed?

  • Eliminate the need for core-js and instead use our core Babel config when building the dist for @readme/oas-form.
    • Since we're already loading in @babel/preset-env for handling polyfills, we don't need to also load in core-js for the same (and also we were only loading that in for a polyfill of Array.includes and Array.fill).
  • Stop building the lib/ directory for @readme/oas-form. It's holdover from RJSF and we use it, need it, nor do we need to keep the Babel infrastructure in this package to maintain it.
  • Remove existing (unused) validation support.
    • Removes all support for exposing errors from AJV validation including the rawErrors, and errorSchema props as well as the onError event handler.
  • Removing support for JSON Schema dependencies from oas-form.
    • OAS 3.0 doesn't support dependencies at all. OAS 3.1 supports a flavor of this through dependentSchemas, but we aren't there yet to be able to adequately support this so I'm pulling it as it adds a chunk of unused bloat.
  • Removing the omitExtraData and liveOmit props.
    • They're there to prevent data that's not in the form from getting into formData when onSubmit is called but as we neither set these to true or have any cases where form data would be present without having gone through the form it doesn't make sense to keep it.
  • Removing the deprecated autocomplete prop.
    • There's an autocomplete and autoComplete prop. The former is deprecated for the latter. We use neither, but being able to extend that down to the Form component is nice and we might use it in the future so I'm removing the deprecated version.
  • Removing the withTheme export.
    • It's present for people to add additional theme-driven props to the core Form component, but since we just use this stuff directly we don't need it around. Dropping it also allows us to remove the dependency on react-is for detecting React.forwardRef components.
  • Removing the ui:order UI schema property for customizing the order of object properties.
    • We've never used this, have no way of using it with the way we generate JSON Schema, and have no plans of using it.
  • Remove Lodash
    • With the removal of the above code we can now stop using Lodash and its union, pick, get, and isEmpty methods.
  • Remove AJV

🐳 Why remove AJV and validation support?

The amount of overhead for what AJV does, validate JSON Schema, is incredible compared to what we actually need it to do: validate form inputs.

Since we don't need to use AJV to validate that arrays are arrays, or objects are objects, because those schemas are already handled by way of the form construction, what's left for it to validate is schema patterns. Well thankfully input patterns are natively supported on every browser that we target: https://caniuse.com/input-pattern. Now while we can't natively render multiple errors on inputs at the same time, we can use native APIs to compile those errors together and render them somewhere (as demonstrated here).

That said, since we aren't even doing validation right now, and don't plan to do it with AJV in the future, it doesn't make sense to ship all this unused bloat right now and for the indefinite future.

🧹 Bundle size changes

The file sizes here are what Webpack outputs to the console when running npm run build. They do not take gzipping into account.

Branch @readme/api-explorer @readme/oas-form
Before (next) 2.65 MiB 297 KiB
After 2.46MiB 136 KiB

But wait, how come removing AJV didn't clear off hella space on the bundle? Well the short of it is that there's still a lot of packages that we're loading into the bundle that we shouldn't be; namely @readme/syntax-highlighter:

Screen Shot 2021-02-17 at 4 35 20 PM

🧙 Future

There are still a lot of improvements that we can make to further reduce the size of our API Explorer bundles:

  • Treat @readme/syntax-highlighter as an external. Unfortunately this isn't that easy because @readme/ui and @readme/oas-to-snippet load it in so we'd need to make some improvements there.
  • Since @readme/ui is deprecated we should pull in the components that we use there into this library. This'll allow to exclude all components, compositions, and views that we don't use.
  • Possibly fork @apidevtools/json-schema-ref-parser? It has support for parsing YAML files, but since our oas library, which loads it for dereferencing, only handles JSON, it doesn't make much sense to ship full copies of js-yaml and esprima in our bundles.

🧬 Testing

  • Does the explorer throw any erorrs?
  • Does polymorphism still work?
  • Do discriminators still work?
  • Does form data updating still work?
  • Does Try It still work?

@erunion erunion temporarily deployed to readme-api-e-refactor-o-4aoxfi February 9, 2021 01:42 Inactive
@erunion erunion temporarily deployed to readme-api-e-refactor-o-4aoxfi February 9, 2021 01:42 Inactive
@erunion erunion added the type:refactor Issues about tackling technical debt label Feb 9, 2021
@erunion erunion changed the title perf: oas-form validation overhauls perf: oas-form validation and bundle overhauls Feb 9, 2021
@erunion erunion force-pushed the refactor/oas-form-validation branch from 2fae577 to 1c7f4ce Compare February 16, 2021 21:28
@erunion erunion temporarily deployed to readme-api-e-refactor-o-hzudqu February 16, 2021 21:28 Inactive
@erunion erunion temporarily deployed to readme-api-e-refactor-o-hzudqu February 17, 2021 01:03 Inactive
@erunion erunion temporarily deployed to readme-api-e-refactor-o-hzudqu February 17, 2021 02:04 Inactive
@erunion erunion force-pushed the refactor/oas-form-validation branch from f1ef333 to ab4705f Compare February 17, 2021 18:15
@erunion erunion temporarily deployed to readme-api-e-refactor-o-hzudqu February 17, 2021 18:15 Inactive
@erunion erunion changed the title perf: oas-form validation and bundle overhauls perf: oas-form bloat reduction and bundle overhauls Feb 17, 2021
@erunion erunion temporarily deployed to readme-api-e-refactor-o-hzudqu February 17, 2021 19:25 Inactive
@erunion erunion temporarily deployed to readme-api-e-refactor-o-hzudqu February 17, 2021 19:49 Inactive
@erunion erunion temporarily deployed to readme-api-e-refactor-o-hzudqu February 17, 2021 19:58 Inactive
@erunion erunion temporarily deployed to readme-api-e-refactor-o-hzudqu February 17, 2021 20:50 Inactive
@erunion erunion temporarily deployed to readme-api-e-refactor-o-hzudqu February 17, 2021 21:00 Inactive
@erunion erunion temporarily deployed to readme-api-e-refactor-o-hzudqu February 17, 2021 21:22 Inactive
@erunion erunion temporarily deployed to readme-api-e-refactor-o-hzudqu February 17, 2021 21:40 Inactive
@erunion erunion temporarily deployed to readme-api-e-refactor-o-hzudqu February 17, 2021 23:18 Inactive
@erunion erunion temporarily deployed to readme-api-e-refactor-o-hzudqu February 18, 2021 00:30 Inactive
@erunion erunion temporarily deployed to readme-api-e-refactor-o-hzudqu February 18, 2021 00:52 Inactive
@erunion erunion marked this pull request as ready for review February 18, 2021 01:02
Copy link
Contributor

@rafegoldberg rafegoldberg left a comment

Choose a reason for hiding this comment

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

This work looks great! From my once-over:

  • Does the explorer throw any erorrs?
    Randomly poked through our list of OAS schemas in the CI app—most all of 'em rendered great! I did come across one or two errors, but these endpoints are also on the fritz in "production" (on preview.readme.io, that is) so I doubt it's anything specific to this PR!
  • Does polymorphism still work?
    I checked out the polymorphism example and played around with various bits and pieces: updating data in the form, futzing with the JSON editor, scanning the req/res snippets, etc. E'erything seemed in good working order to my eye.
  • Does form data updating still work?
    Yep, at least from what I know to test! Snippet generation looks good. JSON editor reset is working nicely.
All that said, I'm an OAS noob so I wouldn't be surprised if I missed some deeper, mission-critical functionality... 😶 Will leave the rest of these tests to those more qualified!
  • Does Try It still work?
  • Do discriminators still work?

@erunion
Copy link
Member Author

erunion commented Feb 18, 2021

Randomly poked through our list of OAS schemas in the CI app. Most rendered great; where I did see an endpoint or two erroring out I checked em against "production" (preview.readme.io, that is) and they were also erroring there.

@rafegoldberg which ones did you find errors on?

@erunion erunion requested a review from darrenyong February 18, 2021 01:50
@rafegoldberg
Copy link
Contributor

rafegoldberg commented Feb 18, 2021

@erunion there were two if I remember right, but this is the only one I still have the URL for on my clipboard.

@erunion erunion temporarily deployed to readme-api-e-refactor-o-hzudqu February 18, 2021 02:00 Inactive
@erunion erunion temporarily deployed to readme-api-e-refactor-o-hzudqu February 18, 2021 19:24 Inactive
this.state = {
selectedOption: this.getMatchingOption(formData, options),
Copy link
Contributor

Choose a reason for hiding this comment

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

Do we ever provide form data to an initial page load? If so, losing this will stop the polymorphism dropdown from having an initially selected value

Copy link
Member Author

Choose a reason for hiding this comment

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

Thankfully we don't. Only data we provide is through JSON Schema default props, and those get automatically compiled into the initial page load through computeDefaults.

@@ -246,9 +242,6 @@ function computeDefaults(_schema, parentDefaults, rootSchema, rawFormData = {},
}

return computeDefaults(refSchema, defaults, rootSchema, formData, includeUndefinedValues);
Copy link
Contributor

Choose a reason for hiding this comment

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

Discriminators uses this, but I never really bothered to check what it was for? If the discriminator tests run I probably feel fine with this change.

Copy link
Member Author

Choose a reason for hiding this comment

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

This is what compiles the original default formData on load.

@@ -691,124 +648,6 @@ export function retrieveSchema(schema, rootSchema = {}, formData = {}) {
return resolvedSchema;
}

function resolveDependencies(schema, rootSchema, formData) {
Copy link
Contributor

Choose a reason for hiding this comment

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

What are dependencies and why don't we need this?

Copy link
Member Author

Choose a reason for hiding this comment

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

That's all from this https://react-jsonschema-form.readthedocs.io/en/latest/usage/dependencies/. It's not part of the JSON Schema spec anymore.

@erunion erunion temporarily deployed to readme-api-e-refactor-o-hzudqu February 19, 2021 22:07 Inactive
@erunion erunion merged commit f86d388 into next Feb 19, 2021
@erunion erunion deleted the refactor/oas-form-validation branch February 19, 2021 23:38
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
exploration type:refactor Issues about tackling technical debt
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants