Why BabylonJS is so heavy for syntax checker tools?

Sorry guys, I don’t know how to title this question properly. I have a problem with a syntax checking. It lasts too long for every changing in my .ts files. As for code editors I’ve checked that in: nvim, vscode.
Recently I’ve coded using Phaser3 engine - there syntax checking works immediately, blazingly fast. Yeah I know Phaser3’s size is 4 times smaller: 1mb for Phaser3 vs 4mb for BJS.

I’ve thought the problem with my PC. Yeah I think it definetely could work faster if my PC was much faster than it is, sure. But: the Playgrounds are aslo check syntax not immediately but using some time gap (about 4-7 seconds for simple JS instructions).

I’ve had some success after migrating my projects from:
import * as BABYLON from "babylonjs";
to:
import { Engine, Scene, ...... } from "babylonjs"

I don’t know if this was the thing that my syntax checker now works faster but I think it’s definitely helped to work faster.
Do you face any problems with slow syntax checking when using BabylonJS?

1 Like

Hey @Rata_Blanca,

I think the PC is one think but the size of a project and the toolset is another.
I have pretty small Babylon project, my IDE is VSCode and everything works very fast.
Are you doing only syntax checking or some linting too?
Do you feel like your PC is under pressure? Maybe some other applications are slowing things down.
Can you share you code? Maybe you have some strange things in your tsconfig file :wink:

You could try to move to our ES6 packages allowing tree shaking and preventing your tooling to parse everything

3 Likes

That ^^^^^^^

es modules are lighter, better, faster, simpler to parse…

4 Likes

omg… that’s blazingly fast now! I have no delay before showing hints anymore! That’s a huge difference!

@sebavan @RaananW Thanks for the advice!

BTW Is there a difference in terms of performance to use:

import {
	Engine, Scene, FreeCamera, Mesh, DirectionalLight, HemisphericLight
} from "@babylonjs/core";

vs:

import { FreeCamera } from '@babylonjs/core/Cameras/freeCamera';
import { Engine } from '@babylonjs/core/Engines/engine';
import { HemisphericLight } from '@babylonjs/core/Lights/hemisphericLight';
import { Vector3 } from '@babylonjs/core/Maths/math.vector';
import { CreateGround } from '@babylonjs/core/Meshes/Builders/groundBuilder';
import { CreateSphere } from '@babylonjs/core/Meshes/Builders/sphereBuilder';
import { Scene } from '@babylonjs/core/scene';

is it better to use the second case of declarations or there’s no big difference?

1 Like

Second is better :blush:
It enables tree shaking (was shading! ;-))

1 Like

Thanks, got it!

But how to set webpack config to not to include the whole BJS code into bundle? For storing BJS code separately and include it with “babylon.min.js” on my webpage.
I found only one way to do it:

externals: [
	{ "@babylonjs/core": "BABYLON" },

	{ "@babylonjs/core/Engines/engine": "BABYLON" },
	{ "@babylonjs/core/Engines/constants": "BABYLON" },
	{ "@babylonjs/core/Meshes/mesh": "BABYLON" },
	{ "@babylonjs/core/Meshes/meshBuilder": "BABYLON" },
	{ "@babylonjs/core/Materials/standardMaterial": "BABYLON" },
	{ "@babylonjs/core/Cameras/freeCamera": "BABYLON" },
	{ "@babylonjs/core/Lights/hemisphericLight": "BABYLON" },
	{ "@babylonjs/core/Lights/directionalLight": "BABYLON" },
	{ "@babylonjs/core/Maths/math.vector": "BABYLON" },
	{ "@babylonjs/core/Maths/math.scalar": "BABYLON" },
	{ "@babylonjs/core/Maths/math.vector": "BABYLON" },
	{ "@babylonjs/core/Maths/math": "BABYLON" },
	{ "@babylonjs/core/Maths/math.color": "BABYLON" },
	{ "@babylonjs/core/Meshes/Builders/groundBuilder": "BABYLON" },
	{ "@babylonjs/core/scene": "BABYLON" },
	{ "@babylonjs/core/Audio/sound": "BABYLON" },
	{ "@babylonjs/core/Materials/Textures/texture": "BABYLON" },
]

Not the best solution I think but it works. Here you need to list all the imports. Is there a way better? :grinning:

Why do you need that? You don’t need the global namespace, just import what you need and use it directly.

Well maybe I understand something wrong. I use BJS on my webpage like this:

<script src="js/babylon.min.js"></script>
<script src="js/my_app_bundle.js"></script>

my_app_bundle.js is just usual JS file packed with WebPack, so I get something like this:

const scene = new BABYLON.Scene(engine);
const camera = new BABYLON.ArcRotateCamera("camera", -Math.PI / 2, Math.PI / 2.5, 3, new BABYLON.Vector3(0, 0, 0), scene);
camera.attachControl(canvas, true);
const light = new BABYLON.HemisphericLight("light", new BABYLON.Vector3(0, 1, 0), scene);
const box = BABYLON.MeshBuilder.CreateBox("box", {}, scene);

that’s why I need that global namespace: BABYLON.

So for the developing I use TS and those imports and for the production code I use WebPack to not to include the whole BJS code into my bundle as I use BJS as a separate package.

Like it shown in the First Web App documentation. There is also that global namespace BABYLON.

Do I make something wrong? :grinning:

you are mixing npm packages and normal script tags in your app. If you use an npm package you ned to work with imports and import the classes you need (just like you did in your code). Then you don’t need the script tag and don’t need the global namespace settings.
you are already doing it, and i assume your setup is well prepared for that. meaning - remove the externals, remove the global script, and webpack should take care of the rest.

1 Like

Well, I tried to do it. If I remove my external then my js-bundle size has ~30mb. Seems like it packs BJS code into one big bundle js-file. I stored it separately for sharing the same BJS code (babylon.min.js) between a few my apps for faster loading. As I think browser can cache babylon.min.js file and load it faster next time.

Sorry but I didn’t get it. If I will not use script tags then how can I run my web app without it?

I would recommend you to read about how webpack works (out of our scope here, sadly), or check one of the templates provided by our community. I built this one - RaananW/babylonjs-webpack-es6: Babylon.js basic scene with typescript, webpack, es6 modules, editorconfig, eslint, hot loading and more. Will even make coffee if you ask nicely. (github.com) , but there are others.

1 Like

@Rata_Blanca it all depends on your case and your needs, but…

  1. You do need at least one script tag in your HTML file - you need to load the JS somehow. So it can be just
    <script src="js/my_app_bundle.js"></script>
  2. ~30mb of js file is quite large. You’re talking about developer version (uncompressed)?
    I’m having ~11mb of my uncompressed bundle file. (but I’m using Parcel - not Webpack)
    What do you have in that bundle?
  3. In general with ES6 you shouldn’t need to use global namespace, you import the babylon and you use that in your source code like you wrote before, eg.
    import { Scene } from '@babylonjs/core/scene';
    The bundling tool should take care of providing the required dependencies in the scope.
  4. As for the browser caching - browser will cache your bundled file too, so it shouldn’t matter much if you have it in two files or in one (there is difference of course, but let’s leave it for now)

Do you use Webpack in production mode? It will minify your bundle, and thanks to the tree-shaking your bundle can be smaller than BJS + YOUR_CODE because you probably don’t need everything from the babylon.min.js.
6.

I stored it separately for sharing the same BJS code (babylon.min.js) between a few my apps for faster loading.

It depends on your architecture, but if you have few applications and you use one Webpack configuration you can share the code between those applications. Not only BJS code, but some utils or whatever you want to

So you can have like one Webpack configuration with few entries and with that shared chunk which will be cached by the browser and reused in every of your app.

If you need some more explanation or any help with any of that you can DM me :slight_smile:

1 Like

It is not summer anymore :slight_smile: :slight_smile: :slight_smile:

don’t we have a tree shader?