-
Notifications
You must be signed in to change notification settings - Fork 1.6k
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
Improving design section JS binding performance #15431
Conversation
…rame for running JS in the frontend, to improve performance.
…ontend-js-performance
QA Wolf here! As you write new code it's important that your test coverage is keeping up. |
1 similar comment
QA Wolf here! As you write new code it's important that your test coverage is keeping up. |
…/budibase into feature/frontend-js-performance
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
🚀 I love that reusing the iframe had such a big impact. Definitely opens the doors for introducing bindings into grids for things like custom columns, and also hopefully lets me simplify some client library logic, which was extremely heavily optimised (at the cost of complexity) to minimize binding evaluation at all costs.
Description
This PR introduces vm-browserify as a direct dependency, rather than receiving this as part of the string-templates build process and a browser polyfill for the
vm
Node library.I have forked the library to add an optimisation to re-use the iframe when processing JS - previously each JS binding on the page would add an iframe, run the JS and then destroy said iframe - from our testing this has some particularly large performance costs.
The difference can be seen here, when rendering a page with a repeater block, containing a headline with a
return 1
JS binding - this is for 1000 components.Before the library update:
![image](https://private-user-images.githubusercontent.com/4407001/406094287-38a570ff-52c5-454a-968c-7f91e275b323.png?jwt=eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpc3MiOiJnaXRodWIuY29tIiwiYXVkIjoicmF3LmdpdGh1YnVzZXJjb250ZW50LmNvbSIsImtleSI6ImtleTUiLCJleHAiOjE3MzkxMDcwMzMsIm5iZiI6MTczOTEwNjczMywicGF0aCI6Ii80NDA3MDAxLzQwNjA5NDI4Ny0zOGE1NzBmZi01MmM1LTQ1NGEtOTY4Yy03ZjkxZTI3NWIzMjMucG5nP1gtQW16LUFsZ29yaXRobT1BV1M0LUhNQUMtU0hBMjU2JlgtQW16LUNyZWRlbnRpYWw9QUtJQVZDT0RZTFNBNTNQUUs0WkElMkYyMDI1MDIwOSUyRnVzLWVhc3QtMSUyRnMzJTJGYXdzNF9yZXF1ZXN0JlgtQW16LURhdGU9MjAyNTAyMDlUMTMxMjEzWiZYLUFtei1FeHBpcmVzPTMwMCZYLUFtei1TaWduYXR1cmU9MTUzNGEyZTkxODUyNzczODNkOWNkZTJkNGRkMDY1YWUwNjRlOGQ4Zjk0ZGFkYTZlOWMyNTEwNzBjNGQ5OGQzMCZYLUFtei1TaWduZWRIZWFkZXJzPWhvc3QifQ.CAiOWBEn_rdnQnLwRtiKA2mPRPsbJHdq-Sn0RHYRHcc)
After the library update:
![image](https://private-user-images.githubusercontent.com/4407001/406094223-c2240bce-8e73-410d-91f4-a156b145f3a2.png?jwt=eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpc3MiOiJnaXRodWIuY29tIiwiYXVkIjoicmF3LmdpdGh1YnVzZXJjb250ZW50LmNvbSIsImtleSI6ImtleTUiLCJleHAiOjE3MzkxMDcwMzMsIm5iZiI6MTczOTEwNjczMywicGF0aCI6Ii80NDA3MDAxLzQwNjA5NDIyMy1jMjI0MGJjZS04ZTczLTQxMGQtOTFmNC1hMTU2YjE0NWYzYTIucG5nP1gtQW16LUFsZ29yaXRobT1BV1M0LUhNQUMtU0hBMjU2JlgtQW16LUNyZWRlbnRpYWw9QUtJQVZDT0RZTFNBNTNQUUs0WkElMkYyMDI1MDIwOSUyRnVzLWVhc3QtMSUyRnMzJTJGYXdzNF9yZXF1ZXN0JlgtQW16LURhdGU9MjAyNTAyMDlUMTMxMjEzWiZYLUFtei1FeHBpcmVzPTMwMCZYLUFtei1TaWduYXR1cmU9ZGUzNWJkZjlhZGFhYTUzZGE3ZDRkMDBhMjY3NWM4Y2NhNjk2OGE0OWI4MzUzZDlkNjczMTIzMjNlOGZmOWE2NSZYLUFtei1TaWduZWRIZWFkZXJzPWhvc3QifQ.I__3TmFZl1pq68726e4GfFHgFMOKO9Uwuhaw1vyo8Kw)
Here we can see the total time to prepare the data for rendering has gone from 32.8 seconds to 1.4 seconds - a massive improvement in performance.
We have also introduced support for the iframe sandbox capabilities that are now generally supported by browsers (not an option when the library was originally built) - information can be found here: https://developer.mozilla.org/en-US/docs/Web/HTML/Element/iframe
This restricts the JS binding from performing certain actions like opening a popover - we have limited it to
allow-scripts
andallow-same-origin
sandboxing behaviours.The re-use of the iframe did raise a question of global state management, however after much testing it was found that there is little difference, since the parent body is always accessible in the JS via
window.parent
- this means there has always been the potential of global state.