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

[Vue] Chunk UMD JavaScript into a set of asynchronously loaded files #18761

Merged
merged 16 commits into from Mar 4, 2022

Conversation

diosmosis
Copy link
Member

@diosmosis diosmosis commented Feb 8, 2022

Description:

cc @tsteur

Now that there are multiple plugins that have Vue code its possible to experiment with different ways of loading the JS, instead of loading everything into a single file and loading it (which might be a problem since the Vue templates get compiled). (This is the simplest/quickest approach I could think of.)

This PoC provides two different methods of loading the UMD JS files:

  • Load each plugin UMD file by itself asynchronously. This results in one <script defer> element per plugin with Vue code. Which could be a lot of AJAX requests eventually.
  • Have a set limit of chunks that can be loaded asynchronously and divide the plugin modules among them so the number of AJAX requests is limited.

In both they are not loaded into the main assetmanager JS files, they are instead put into separate JS files and loaded with the defer <script> attribute. So they will all load asynchronously and run in the correct order after.

@tsteur let me know what you think. I'm not sure if there will need to be some performance testing on cloud just to see if it's worth it.

Changes:

  • Create PluginUmdAssetFetcher.php to group assets into chunks. Used by AssetManager.
  • Modify compute command to output size of chunks as well.
  • Add two undocumented INI config to control chunking: [General] assets_umd_load_individually, [General] assets_umd_chunk_count

Review

@tsteur
Copy link
Member

tsteur commented Feb 9, 2022

👍 I guess it'll be worth it for plugins like TagManager etc where the files are only needed in specific screens. It be worth giving this a try and we can always adjust if needed 👍 @sgiehl maybe you can have a look at this?

@diosmosis
Copy link
Member Author

@tsteur note this still loads all javascript beforehand, it just does it in N simultaneous ajax requests rather than one big request. It doesn't load the files right before they are needed, that's a bit harder to do.

@tsteur
Copy link
Member

tsteur commented Feb 9, 2022

got it 👍

One thing we will need to test once this is merged and a beta is out that it also works well with Matomo for WordPress and plugins. Or maybe we can also test it as part of this PR. It would require a non-core plugin though and we would need to define:

To locate plugins from a custom directory by setting an environment variable MATOMO_PLUGIN_DIRS or a $GLOBALS['MATOMO_PLUGIN_DIRS'] variable in $MATOMO_ROOT/bootstrap.php.

Like we have say also plugins in $matomoDir/my-custom-plugins/ (eg ``$matomoDir/my-custom-plugins/my-custom-plugin`) and then it would also need to load the file correctly from that directory.

Some people use this to have non-core plugins with different file permissions in a different directory and Matomo for WordPress also uses it. I'm saying this as the JS files will need to be loaded from a different path as they won't be in the /plugins/ directory. Not sure it's relevant or not.

@diosmosis
Copy link
Member Author

Some people use this to have non-core plugins with different file permissions in a different directory and Matomo for WordPress also uses it. I'm saying this as the JS files will need to be loaded from a different path as they won't be in the /plugins/ directory. Not sure it's relevant or not.

Yes, that's relevant, currently /plugins/ is hardcoded. I'll change the PR to use Plugin\Manager::getPluginsDirectories(), hopefully that's enough.

@diosmosis diosmosis added this to the 4.8.0 milestone Feb 10, 2022
@diosmosis diosmosis added the Needs Review PRs that need a code review label Feb 10, 2022
@diosmosis diosmosis changed the title [Vue] PoC for chunking UMD JavaScript into a set of asynchronously loaded files that [Vue] Chunk UMD JavaScript into a set of asynchronously loaded files Feb 10, 2022
@github-actions
Copy link
Contributor

This issue is in "needs review" but there has been no activity for 7 days. ping @matomo-org/core-reviewers

@github-actions github-actions bot added the Stale The label used by the Close Stale Issues action label Feb 18, 2022
@diosmosis diosmosis added Do not close PRs with this label won't be marked as stale by the Close Stale Issues action and removed Stale The label used by the Close Stale Issues action labels Feb 18, 2022
Copy link
Contributor

@peterhashair peterhashair left a comment

Choose a reason for hiding this comment

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

Looks good to me, Test Couple plugins, works as expected, it reduce the head script size by a lot. Worse case, use this config will reset to original disable_merged_assets = 1. Ping @sgiehl

@sgiehl
Copy link
Member

sgiehl commented Feb 22, 2022

@diosmosis It seems the cachebuster is currently not appended to the additional js requests. Guess this part needs to be adjusted so the additional defer doesn't prevent adding the cachebuster:

matomo/core/View.php

Lines 360 to 378 in 4764df9

$tagJs = 'cb=' . $cacheBuster->piwikVersionBasedCacheBuster();
$tagCss = 'cb=' . $cssCacheBusterId;
$pattern = array(
'~<script type=[\'"]text/javascript[\'"] src=[\'"]([^\'"]+)[\'"]>~',
'~<script src=[\'"]([^\'"]+)[\'"] type=[\'"]text/javascript[\'"]>~',
'~<link rel=[\'"]stylesheet[\'"] type=[\'"]text/css[\'"] href=[\'"]([^\'"]+)[\'"] ?/?>~',
// removes the double ?cb= tag
'~(src|href)=\"index.php\?module=([A-Za-z0-9_]+)&action=([A-Za-z0-9_]+)\?cb=~',
);
$replace = array(
'<script type="text/javascript" src="$1?' . $tagJs . '">',
'<script type="text/javascript" src="$1?' . $tagJs . '">',
'<link rel="stylesheet" type="text/css" href="$1?' . $tagCss . '" />',
'$1="index.php?module=$2&amp;action=$3&amp;cb=',
);
return preg_replace($pattern, $replace, $output);

@diosmosis
Copy link
Member Author

@sgiehl updated

@diosmosis
Copy link
Member Author

Oh looks like tests aren't passing, not sure why disable_merged_assets is enabled for me no matter what... looking into it, no need to review right now.

@diosmosis
Copy link
Member Author

@sgiehl ok should be good for another review

Copy link
Member

@sgiehl sgiehl left a comment

Choose a reason for hiding this comment

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

Looks good to me now. We could though think about adding some tests for the new asset loading stuff.
@diosmosis can you think of any potential problem that might cause? Just wondering if we shall merge that now, before an upcoming release or better wait after it.

@sgiehl sgiehl removed the Needs Review PRs that need a code review label Feb 23, 2022
@diosmosis
Copy link
Member Author

Looks good to me now. We could though think about adding some tests for the new asset loading stuff.

Sure I'll add some tests.

@diosmosis can you think of any potential problem that might cause? Just wondering if we shall merge that now, before an upcoming release or better wait after it.

Can't think of any, but sure it can wait. It'll take time to add some tests anyway.

@justinvelluppillai justinvelluppillai modified the milestones: 4.8.0, 4.9.0 Mar 1, 2022
@diosmosis
Copy link
Member Author

@sgiehl added tests and fixed some issues. There's one image that needs to be updated, I'll update that before merging. Pinging in case you want to review the rest of the code first.

Copy link
Member

@sgiehl sgiehl left a comment

Choose a reason for hiding this comment

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

LGTM

@diosmosis diosmosis merged commit b774954 into 4.x-dev Mar 4, 2022
@diosmosis diosmosis deleted the vue-asset-chunking branch March 4, 2022 16:35
@justinvelluppillai justinvelluppillai added the not-in-changelog For issues or pull requests that should not be included in our release changelog on matomo.org. label Apr 11, 2022
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Do not close PRs with this label won't be marked as stale by the Close Stale Issues action not-in-changelog For issues or pull requests that should not be included in our release changelog on matomo.org.
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

5 participants