Polymer HTML Import caching - html

I want to make sure that the browser gets the latest version of my custom elements via HMLT import. Right now, I am attaching a version query string:
e.g.
<link rel="import" href="/dist/elements/my-element.html?v=12345">
This is a common practice for JS and CSS files, and I am wondering if this is valid approach for HTML Imports as well?

Yes, the same principles apply.
As an example, take a look at the source of http://www.polymer-project.org/. At the time of this writing, it contains <link rel="import" href="http://www.polymer-project.org/elements/homepage_elements.vulcanized.html?20140828">.
P.S. Described query parameter is not used at http://www.polymer-project.org/ anymore.

Related

Defining Polymer web components without importing them

Is there a way to define Polymer web components directly in the HTML file for the page where they're used instead of importing them through link tags?
This seems like it would be faster vs having to request a page and then send requests for the web component html files as well. So far all the guides I've seen only reference importing via <link rel="import" href="/my_component.html" />.
You can use Polymer Bundler to reduce the number of network requests concatenating web components and dependencies in one file. You can find more info here.
As suggested in the other answer, it seems like a better approach to worry more about having a clear structure of your files/elements while you're developing, and to let a build script worry about stuff like that.
But since a bundler would basically do the same thing, define all the elements in a file, it's obviously possible. So only to answer the initial question, you can see a sample here.
So you just have to use multiple dom-module tags like:
<dom-module id="my-element">
...
</dom-module>
<dom-module id="my-inner-element">
...
</dom-module>
And multiple calls to customElements.define:
customElements.define(MyElement.is, MyElement);
customElements.define(MyInnerElement.is, MyInnerElement);
But I would most certainly recommend against writing your entire application in a single file.

How to prefetch correctly a CSS file?

I use two CSS files, one is a little one for my home.html with all the important things for this page and there I pre fetch a bigger CSS file that takes care of the internal structure.
It works as I want but when I try to pass the W3C validation it complains with:
Error: A link element with an as attribute must have a rel attribute
that contains the value preload.
<link rel="prefetch alternate stylesheet" href="/css/internal.css" as="style">
Can I get rid correctly of this?

Understanding Render Blocking CSS

I am trying to understand how CSS is evaluated in a specific setting:
Lets assume I have the following content in my <head> tag:
<html><head>
...
<link href="reset.css" type="text/css" rel="stylesheet">
<link href="style.css" type="text/css" rel="stylesheet">
<link href="autocomplete.css" type="text/css" rel="stylesheet">
</head>
<body>
... html ...
<script type="text/javascript" src="/js/script.js"></script>
</body></html>
Now, let's assume reset.css and style.css contain some rules that immediately affect the above the fold content or the the elements in the HTML. However, autocomplete.css only contains class used that are used later by some JavaScript.
Now, let's further assume the browser already downloaded reset.css and style.css but autocomplete.css is still pending.
I am wondering what would happen if the browser would do it encounters the blocking script tag at the end of the page? Obviously, it can render the HTML up to the script tag, but is the execution of the script blocked by the missing autocomplete.css?
Note that the script tag is not a sync.
I've read:
https://developers.google.com/web/fundamentals/performance/critical-rendering-path/analyzing-crp
And there it says that the execution of the JavaScript is blocked until the CSSOM is there.
Now:
1. Will the page start rendering even autocomplete.css has not yet arrived? and,
2. Is the execution of the script.js javascript blocked until the autocomplete.css is there?
Note, I am referring to two different things: rendering and script execution.
All CSS is render blocking. The only exception from this rule would be CSS that your DOM does not yet know about (loaded async, built/loaded on the fly via javascript).
Until your browser didn't resolve (or thinks it resolved) all CSS by building the CSS Object Model, the page won't render and javascript will not be executed. However, resolve does not necessarily mean load. It can mean two things:
load & parse. If it's above 2k lines of code, you're going to notice it when measuring with proper tools. If it's above 10k lines of code, you'll be able to notice it without using any tools. This is regardless if it contains rules concerning elements above the fold or not.
not being able to load/parse (due to network problems or invalid rules) - if an error is returned when CSS is loaded/parsed, it will resolve faster and the resulting differences will be hardly noticeable. If the server does not return an error (and just doesn't respond) - that's going to block your CSSOM from building, your page from loading and your scripts from executing.
Resources:
W3C's CSSOM spec.
MDN's CSSOM resource page
What is CSSOM?
The latest performance recommendations are as follows:
1) Inline all css into the header that the browser needs to render above-the-fold-content. Content which is visible without scrolling.
2) Add all other css to the bottom of the page or better load it asynchronously with something like this: https://github.com/filamentgroup/loadCSS
autocomplete is a css file. As such, it only adds style properties to the classes which are defined in the html. The javascript will still execute correctly, even if the css is missing.
The only thing that might happen is that if the js changes some css styles of the classes which style is defined in autocomplete.css. However even then it's unlikely.

Include HTML into other HTML with web components

What is the right way to insert HTML snippet into main HTML file with HTML5 imports?
The answer to more generic question https://stackoverflow.com/a/22142111/239247 mentions that it is possible to do:
<head>
<link rel="import" href="header.html">
</head>
But this doesn't work. I don't need to insert JS and CSS. Only plain HTML markup inserted at the top of <body>. What is the most simple way to do this and keep HTML readable?
The way I have found to do this is to use ASP.NET and .cshtml files and use razor, as seen here:
http://weblogs.asp.net/scottgu/asp-net-mvc-3-layouts
Beyond simply inserting html into other html this also allows you to have consistent navigation bars, footers, etc. and minimizes your code profile. Also, the use of a layout file gives the site a better feel as only a section of the site refreshes when you click an internal link, as opposed to the whole site.
Found a way to do this from html5rocks, but it is far from being readable. This is the ideal way:
<body>
<include src="header.html"/>
</body>
And this is how it is implemented by HTML5 imports:
<head>
<link rel="import" href="header.html">
</head>
<body>
...
<script>
document.body.appendChild(
document.querySelector('link[rel="import"]')
.import
.querySelector('body')
.cloneNode(true));
</script>
</body>
Notes:
not clear how to choose include if both header.html and footer.html are there
querySelector('body') is required to avoid Uncaught HierarchyRequestError: Failed to execute 'appendChild' on 'Node': Nodes of type '#document' may not be inserted inside nodes of type 'BODY'.
not clear how to insert <body> tag contents without the tag itself
HTML5 import doesn't work in Firefox (38) http://caniuse.com/#feat=imports =/
See: http://www.w3schools.com/angular/angular_includes.asp
It says:
HTML Includes in Future HTML. Including a portion of HTML in HTML is, unfortunately, not (yet) supported by HTML.
So this is on its way, but not here yet.
EDIT: If you are able to, I would use PHP, which is close to the level of cleanliness. The link I inclueded shows multiple ways to do what you are trying to do.
Late edit: if it still counts (for those worried about sourcing): http://caniuse.com/#feat=imports

In the HTML Import polyfill, how do you get the imported content?

Under native HTML Imports, a <link rel="import" href="..."> will, once loaded, have an .import property pointing to the imported document. Under the polyfill, this property does not seem to be available. (See http://jsbin.com/sifem/4/edit, which displays "Got content" in the console under native HTML Imports in Canary, and "No content" under the polyfill.)
How then can one reliably access imported content in code?
When you wrote onload="loaded(this)" you bypassed the ShadowDOMPolyfill, so the reference received in loaded is unwrapped and unsuitable for use.
addEventListener doesn't have this problem:
http://jsbin.com/xokar/1/edit
You could also use wrap, like onload = "loaded(wrap(this))", but it's best to avoid referring to wrap|unwrap if you can.