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

Add babel-plugin-optimize-react #32445

Closed
wants to merge 1 commit into from

Conversation

jsnajdr
Copy link
Member

@jsnajdr jsnajdr commented Apr 20, 2019

Trying out a Babel plugin I discovered when reading about Create React App 3.0 (facebook/create-react-app#6219).

The most interesting thing it does is reshuffling the React import code so that React.createElement references can be turned into one-letter mangled identifiers. This doesn't happen by default, at least not with webpack: accessing bindings imported from other modules is a rather complicated code that the minifier doesn't compress well.

This should help compress large JSX trees, e.g., the inline SVGs we still use a lot.

The results are consisted across all our chunks: parsed size gets smaller, gzipped size gets bigger.

Cc @trueadm who expressed interest in large apps giving the plugin a test drive. See this bundle size report from out bot that runs webpack-bundle-analyzer on every PR.

@matticbot
Copy link
Contributor

@jsnajdr jsnajdr force-pushed the add/babel-plugin-optimize-react branch from 5e51de6 to 9f89de3 Compare April 20, 2019 09:51
@matticbot
Copy link
Contributor

Here is how your PR affects size of JS and CSS bundles shipped to the user's browser:

Webpack Runtime
webpack runtime for loading modules. It is included in the HTML page as an inline script. Is downloaded and parsed every time the app is loaded.

name      parsed_size           gzip_size
manifest       +465 B  (+0.3%)     +128 B  (+0.5%)

App Entrypoints
Common code that is always downloaded and parsed every time the app is loaded, no matter which route is used.

name            parsed_size           gzip_size
build               -2560 B  (-0.1%)     +638 B  (+0.1%)
domainsLanding       -378 B  (-0.1%)      +99 B  (+0.1%)

Sections
Sections contain code specific for a given set of routes. Is downloaded and parsed only when a particular route is navigated to.

name                      parsed_size           gzip_size
woocommerce                  -35610 B  (-1.8%)    +3437 B  (+0.7%)
domains                      -17698 B  (-2.6%)    +2021 B  (+1.3%)
stats                        -17217 B  (-1.7%)    +1757 B  (+1.0%)
post-editor                  -15562 B  (-0.7%)    +1817 B  (+0.4%)
checkout                     -14065 B  (-2.0%)    +1938 B  (+1.2%)
purchases                    -12392 B  (-1.9%)    +1664 B  (+1.1%)
plans                        -10214 B  (-3.2%)    +1373 B  (+1.7%)
jetpack-connect               -9644 B  (-2.6%)     +782 B  (+0.8%)
plugins                       -8178 B  (-2.5%)     +465 B  (+0.6%)
notification-settings         -7899 B  (-2.8%)    +1052 B  (+1.6%)
security                      -7712 B  (-2.1%)    +1399 B  (+1.5%)
settings                      -6781 B  (-0.9%)     +497 B  (+0.5%)
posts-pages                   -6503 B  (-2.5%)     +515 B  (+0.7%)
reader                        -6431 B  (-1.8%)    +1356 B  (+1.5%)
activity                      -6162 B  (-0.9%)     +483 B  (+0.5%)
settings-writing              -6106 B  (-0.8%)     +822 B  (+0.9%)
wp-super-cache                -6096 B  (-4.6%)     +412 B  (+1.3%)
help                          -6063 B  (-0.8%)     +406 B  (+0.4%)
account                       -5184 B  (-1.8%)     +960 B  (+1.3%)
feature-upsell                -5179 B  (-9.0%)     +302 B  (+2.8%)
gutenberg-editor              -4986 B  (-0.9%)    +1559 B  (+1.1%)
posts-custom                  -4857 B  (-2.2%)     +451 B  (+0.7%)
email                         -4786 B  (-3.0%)    +1118 B  (+2.7%)
people                        -4489 B  (-1.8%)    +1130 B  (+1.8%)
comments                      -4377 B  (-0.5%)    +1379 B  (+1.2%)
account-close                 -4002 B  (-1.9%)     +270 B  (+0.5%)
themes                        -3980 B  (-2.1%)     +446 B  (+0.9%)
sharing                       -3974 B  (-1.8%)    +1172 B  (+2.1%)
media                         -3607 B  (-1.4%)    +1398 B  (+2.2%)
privacy                       -3600 B  (-1.8%)     +211 B  (+0.4%)
site-blocks                   -3508 B  (-1.6%)     +244 B  (+0.5%)
earn                          -3496 B  (-3.6%)     +158 B  (+0.7%)
happychat                     -3495 B  (-1.7%)     +730 B  (+1.4%)
settings-traffic              -3340 B  (-0.9%)     +381 B  (+0.4%)
me                            -3310 B  (-1.7%)     +209 B  (+0.4%)
settings-security             -2969 B  (-2.4%)     +305 B  (+1.0%)
accept-invite                 -2582 B  (-1.4%)     +112 B  (+0.2%)
google-my-business            -2433 B  (-1.3%)    +1050 B  (+2.0%)
theme                         -2427 B  (-2.1%)     +702 B  (+2.4%)
login                         -2399 B  (-2.4%)     +242 B  (+1.0%)
settings-discussion           -2088 B  (-2.5%)     +189 B  (+1.0%)
settings-performance          -1593 B  (-1.8%)     +279 B  (+1.3%)
jetpack-onboarding            -1365 B  (-2.9%)     +212 B  (+1.8%)
concierge                     -1340 B  (-0.3%)     +274 B  (+0.8%)
signup                        -1329 B  (-1.4%)       -8 B  (-0.0%)
devdocs                       -1283 B  (-1.0%)     +172 B  (+0.5%)
zoninator                     -1190 B  (-1.0%)     +288 B  (+1.0%)
account-recovery              -1070 B  (-3.3%)     +160 B  (+2.0%)
domain-connect-authorize       -586 B  (-4.5%)      +80 B  (+2.1%)
hello-dolly                    -360 B  (-5.1%)      +10 B  (+0.4%)
checklist                      -277 B  (-0.4%)      +17 B  (+0.1%)
mailing-lists                  -232 B  (-4.0%)       +1 B  (+0.1%)
customize                      -218 B  (-0.5%)      +36 B  (+0.3%)
sensei                          -98 B  (-4.1%)      +11 B  (+1.3%)
preview                         -82 B  (-1.3%)       +3 B  (+0.1%)

Async-loaded Components
React components that are loaded lazily, when a certain part of UI is displayed for the first time.

name                                                         parsed_size            gzip_size
async-load-design-blocks                                        -29711 B   (-1.1%)    +2627 B   (+0.5%)
async-load-design                                               -20856 B   (-1.1%)     +736 B   (+0.2%)
async-load-design-playground                                    -19248 B   (-1.1%)     +685 B   (+0.2%)
async-load-layout-guided-tours-component                         -7547 B   (-7.8%)     +617 B   (+2.9%)
async-load-signup-steps-domains                                  -5427 B   (-2.5%)     +192 B   (+0.3%)
async-load-components-web-preview-component                      -4702 B   (-1.4%)     +505 B   (+0.6%)
async-load-post-editor-media-modal                               -3951 B   (-1.4%)     +593 B   (+0.8%)
async-load-signup-steps-plans                                    -3683 B   (-2.3%)     +222 B   (+0.5%)
async-load-signup-steps-plans-without-free                       -3673 B   (-2.2%)     +225 B   (+0.5%)
async-load-notifications                                         -3204 B   (-2.8%)     +220 B   (+0.7%)
async-load-signup-steps-clone-point                              -3165 B   (-0.5%)     +164 B   (+0.2%)
async-load-signup-steps-plans-atomic-store                       -2908 B   (-2.2%)     +146 B   (+0.4%)
async-load-signup-steps-user                                     -2612 B   (-2.6%)     +133 B   (+0.4%)
async-load-blocks-inline-help-popover                            -2417 B   (-0.5%)     +255 B   (+0.6%)
async-load-signup-steps-about                                    -2312 B   (-2.6%)     +142 B   (+0.5%)
async-load-my-sites-site-settings-section-import                 -2103 B   (-1.0%)     +241 B   (+0.2%)
async-load-signup-steps-site-or-domain                           -2064 B   (-4.2%)      +90 B   (+0.6%)
async-load-my-sites-checklist-wpcom-checklist-component-jsx      -1892 B   (-1.2%)     +136 B   (+0.3%)
async-load-extensions-woocommerce-app-store-stats                -1802 B   (-3.7%)     +150 B   (+1.2%)
async-load-signup-steps-rewind-form-creds                        -1800 B   (-2.6%)      +57 B   (+0.3%)
async-load-signup-steps-design-type-with-atomic-store            -1771 B   (-2.8%)     +102 B   (+0.5%)
async-load-signup-steps-clone-credentials                        -1758 B   (-2.6%)      +59 B   (+0.3%)
async-load-extensions-woocommerce-app-store-stats-referrers      -1693 B   (-3.6%)     +143 B   (+1.1%)
async-load-my-sites-current-site-domain-warnings                 -1686 B   (-3.3%)      +14 B   (+0.1%)
async-load-signup-steps-clone-destination                        -1669 B   (-3.5%)      +45 B   (+0.3%)
async-load-blocks-reader-full-post                               -1665 B   (-4.2%)     +100 B   (+1.0%)
async-load-signup-steps-theme-selection                          -1581 B   (-2.4%)     +115 B   (+0.6%)
async-load-signup-steps-clone-start                              -1555 B   (-3.5%)      +47 B   (+0.3%)
async-load-signup-steps-import-url                               -1534 B   (-3.1%)      +49 B   (+0.3%)
async-load-reader-following-manage                               -1518 B   (-1.2%)     +107 B   (+0.3%)
async-load-signup-steps-clone-ready                              -1507 B   (-2.6%)      +47 B   (+0.3%)
async-load-signup-steps-clone-cloning                            -1507 B   (-3.5%)      +50 B   (+0.3%)
async-load-signup-steps-reader-landing                           -1443 B   (-3.5%)      +65 B   (+0.5%)
async-load-reader-search-stream                                  -1318 B   (-1.2%)      +73 B   (+0.3%)
async-load-signup-steps-site-title                               -1271 B   (-3.0%)      +64 B   (+0.5%)
async-load-signup-steps-site                                     -1261 B   (-2.7%)      +83 B   (+0.5%)
async-load-signup-steps-site-topic                               -1236 B   (-2.2%)     +108 B   (+0.6%)
async-load-signup-steps-site-information                         -1226 B   (-2.6%)      +66 B   (+0.4%)
async-load-signup-steps-survey                                   -1209 B   (-2.7%)      +62 B   (+0.4%)
async-load-signup-steps-site-style                               -1189 B   (-2.8%)      +64 B   (+0.4%)
async-load-signup-steps-site-type                                -1165 B   (-2.9%)      +64 B   (+0.5%)
async-load-signup-steps-design-type                              -1161 B   (-2.8%)      +65 B   (+0.5%)
async-load-my-sites-site-settings-section-export                 -1157 B   (-4.2%)     +133 B   (+1.8%)
async-load-reader-site-stream                                    -1155 B   (-3.8%)      +77 B   (+0.9%)
async-load-design-typography                                     -1142 B  (-20.7%)      -17 B   (-1.0%)
async-load-signup-steps-rewind-migrate                           -1139 B   (-2.1%)      +67 B   (+0.4%)
async-load-signup-steps-clone-jetpack                            -1135 B   (-2.8%)      +73 B   (+0.5%)
async-load-signup-steps-rebrand-cities-welcome                   -1123 B   (-2.7%)      +67 B   (+0.5%)
async-load-signup-steps-creds-permission                         -1123 B   (-2.1%)      +57 B   (+0.3%)
async-load-my-sites-guided-transfer                              -1115 B   (-5.7%)     +131 B   (+2.6%)
async-load-signup-steps-rewind-were-backing                      -1107 B   (-2.9%)      +58 B   (+0.4%)
async-load-signup-steps-rewind-add-creds                         -1107 B   (-2.8%)      +58 B   (+0.4%)
async-load-signup-steps-creds-confirm                            -1107 B   (-2.1%)      +56 B   (+0.3%)
async-load-signup-steps-creds-complete                           -1107 B   (-2.9%)      +56 B   (+0.4%)
async-load-signup-steps-site-picker                              -1075 B   (-2.8%)      +56 B   (+0.4%)
async-load-reader-feed-stream                                    -1011 B   (-3.6%)      +64 B   (+0.9%)
async-load-reader-sidebar                                         -926 B   (-2.8%)     +182 B   (+2.1%)
async-load-post-editor-editor-sharing-accordion                   -620 B   (-2.6%)      +54 B   (+0.9%)
async-load-components-jetpack-header-liquidweb                    -582 B   (-3.5%)      -37 B   (-0.6%)
async-load-components-jetpack-header-pressable                    -496 B   (-2.9%)      -18 B   (-0.3%)
async-load-components-jetpack-header-dreamhost                    -496 B   (-2.7%)      -22 B   (-0.4%)
async-load-blocks-calendar-popover                                -465 B   (-0.1%)      +38 B   (+0.1%)
async-load-extensions-woocommerce-app-store-stats-listview        -452 B   (-2.6%)      +35 B   (+0.7%)
async-load-quick-language-switcher                                -434 B   (-1.5%)     +584 B   (+8.0%)
async-load-docs-selectors                                         -418 B   (-8.1%)      +37 B   (+2.2%)
async-load-components-jetpack-header-bluehost                     -416 B   (-3.6%)      -10 B   (-0.3%)
async-load-components-community-translator                        -392 B   (-4.8%)      +21 B   (+0.8%)
async-load-reader-list-stream                                     -370 B   (-3.6%)      +31 B   (+1.1%)
async-load-layout-nps-survey-notice                               -351 B   (-2.7%)      +46 B   (+1.4%)
async-load-reader-tag-stream-main                                 -340 B   (-2.1%)      +31 B   (+0.6%)
async-load-my-sites-current-site-notice                           -298 B   (-1.4%)      +56 B   (+1.0%)
async-load-post-editor-editor-author                              -280 B   (-1.7%)      +20 B   (+0.4%)
async-load-layout-masterbar-drafts-popover                        -273 B   (-3.3%)      +39 B   (+1.5%)
async-load-components-jetpack-header                              -272 B   (-7.0%)      +15 B   (+1.3%)
async-load-blocks-login-social-connect-prompt                     -272 B   (-0.6%)       +3 B   (+0.0%)
async-load-components-happychat                                   -249 B   (-1.5%)     +559 B  (+11.4%)
async-load-lib-preferences-helper                                 -213 B   (-5.4%)      +91 B   (+8.3%)
async-load-reader-conversations-stream                            -200 B   (-4.4%)      +13 B   (+0.8%)
async-load-post-editor-editor-location                            -190 B   (-1.8%)      +19 B   (+0.6%)
async-load-post-editor-editor-discussion                          -172 B   (-3.3%)       +4 B   (+0.2%)
async-load-layout-community-translator-launcher                   -157 B   (-1.7%)      +14 B   (+0.4%)
async-load-post-editor-editor-post-formats-accordion              -145 B   (-2.6%)      +20 B   (+1.1%)
async-load-lib-abtest-test-helper                                 -104 B   (-5.1%)       +7 B   (+0.8%)
async-load-post-editor-editor-seo-accordion                       -102 B   (-1.7%)      +15 B   (+0.8%)
async-load-blocks-inline-help                                      -98 B   (-0.1%)      +25 B   (+0.1%)
async-load-featured-image                                          -80 B   (-2.5%)      +11 B   (+1.0%)
async-load-components-jetpack-header-inmotion                      -80 B   (-0.3%)       -3 B   (-0.0%)
async-load-blocks-inline-help-dialog                               -34 B   (-0.7%)       +8 B   (+0.4%)
async-load-components-webpack-build-monitor                        -28 B   (-1.2%)       +4 B   (+0.4%)
async-load-signup-steps-launch-site                                +21 B   (+4.7%)      +12 B   (+3.9%)
async-load-layout-guided-tours                                     +14 B   (+0.1%)       +6 B   (+0.1%)
async-load-reader-team-main                                        +10 B   (+2.6%)       +6 B   (+2.2%)
async-load-components-jetpack-header-milesweb                      +10 B   (+1.5%)       +4 B   (+1.0%)

Parsed Size: Uncompressed size of the JS and CSS files. This much code needs to be parsed and stored in memory.
Gzip Size: Compressed size of the JS and CSS files. This much data needs to be downloaded over network.

Generated by performance advisor bot at iscalypsofastyet.com.

@jsnajdr jsnajdr requested review from a team and sgomes April 23, 2019 07:52
@jsnajdr jsnajdr self-assigned this Apr 23, 2019
@jsnajdr jsnajdr added Build [Type] Performance [Status] Needs Review The PR is ready for review. This also triggers e2e canary tests and wp-desktop tests automatically. labels Apr 23, 2019
@sgomes
Copy link
Contributor

sgomes commented Apr 23, 2019

Thanks, @jsnajdr, this is a very interesting plugin!

@trueadm: Thank you for listening to community feedback! 🙂If you have a chance to comment here, could you let us know whether the increase in the gzipped size is expected, or whether it's something that should be investigated?

The increase in gzipped size seems unintuitive to me without a deeper understanding of what the plugin is doing. It's quite interesting that it's always one order of magnitude smaller than the reduction in parsed size, and roughly 10% of it.

As it is, I'm not sure if the reduction in parsed size makes up for the increase in gzipped size. We'd be increasing network time in exchange for reducing CPU time, but it's not clear how impactful the latter would be without some in-depth testing. I'll be happy to look into that if the increase in gzipped size is indeed expected.

@trueadm
Copy link

trueadm commented Apr 23, 2019

@sgomes @jsnajdr

Thanks for looking into this and doing this investigation! It's to be expected that gzip will suffer a bit, as there's duplication of createElement and other string. Duplication is where gzip shines, so by removing via this plugin, gzip won't give as many benefits.

In terms of what is better, it's very difficult to say. There's also the additional benefit of better theoretical runtime performance (as you're not doing as many object property lookups in the case of React.createElement). It would be good to get some metrics on the differences in runtime performance if that's possible?

@sgomes
Copy link
Contributor

sgomes commented Apr 23, 2019

@trueadm No problem, I'll run some tests to find out! 👍

@jsnajdr Does running lab-assistant with "before" as the calypso.live branch for bc17fd5 and "after" as the calypso.live branch for this PR, on /start/, with no CPU or network slowdown, using the load metric, sound like a reasonable test?

@jsnajdr
Copy link
Member Author

jsnajdr commented Apr 23, 2019

Does running lab-assistant [...] sound like a reasonable test?

I don't know, probably yes 🙂 But I expect the performance benefit to be very small and hard to measure. Object property lookups and getter functions calls should be cheap operations. And there is so much other code being executed on every React render...

@sgomes
Copy link
Contributor

sgomes commented Apr 23, 2019

@trueadm @jsnajdr

With no throttling of any kind, there's no meaningful difference between both versions.

With a 6x CPU throttle, I'd expect to see a benefit in CPU time if at all present, but there appears to be no significant change either.

I'm currently modifying the tool to allow for network throttling and will report back.

@sgomes
Copy link
Contributor

sgomes commented Apr 23, 2019

@trueadm @jsnajdr

Throttling to 3G fast (1.6Mbps/768Kbps 150ms RTT) in addition to keeping the 6x CPU slowdown doesn't appear to produce any significant difference either.

My testing appears to produce a standard deviation of around 1s across both sets of results, so I'm not surprised the tool isn't able to draw any meaningful conclusions from the data 😕

@trueadm
Copy link

trueadm commented Apr 23, 2019

@sgomes Thanks for digging into it. Based on those results, I'd say that the extra build complexity of having this plugin is probably not going to give any real benefits to this app then. :)

@jsnajdr jsnajdr mentioned this pull request Aug 27, 2020
@jsnajdr
Copy link
Member Author

jsnajdr commented Oct 14, 2020

This was an experimental PR that can be closed now. Some of the optimizations that babel-plugin-optimize-react did are now directly baked into the new JSX transform.

@jsnajdr jsnajdr closed this Oct 14, 2020
@jsnajdr jsnajdr deleted the add/babel-plugin-optimize-react branch October 14, 2020 08:30
@matticbot matticbot removed the [Status] Needs Review The PR is ready for review. This also triggers e2e canary tests and wp-desktop tests automatically. label Oct 14, 2020
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants