Update: The talk is now up on YouTube.
If you don’t want to read and just want to look at the stuff I link to in this post and in the talk, have at it. There are some great resources.
- Magento’s new app framework
- Intro to Content Security Policy
- Cross Site Scripting
- CSP documentation
- Pagespeed Insights on render blocking JS
- How to load scripts asynchronously
- AMD introduction
- AMD specification
- Magento code to load JS
- RequireJS entry point
- HTTP2 browser support
The Actual Post
But on top of that maturing process, there are three big changes:
There is a really cool app framework that you can use to get data from Magento’s APIs. I figure this is important and worth learning, but I’m not going to mention it further in this post, because it’s a big big topic. The framework is based on KnockoutJS, though, and your time would be well spent learning about it.
Inline Scripts have been banished. This allows us to implement Content Security Policy across our sites, which is the next generation of online security.
- Scripts no longer block the rendering of the page, so your users can start spending money without having to wait for your stupid jQuery code.
To illustrate this, we’re going to port the following code:
The most heinous part of our original piece of art is that its using an inline <script /> tag to get data from the server to the page. This is bad for lots of reasons like mixing behaviour and knowledge, but it’s especially bad because it blocks us from implementing Content Security Policy.
Content Security Policy is the next step in web security. Under the current model, the browser will run any code that gets into the page. This seems reasonable on the outside, but it’s not. Because it’s surprisingly, unnervingly easy to get code into a webpage. The act of getting code into a webpage for nefarious purposes is called Cross Site Scripting (XSS). Owasp have a pretty good set of references on XSS, and how to mitigate it.
And rather than take that risk (which would invalidate the entire point of CSP), the standards body chose to outlaw inline scripts. So detach yourself from them, because security won’t wait around for you.
This is how Magento are expecting us to load data into our templates. How this gets turned into actual running code is the other side of this coin.
Google highlight this as one of their biggest performance indicators inside pagespeed. So if you think I’m having you on, you should trust them.
It’s pretty well documented, but the short story is that you get a function to define modules. You say what your module does, and what it needs to do it, and put it in a file. RequireJS handles the rest. Let’s take a look:
Note that you can use requirejs-config.js to set a human readable name that maps to that URL. This is generally considered best practice, since it makes it easier for somebody to override your component with something else in a customisation. To read more about how to configure this, you’ll want to read Magento’s documentation, and then RequireJS' documentation, and then look at this example.
In AMD, the function you pass as an argument is run, and its return value becomes the module. In this case (and in lots of cases), we are returning a function as the module value.
Many people have highlighted an issue with this, though. In Magento 1, you can switch a configuration flag to combine all those millions of scripts we put in through the XML. I dislike this feature for a number of reasons, but you don’t need this in Magento 2. First of all, while it’s loading these scripts, your page is visible. For the few seconds that your navigation might not work, your customer is probably still getting their bearings, trying to work out why your page loaded so damn quickly. Tehe other reason you don’t need to worry is that you can make it super fast by turning on HTTP2. If the performance impact of many requests bothers you, I implore you to enable HTTP2 on your stores. It’s well supported, and designed to handle exactly this kind of use case.