Webpack Stenciljs PWA - ionic-framework

I need to reduce the size of a Stenciljs PWA for a project using Webpack. The Stenciljs Compiler creates several JS files and embeds them as nomodule script tag in the index.html file.
Now my questions:
Is there a way to combine all scripts (e.g. with gulp)?
Is there a way to get Stenciljs not to include the JS files using nomodule script tag? This is not resolved by webpack.

Stencil already does its best to generate optimized bundles that are minified in production builds. I doubt you'll be able to minify this much further with Webpack. Don't be fooled by checking the size of the output folder (www if it's an app), as it doesn't represent the size of what's actually loaded when you open the app in the browser.
There's no way to combine all scripts into one by simply concatenating the scripts, as that's against the nature of ES modules (one file per module). You could try the dist-custom-elements-bundle output target (https://stenciljs.com/docs/custom-elements), which allows you to create only one bundle that includes all your components. However that is a dist-type output target, so you'll have to figure out how to consume that for your app.
Stencil doesn't embed any nomodule script tags in your index.html. Maybe you meant rel="modulepreload"?
In addition, all the metadata collected by the compiler and the dependency graph generated by rollup can be used to automatically create “modulepreload” links, reducing the amount of network round-trips required to download all the JS in the critical path to zero. This drastically reduces the Time-To-Interactive of apps built with Stencil.
(from https://ionicframework.com/blog/announcing-stencil-one-beta/)
The only nomodule-type script that would be in your src/index.html is the one with the entry point for your app for browsers that don't support type="module". It's added by default, see src/index.html#L22. This script will be ignored (i. e. not loaded) by browsers that already support ES modules. However it's up to you to remove it, your app just won't work in any browsers that don't support ES modules then.
If you want to drop support for IE11 and old Edge (before v18), you can use the extras option in your stencil.config.ts, which might reduce the size further:
export const config: Config = {
buildEs5: false,
extras: {
dynamicImportShim: false,
cssVarsShim: false,
shadowDomShim: false,
scriptDataOpts: false,
safari10: false
}
}
(see https://stenciljs.com/docs/config-extras)

Related

Is there any way to split data files into smaller chunks in Unity WebGL builds?

I am limited to the size of web applications I can build by the "Build\application.data" file.
I.e if its over a certain size I cannot upload it certain hosts, github, etc.
Ideally I would like to split the application into multiple data files under a certain size, while the application is still executable.
How would this be possible? Is this something I can do from Unity build configuration?
Can I do it after the build is done?
Can I split the file into chunks by archiving it with zero compression, and somehow still execute it from the browser? There is a file called Build.Loader.js, is it something that can be edited for this purpose?
This is for the purposes of using the application after it has been uploaded, not sharing it, I do not want to compress it into separate archives, or use gitlfs, I've tested this and the application does not work from the browser with github and gitlfs.
Thanks
Unity has 2 technologies for split data file:
Asset bundle
An AssetBundle is an archive file that contains platform-specific
non-code Assets (such as Models, Textures, Prefabs, Audio clips, and
even entire Scenes) that Unity can load at run time
Addressbles
The Addressable Asset System allows the developer to ask for an asset
via its address. Once an asset (e.g. a prefab) is marked
"addressable", it generates an address which can be called from
anywhere. Wherever the asset resides (local or remote), the system
will locate it and its dependencies, then return it.
Both technologies create separate files that you can host on a server and download as needed. Addressable is a newer technology that Unity team recommends.
Probably the total size of the bundle will grow, but user will be able to download only the necessary assets and the amount of data for the user may decrease
If you do not use Unity solutions, you can divide data file into parts. But on the client side (javascript) you will need to download all the parts, connect them and pass to Unity loader. You probably won't be able to use the browser's built-in gzip or brotli (not sure). It seems to be quite difficult.

Multi-page Airconsole controller?

I'm just starting to create a controller for use with Airconsole. I'd like it to be somewhat complicated and will be using Angular to create different pages.
In Unity, I can drag in a controller.html file. However, I've been getting resource not found errors when I try to access say controller.js or controller.css. How can I upload multliple files to the Airconsole host? Is there a general pattern used by other games?
So far I'm considering
hosting my app separately and just redirecting to my separate web page. This seems to give errors in the emulator though.
Compiling the entire app into just one HTML file.. Not sure how to get these entirely into one file. When I run ng build I get a smaller dist compiled file, but it still consists of several smaller files. Will try dragging that into Unity and trying again. But dragging the entire Angular project inside Unity felt like a really bad idea..
Link to files hosted on separate pages but still have the uploaded HTML file do something.. But not sure how much I need to do here vs how much I can move to other files that I host.
You can create your controller using controller.html with Angular (1?!), have different pages (e.g. via ng-include and the angular routing module) and upload everything to AirConsole (developers).
By using ng-include you can have multiple .html views you dynamically load into the controller.html.
I once wrote an example app for AirConsole and Angular:
https://github.com/francois-n-dream/airconsole-angular-phaser
Just think of it as if you would make a (mobile) website which in addition uses the AirConsole API for device communication.
My basic "how to include other files" question was answered well by another question: How to include js and css.
For the more generic question of working with Angular, I still haven't quite figured it out. But what I'm doing at the moment:
I have an Angular project outside of Unity. I run ng build to compile everything into a folder dist. Then two options work:
Deploy the dist folder to static file hosting and change index.html's relative links to point to the separately hosted files with <base href="https://cloudfilehosting/airconsole-host/">
OR
Copy the dist folder into Unity's Assets/WebGLTemplates/AirConsole folder.

Wicket 6 and on the fly javascript compression

I know that wicket will take min files when running in deployment mode. But I would like to have possibility to bundle multiple javascript files into one, so that the generated page can load whole javascript from single url. This should happen only is deployment mode, development should still deliver pages containing multiple javascript files.
You need to use "resource bundles". See http://wicket.apache.org/guide/guide/resources.html#resources_6.
You can wrap the registrations with "if (usesDeploymentMode()) {...}"

Unity web open custom html after build

I made a custom html file for my Unity web project. Though after building my project, it opens the default pre-made one. Is there a way to make Unity open my own html file instead of the default one?
You're looking for the Web Player Templates manual page.
In your Assets folder, create a folder named WebPlayerTemplates, and put your template in there. You'll need an HTML file. To help make this slightly easier, Unity will look in that HTML for certain tokens that it can replace with data from the project.
For example, one such tag is %UNITY_WEB_PATH%, which will be replaced with the path to your built project file.
Some tags include:
UNITY_WEB_NAME Name of the webplayer.
UNITY_WIDTH UNITY_HEIGHT Onscreen width and height of the player in
pixels.
UNITY_WEB_PATH Local path to the webplayer file.
UNITY_UNITYOBJECT_URL In the usual case where the page will download
UnityObject2.js from the Unity’s website (ie, the Offline Deployment
option is disabled), this tag will provide the download URL.
UNITY_UNITYOBJECT_DEPENDENCIES The UnityObject2.js have dependencies
and this tag will be replaced with the needed dependencies for it to
work properly.
In every deployment I've seen, the WebPlayer plugin is is launched via JavaScript, by instantiating a UnityObject2 and calling its initPlugin method:
var u = new UnityObject2();
u.initPlugin(jQuery("#unityPlayer")[0], "Example.unity3d");
The above assumes that you have a div with id #unityPlayer, and that Example.unity3d is a valid path to your Unity build file.
In practice, though, I recommend working from Unity's generated HTML files; they include some failsafes for cases where the WebPlayer plugin isn't installed or fails to load. The manual page linked above also has HTML source examples which include some of those special tags.
UnityObject2 does have some advanced features, which are also documented in the manual. If your game needs to communicate with the outer web page, that is also possible.

Deploy GWT Application as Single JavaScript File

The compiled JavaScript output of a GWT application is divided into various files, for instance
*.cache.html
*.gwt.rpc
hosted.html
*.nocache.js
...
I know this is done with the purpose of minimizing the size of the JavaScript, which has to be downloaded by users. For instance so that a Firefox user does not have to load the JavaScript specifically compiled for IE6.
However, especially for small GWT applications it might often be faster to download a single file of say 500kb rather than make two sequential requests first for the 5kb *.nocache.js script and then for the rest of the app (cache.html files, etc.).
This leads me to the question: Is there any framework or procedure to bundle the output of the GWT compiler into a single JavaScript file?
First, you can merge all permutations in a single file by using so-called "soft permutations".
Then, you can inline your *.nocache.js into the HTML host page (e.g. using a JSP's #include directive) to cut one additional request (you might have to add a <meta name=gwt:property content='baseUrl=myapp'> where myapp is the subfolder where the .nocache. files are located).
AFAIK that's what Google are doing for their GWT apps.
Alternatively, you can run the permutation selection on the server-side if you can totally replace the selection script (*.nocache.js) with server-side content negotiation (based on User-Agent and Accept-Language request headers for instance) that can directly generates a <script> tag for the appropriate *.cache.js file (provided you use the xsiframe linker).
AFAIK, Google use all these techniques for their GWT apps (such as Google Groups). For a small app, though, I'm not sure it's worth the effort…
Also, the last two techniques work best when your HTML host page is already dynamic and therefore already non-cacheable; otherwise you're mostly moving the problem, not solving it.
I wonder whether the sso linker can be used when you collapse all properties and soft-permutations down to a single hard permutation.
Yes, but it's maybe not something you want. See this answer: https://stackoverflow.com/a/4453716/66416 to this stackoverflow question: Merge GWT generated files.
I found another way to accomplish this: Writing a custom Linker for GWT. Two examples for linkers which compile into a single JavaScript file are:
GwtNodeLinker.java from Gwt Node project
ServerSingleScriptLinker.java from Env.js project