Maybe I'm paranoid. I always like to have my code as slim as possible. I always target my websites to be under 1.5 MB (All images compressed and resized as appropriate(. I started working with Polymer the month before thinking that I could shave off those 150 KBs from Bootstrap and 90 KB from jQuery, and have a relatively lightweight site.
I've just vulcanized my elements.html file and I am horrified. The beast is 947KB without images, just bare HTML and JS. I have around 40 custom elements + Couple of the Elements catalog (and I'm not even close to creating new elements). (GZip is 307.40 KB out of 947KB) (Using ASP.NET MVC5 and .NET 4.6).
With a regular 3G connection, it takes about 5.15 seconds to load in Chrome 52 (which is awful). The Polymer Shop demo loads beautifully fast (<3 seconds from cold cache in regular 3G)
First of all, is this acceptable? I'm trying to hit before the 3 second mark (or get to it as close as possible).
Also, there are many JavaScript files that are being loaded part of Vulcanize which I don't need.
I've seen this Gist: Vulcanize and Polymer auto Lazy Loading but I don't know what to do with it.
These are the imports of my elements.html file:
<link rel="import" href="../bower_components/app-route/app-route.html">
<link rel="import" href="../bower_components/app-route/app-location.html">
<link rel="import" href="../bower_components/app-layout/app-drawer-layout/app-drawer-layout.html">
<link rel="import" href="../bower_components/app-layout/app-drawer/app-drawer.html">
<link rel="import" href="./pgarena-drawer/pgarena-drawer.html">
<link rel="import" href="./pgarena-navbar/pgarena-navbar.html">
<link rel="import" href="./pgarena-auth/pgarena-oauth/pgarena-oauth.html">
<link rel="import" href="./routes/pgarena-app.html">
Then all my custom elements (pgarena) have more polymer components built into it.
I've tried several combinations (Only with my elements) and (Only with the Polymer elements shown) and I've had varied results (as expected)
I don't know what to do... Before resorting to a hacky stuff... Any recommendations?
Ok, people, bear with me. This is going to be a long answer. It can become a little bit hairy. First of all, this was a Polymer 1.x solution. I don't know what of this has changed for version 2.0
TL;DR: We get the URLs of the .HTML and use JavaScript to create the
link
attribute (HTML import) to load the element. We check with Polymer usingPolymer.isInstance(element)
to see if the object has been set or not.Here's the code:
For this to work, I was using
iron-pages
, and custom JavaScript.We have our app, as the following:
Note*: The following code I had it in the same file, you can separate it as you wish.
Let's get some things first:
[[]]
to one-way data bind.Note, that the elements are not included in the URL, because we're going to lazy load them.
Let's go to the JavaScript portion of this element:
The code is simple in here. We define our element, and we listen to the iron select event. This signals us that iron-page has been selected. We lazy load the element if it's not there. The magic behind this, is in the custom
LazyLoad
JavaScript, which is below.The first thing we do is to define the URLs relative to the document I have. I do this by defining a json with a key whose name is the
title
attribute of theiron-pages
and the value with the relative URL to this document (the pgarena-app).What I mean, is that in the case I want to load
pgarena-tournament-app
and mypgarena-app
(my main entry point to the application) is inwww/polymer/pgarena-app.html
and my pgarena-tournament-app is inwww/polymer/routes/tournament/pgarena-tournament-app.html
, since this is relative my JSON will be:var PGArena = PGArena || {}; PGArena.LazyLoad = { "tournament" : "routes/tournament/pgarena-tournament-app.html", };
Note PGArena.LazyLoad can be anything, this is a global variable I defined with the PGArena namespace.
Then, we see that the code LazyLoad is called:
What I do in here is to check if the Element that I want to lazy load has been referenced in the JSON I defined (PGarena.LazyLoad). If it's not in there, then what I do is that I log that message. If it's there, and it has not loaded, then I Asynchronously load it by creating the HTML import and appending it to the head:
Please notice (I don't know if they've fixed this). There's a polyfill for HTML imports for Firefox, and Edge, and Safari(I believe). The polyfill uses XHR (AJAX) for loading the imports!!! I mention this because at the beginning I tried to intercept the HTML Imports and in Google Chrome it didn't work.
Let me know if you need anything else. As you can see, I tried to use the spinner, but I didn't get it to work. Hope this helps!