我是偏执狂吗? "Brutally" Vulcanize 后的大型 Polymer 网站。我能做些什么来修复它?
Am I paranoid? "Brutally" big Polymer website after Vulcanize. What can I do to fix it?
也许我偏执了。我总是喜欢让我的代码尽可能精简。我总是将我的网站目标定在 1.5 MB 以下(所有图像都根据需要压缩和调整大小(。我在一个月前开始使用 Polymer,然后想到我可以从 Bootstrap 中减少 150 KB,从 [=40 中减少 90 KB =],并拥有一个相对轻量级的网站。
我刚刚硫化了我的 elements.html 文件,我吓坏了。野兽是 947KB,没有图像,只有 HTML 和 JS。我有大约 40 个自定义元素 + 几个元素目录(我什至还没有接近创建新元素)。 (GZip 是 947KB 中的 307.40 KB)(使用 ASP.NET MVC5 和 .NET 4.6)。
使用常规 3G 连接,加载 Chrome 52 大约需要 5.15 秒(这太糟糕了)。 Polymer Shop 演示加载速度非常快(在常规 3G 中从冷缓存中加载不到 3 秒)
首先,这是可以接受的吗?我试图在 3 秒标记之前击中(或尽可能接近它)。
此外,有许多 JavaScript 文件正在作为 Vulcanize 的一部分加载,我不需要这些文件。
我看过这个 Gist:Vulcanize and Polymer auto Lazy Loading 但我不知道如何处理它。
这些是我的 elements.html 文件的导入:
<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">
然后我所有的自定义元素 (pgarena) 都内置了更多的聚合物组件。
我尝试了几种组合(仅使用我的元素)和(仅使用显示的聚合物元素)并且我得到了不同的结果(如预期的那样)
我不知道该怎么做...在诉诸 hacky 东西之前...有什么建议吗?
我先从 Vulcanize 默认情况下仅合并文件这一事实开始。例如,您是否添加了删除评论的开关?
此外,您可能希望缩小捆绑的 HTML 和 JS 文件。大多数示例将向您展示 Gulp 设置,但您也可以在 npm 脚本的第二步中缩小硫化文件。
也许这个 post 会有所帮助:https://jongeho.wordpress.com/2015/06/24/endeavors-with-polymer-1-0-vulcanize-crisper-html-minifier/
也就是说,一个富含 Web 组件的应用程序自然会非常大。我也注意到了这一点
好的,各位,请耐心等待。这将是一个很长的答案。它可能会变得有点毛茸茸。首先,这是一个 Polymer 1.x 解决方案。我不知道 2.0 版有什么变化
长话短说:
我们获取 .HTML 的 URL 并使用 JavaScript 创建 link
属性(HTML 导入)以加载元素。我们使用 Polymer.isInstance(element)
检查 Polymer 是否已设置对象。
代码如下:
为此,我使用了 iron-pages
和自定义 JavaScript。
我们有自己的app,如下:
注意*:下面的代码我已经放在同一个文件里了,大家可以随意分开。
<!-- Main Entry point for the application. This will work as the main "Controller"-->
<link rel="import" href="../../bower_components/polymer/polymer.html">
<link rel="import" href="../../bower_components/app-route/app-location.html">
<link rel="import" href="../../bower_components/app-route/app-route.html">
<link rel="import" href="../../bower_components/iron-pages/iron-pages.html">
<dom-module id="pgarena-app">
<template>
<pgarena-action-config></pgarena-action-config>
<app-route route="{{route}}"
pattern="/:page"
data="{{data}}"
tail="{{tail}}">
</app-route>
<iron-pages selected="[[data.page]]" attr-for-selected="title" fallback-selection="404">
<pgarena-home-app title="" route="[[tail]]"></pgarena-home-app>
<pgarena-tournament-app title="tournaments" route="[[tail]]"></pgarena-tournament-app>
<!--<pgarena-clash-app title="clash" route="[[tail]]"></pgarena-clash-app>-->
<pgarena-account-app title="account" route="[[tail]]"><content></content></pgarena-account-app>
<pgarena-teams-app title="teams" route="[[tail]]"></pgarena-teams-app>
<div title="404">
<h1>{{data.page}} could not be found!</h1>
</div>
</iron-pages>
</template>
<script>
(function () {
'use strict';
Polymer({
is: 'pgarena-app',
ready: function () {
/* console.log("Route is ");
console.log(this.data.page);
console.log(this.tail);*/
document.addEventListener('iron-select',
function (event) {
/*
console.log("---------------------");
console.log(event);
console.log("---------------------");*/
var element = getSelectedElement(event);
var tagName = element.tagName.toLowerCase();
LazyLoad(Polymer, element, tagName, event.target);
});
}
});
})();
</script>
让我们先了解一些事情:
- 我的应用名为:"pgarena-app"
- 我不知道这是否已修复,但 app-route 元素存在双向数据绑定问题。这意味着对于铁页,我必须使用双括号
[[]]
来进行单向数据绑定。
- App 路由将来自 url 的信息传递给 iron-pages,以便它可以切换不同的元素。
- 这不是强制性的,我不知道这样做是否正确。我将我的应用程序分成 "views",它们本身就是元素。他们加载 "view" 所需的所有元素。 注意:这 没有 效果,无论在延迟加载中如何。
请注意,这些元素未包含在 URL 中,因为我们将延迟加载它们。
让我们转到此元素的 JavaScript 部分:
<script>
(function () {
'use strict';
Polymer({
is: 'pgarena-app',
ready: function () {
document.addEventListener('iron-select',
function (event) {
var element = getSelectedElement(event);
var tagName = element.tagName.toLowerCase();
LazyLoad(Polymer, element, tagName, event.target);
});
}
});
})();
</script>
这里的代码很简单。我们定义我们的元素,然后我们 监听 iron select 事件。 这向我们表明 iron-page 已经 selected。如果元素不存在,我们将延迟加载该元素。这背后的魔力在于习俗 LazyLoad
JavaScript,如下所示。
<script>
/**
* Defines all the routes of the imports in here
*
* This is how it goes: The Key name is the tag name of the element.
* The value is the relative URL from the elements folder.
*
* You then get the element's tag name and look for it.
*
* DO NOT PUT TRAILING SLASH BEFORE THE URL! Thanks :)
**/
var PGArena = PGArena || {};
PGArena.LazyLoad =
{
"pgarena-home-app": "routes/home/pgarena-home-app.html",
"pgarena-tournament-app": "routes/tournament/pgarena-tournament-app.html",
"pgarena-account-app": "routes/account/pgarena-account-app.html",
"pgarena-clash-app": "routes/clash/pgarena-clash-app.html",
"pgarena-teams-app": "routes/teams/pgarena-teams-app.html",
"pgarena-tournament-index-view": "views/tournament/pgarena-tournament-index-view/pgarena-tournament-index-view.html",
"pgarena-tournament-list-view": "views/tournament/pgarena-tournament-list-view/pgarena-tournament-list-view.html",
"pgarena-account-index-view": "views/account/pgarena-account-index-view/pgarena-account-index-view.html",
"pgarena-account-login-view": "views/account/pgarena-account-login-view/pgarena-account-login-view.html",
"pgarena-account-register-view": "views/account/pgarena-account-register-view/pgarena-account-register-view.html",
"pgarena-account-confirm-email-view": "views/account/pgarena-account-confirm-email-view/pgarena-account-confirm-email-view.html",
"pgarena-account-oauth-view": "views/account/pgarena-account-oauth-view/pgarena-account-oauth-view.html",
"pgarena-clash-index-view": "views/clash/pgarena-clash-index-view/pgarena-clash-index-view.html",
"pgarena-clash-brawl-view": "views/clash/pgarena-clash-brawl-view/pgarena-clash-brawl-view.html",
"pgarena-teams-index-view": "views/team/pgarena-teams-index-view/pgarena-teams-index-view.html",
"pgarena-teams-create-view": "views/team/pgarena-teams-create-view/pgarena-teams-create-view.html"
};
/**
* This variable keeps track of all the vulcanized elements.
*
**/
PGArena.Vulcanized = {
}
/**
* Global Placeholder for checking which is the selected item of the iron-selectors that
are ready for lazy loading.
**/
PGArena.IronSelected = {
}
/**
* LazyLoad
*
* Lazy Loads the elements as needed. This function is triggered by iron-select
* event. If the element is already registered, then it is not loaded again.
*
* Polymer => Dependency Injection of the Polymer object. (Polymer itself)
* element => The element (DOM-wise: a.k.a tags with everything)
* elementName => The element's name.
* selectorTrigger => The element who triggered the select.
**/
function LazyLoad(Polymer, element, elementName, selectorTrigger) {
if (Polymer.isInstance(element)) {
// console.log(elementName + " is already registered ;)");
return;
} else {
//console.log(elementName+" isn't registered. On its way for Lazy Loading!");
}
//console.log("Lazy Load Started");
var hasProp = PGArena.LazyLoad.hasOwnProperty(elementName);
if (!hasProp) {
console.log("Property " + elementName + " not found for Lazy Loading");
return;
}
var href = PGArena.LazyLoad[elementName];
LoadImportAsync(href, elementName, selectorTrigger);
}
function Spinner(elementName, active) {
var paperId = 'js-' + elementName;
var queryName = active ? elementName : paperId;
var createElem = active ? 'paper-spinner-lite' : elementName;
var elem = document.querySelector(queryName);
var spinner = document.createElement(createElem);
spinner.setAttribute('active', '');
if (elem === null || elem === undefined)
return;
console.log("Element Name is");
console.log(queryName);
console.log("Element is");
console.log(elem);
console.log("Spinner is:");
console.log(spinner);
if (active) {
spinner.setAttribute('id', 'js-' + elementName);
console.log("replacing time");
elem.parentNode.replaceChild(document.createTextNode("Caca"), elem);
//elem.parentNode.replaceChild(spinner, elem);
}
else {
console.log("Replaced");
//elem.parentNode.replaceChild(elem, spinner);
}
}
function ForcedLoad() {
}
/**
* Loads the required import and appends it to the document. It really doesn't
* matter where it is appended.
*
**/
function LoadImportAsync(href, elementName) {
var link = document.createElement('link');
link.rel = 'import';
link.href = getBaseUrl() + "/NodeJS/Polymer/app/elements/" + href;
link.setAttribute('async', ''); // make it async!
link.onload = function () { Spinner(elementName, false); }
link.onerror = function (e) { console.log("There was an error loading " + elementName + ". Please Check the URL") };
document.head.appendChild(link);
}
function getBaseUrl() {
var pathArray = location.href.split('/');
var protocol = pathArray[0];
var host = pathArray[2];
return protocol + '//' + host;
}
/**
* On non-blink browsers (a.k.a Firefox , Edge, Internet Explorer)
* The event.srcElement is undefined. We need to search for it ourselves.
*
* The way we do that is that we get the current targetted element which is the iron form.
* Retrieve its selection mechanism and the supposed element's index.
*
* We proceed by query Selecting the element in the DOM all the way until we nab it.
* Then we are faced with the next challenge. We don't know if the element is using an
* index-based approach (0, 1, 2...) or an attribute approach(title="home", title="tournament",etc.)
*
* So we proceed to fetch its selection mechanism by grabbing the attrForSelected. If null, it means that
* it is using the index-based approach. We continue and get the children position at the element.
*
* Note that selectedAttr variable will return me either the index or the selected attribute's value.
* So it's going to be 0, 1, 2 if using the index based approach.
*
**/
function getSelectedElement(event) {
if (event.srcElement !== undefined)
return event.srcElement.selectedItem;
var element = event.target;
//Get the current selected attribute:
var selectedAttr = element.selected;
//Gets the attribute that is being used for selection:
var attrForSelected = element.attrForSelected;
//This means that it is not using index based
if (attrForSelected !== null) {
return element.querySelector('[' + attrForSelected + '="' + selectedAttr + '"]');
}
//Continues using index based:
var childelem = element.children[parseInt(selectedAttr)];
return childelem;
}
</script>
我们做的第一件事是定义 URL 相对于我拥有的文档。我通过定义一个 json 来实现这一点,其中一个键的名称是 iron-pages
的 title
属性,而值与此文档的相对 URL (pgarena-app ).
我的意思是,在我想要加载 pgarena-tournament-app
的情况下,我的 pgarena-app
(我的应用程序的主要入口点)在 www/polymer/pgarena-app.html
和我的 pgarena- tournament-app 在 www/polymer/routes/tournament/pgarena-tournament-app.html
中,因为这是相对的,我的 JSON 将是:
var PGArena = PGArena || {};
PGArena.LazyLoad =
{
"tournament" : "routes/tournament/pgarena-tournament-app.html",
};
注意PGArena.LazyLoad可以是任何东西,这是我用PGArena命名空间定义的全局变量。
然后,我们看到调用了LazyLoad的代码:
function LazyLoad(Polymer, element, elementName, selectorTrigger) {
if (Polymer.isInstance(element)) {
// console.log(elementName + " is already registered ;)");
return;
} else {
//console.log(elementName+" isn't registered. On its way for Lazy Loading!");
}
//console.log("Lazy Load Started");
var hasProp = PGArena.LazyLoad.hasOwnProperty(elementName);
if (!hasProp) {
console.log("Property " + elementName + " not found for Lazy Loading");
return;
}
var href = PGArena.LazyLoad[elementName];
LoadImportAsync(href, elementName, selectorTrigger);
}
我在这里所做的是检查我要延迟加载的元素是否已在我定义的 JSON (PGarena.LazyLoad) 中被引用。如果它不在那里,那么我所做的就是记录该消息。如果它在那里,但尚未加载,那么我通过创建 HTML 导入并将其附加到头部来异步加载它:
/**
* Loads the required import and appends it to the document. It really doesn't
* matter where it is appended.
*
**/
function LoadImportAsync(href, elementName) {
var link = document.createElement('link');
link.rel = 'import';
link.href = getBaseUrl() + "/NodeJS/Polymer/app/elements/" + href;
link.setAttribute('async', ''); // make it async!
link.onload = function () { Spinner(elementName, false); }
link.onerror = function (e) { console.log("There was an error loading " + elementName + ". Please Check the URL") };
document.head.appendChild(link);
}
请注意(我不知道他们是否解决了这个问题)。有一个用于 Firefox、Edge 和 Safari(我相信)的 HTML 导入的 polyfill。 polyfill 使用 XHR (AJAX) 加载导入!!!我提到这个是因为一开始我试图拦截 HTML 导入,但在 Google Chrome 中它不起作用。
如果您还需要什么,请告诉我。如您所见,我尝试使用微调器,但没有成功。希望这对您有所帮助!
也许我偏执了。我总是喜欢让我的代码尽可能精简。我总是将我的网站目标定在 1.5 MB 以下(所有图像都根据需要压缩和调整大小(。我在一个月前开始使用 Polymer,然后想到我可以从 Bootstrap 中减少 150 KB,从 [=40 中减少 90 KB =],并拥有一个相对轻量级的网站。
我刚刚硫化了我的 elements.html 文件,我吓坏了。野兽是 947KB,没有图像,只有 HTML 和 JS。我有大约 40 个自定义元素 + 几个元素目录(我什至还没有接近创建新元素)。 (GZip 是 947KB 中的 307.40 KB)(使用 ASP.NET MVC5 和 .NET 4.6)。
使用常规 3G 连接,加载 Chrome 52 大约需要 5.15 秒(这太糟糕了)。 Polymer Shop 演示加载速度非常快(在常规 3G 中从冷缓存中加载不到 3 秒)
首先,这是可以接受的吗?我试图在 3 秒标记之前击中(或尽可能接近它)。
此外,有许多 JavaScript 文件正在作为 Vulcanize 的一部分加载,我不需要这些文件。
我看过这个 Gist:Vulcanize and Polymer auto Lazy Loading 但我不知道如何处理它。
这些是我的 elements.html 文件的导入:
<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">
然后我所有的自定义元素 (pgarena) 都内置了更多的聚合物组件。
我尝试了几种组合(仅使用我的元素)和(仅使用显示的聚合物元素)并且我得到了不同的结果(如预期的那样)
我不知道该怎么做...在诉诸 hacky 东西之前...有什么建议吗?
我先从 Vulcanize 默认情况下仅合并文件这一事实开始。例如,您是否添加了删除评论的开关?
此外,您可能希望缩小捆绑的 HTML 和 JS 文件。大多数示例将向您展示 Gulp 设置,但您也可以在 npm 脚本的第二步中缩小硫化文件。
也许这个 post 会有所帮助:https://jongeho.wordpress.com/2015/06/24/endeavors-with-polymer-1-0-vulcanize-crisper-html-minifier/
也就是说,一个富含 Web 组件的应用程序自然会非常大。我也注意到了这一点
好的,各位,请耐心等待。这将是一个很长的答案。它可能会变得有点毛茸茸。首先,这是一个 Polymer 1.x 解决方案。我不知道 2.0 版有什么变化
长话短说:
我们获取 .HTML 的 URL 并使用 JavaScript 创建 link
属性(HTML 导入)以加载元素。我们使用 Polymer.isInstance(element)
检查 Polymer 是否已设置对象。
代码如下:
为此,我使用了 iron-pages
和自定义 JavaScript。
我们有自己的app,如下:
注意*:下面的代码我已经放在同一个文件里了,大家可以随意分开。
<!-- Main Entry point for the application. This will work as the main "Controller"-->
<link rel="import" href="../../bower_components/polymer/polymer.html">
<link rel="import" href="../../bower_components/app-route/app-location.html">
<link rel="import" href="../../bower_components/app-route/app-route.html">
<link rel="import" href="../../bower_components/iron-pages/iron-pages.html">
<dom-module id="pgarena-app">
<template>
<pgarena-action-config></pgarena-action-config>
<app-route route="{{route}}"
pattern="/:page"
data="{{data}}"
tail="{{tail}}">
</app-route>
<iron-pages selected="[[data.page]]" attr-for-selected="title" fallback-selection="404">
<pgarena-home-app title="" route="[[tail]]"></pgarena-home-app>
<pgarena-tournament-app title="tournaments" route="[[tail]]"></pgarena-tournament-app>
<!--<pgarena-clash-app title="clash" route="[[tail]]"></pgarena-clash-app>-->
<pgarena-account-app title="account" route="[[tail]]"><content></content></pgarena-account-app>
<pgarena-teams-app title="teams" route="[[tail]]"></pgarena-teams-app>
<div title="404">
<h1>{{data.page}} could not be found!</h1>
</div>
</iron-pages>
</template>
<script>
(function () {
'use strict';
Polymer({
is: 'pgarena-app',
ready: function () {
/* console.log("Route is ");
console.log(this.data.page);
console.log(this.tail);*/
document.addEventListener('iron-select',
function (event) {
/*
console.log("---------------------");
console.log(event);
console.log("---------------------");*/
var element = getSelectedElement(event);
var tagName = element.tagName.toLowerCase();
LazyLoad(Polymer, element, tagName, event.target);
});
}
});
})();
</script>
让我们先了解一些事情:
- 我的应用名为:"pgarena-app"
- 我不知道这是否已修复,但 app-route 元素存在双向数据绑定问题。这意味着对于铁页,我必须使用双括号
[[]]
来进行单向数据绑定。 - App 路由将来自 url 的信息传递给 iron-pages,以便它可以切换不同的元素。
- 这不是强制性的,我不知道这样做是否正确。我将我的应用程序分成 "views",它们本身就是元素。他们加载 "view" 所需的所有元素。 注意:这 没有 效果,无论在延迟加载中如何。
请注意,这些元素未包含在 URL 中,因为我们将延迟加载它们。
让我们转到此元素的 JavaScript 部分:
<script>
(function () {
'use strict';
Polymer({
is: 'pgarena-app',
ready: function () {
document.addEventListener('iron-select',
function (event) {
var element = getSelectedElement(event);
var tagName = element.tagName.toLowerCase();
LazyLoad(Polymer, element, tagName, event.target);
});
}
});
})();
</script>
这里的代码很简单。我们定义我们的元素,然后我们 监听 iron select 事件。 这向我们表明 iron-page 已经 selected。如果元素不存在,我们将延迟加载该元素。这背后的魔力在于习俗 LazyLoad
JavaScript,如下所示。
<script>
/**
* Defines all the routes of the imports in here
*
* This is how it goes: The Key name is the tag name of the element.
* The value is the relative URL from the elements folder.
*
* You then get the element's tag name and look for it.
*
* DO NOT PUT TRAILING SLASH BEFORE THE URL! Thanks :)
**/
var PGArena = PGArena || {};
PGArena.LazyLoad =
{
"pgarena-home-app": "routes/home/pgarena-home-app.html",
"pgarena-tournament-app": "routes/tournament/pgarena-tournament-app.html",
"pgarena-account-app": "routes/account/pgarena-account-app.html",
"pgarena-clash-app": "routes/clash/pgarena-clash-app.html",
"pgarena-teams-app": "routes/teams/pgarena-teams-app.html",
"pgarena-tournament-index-view": "views/tournament/pgarena-tournament-index-view/pgarena-tournament-index-view.html",
"pgarena-tournament-list-view": "views/tournament/pgarena-tournament-list-view/pgarena-tournament-list-view.html",
"pgarena-account-index-view": "views/account/pgarena-account-index-view/pgarena-account-index-view.html",
"pgarena-account-login-view": "views/account/pgarena-account-login-view/pgarena-account-login-view.html",
"pgarena-account-register-view": "views/account/pgarena-account-register-view/pgarena-account-register-view.html",
"pgarena-account-confirm-email-view": "views/account/pgarena-account-confirm-email-view/pgarena-account-confirm-email-view.html",
"pgarena-account-oauth-view": "views/account/pgarena-account-oauth-view/pgarena-account-oauth-view.html",
"pgarena-clash-index-view": "views/clash/pgarena-clash-index-view/pgarena-clash-index-view.html",
"pgarena-clash-brawl-view": "views/clash/pgarena-clash-brawl-view/pgarena-clash-brawl-view.html",
"pgarena-teams-index-view": "views/team/pgarena-teams-index-view/pgarena-teams-index-view.html",
"pgarena-teams-create-view": "views/team/pgarena-teams-create-view/pgarena-teams-create-view.html"
};
/**
* This variable keeps track of all the vulcanized elements.
*
**/
PGArena.Vulcanized = {
}
/**
* Global Placeholder for checking which is the selected item of the iron-selectors that
are ready for lazy loading.
**/
PGArena.IronSelected = {
}
/**
* LazyLoad
*
* Lazy Loads the elements as needed. This function is triggered by iron-select
* event. If the element is already registered, then it is not loaded again.
*
* Polymer => Dependency Injection of the Polymer object. (Polymer itself)
* element => The element (DOM-wise: a.k.a tags with everything)
* elementName => The element's name.
* selectorTrigger => The element who triggered the select.
**/
function LazyLoad(Polymer, element, elementName, selectorTrigger) {
if (Polymer.isInstance(element)) {
// console.log(elementName + " is already registered ;)");
return;
} else {
//console.log(elementName+" isn't registered. On its way for Lazy Loading!");
}
//console.log("Lazy Load Started");
var hasProp = PGArena.LazyLoad.hasOwnProperty(elementName);
if (!hasProp) {
console.log("Property " + elementName + " not found for Lazy Loading");
return;
}
var href = PGArena.LazyLoad[elementName];
LoadImportAsync(href, elementName, selectorTrigger);
}
function Spinner(elementName, active) {
var paperId = 'js-' + elementName;
var queryName = active ? elementName : paperId;
var createElem = active ? 'paper-spinner-lite' : elementName;
var elem = document.querySelector(queryName);
var spinner = document.createElement(createElem);
spinner.setAttribute('active', '');
if (elem === null || elem === undefined)
return;
console.log("Element Name is");
console.log(queryName);
console.log("Element is");
console.log(elem);
console.log("Spinner is:");
console.log(spinner);
if (active) {
spinner.setAttribute('id', 'js-' + elementName);
console.log("replacing time");
elem.parentNode.replaceChild(document.createTextNode("Caca"), elem);
//elem.parentNode.replaceChild(spinner, elem);
}
else {
console.log("Replaced");
//elem.parentNode.replaceChild(elem, spinner);
}
}
function ForcedLoad() {
}
/**
* Loads the required import and appends it to the document. It really doesn't
* matter where it is appended.
*
**/
function LoadImportAsync(href, elementName) {
var link = document.createElement('link');
link.rel = 'import';
link.href = getBaseUrl() + "/NodeJS/Polymer/app/elements/" + href;
link.setAttribute('async', ''); // make it async!
link.onload = function () { Spinner(elementName, false); }
link.onerror = function (e) { console.log("There was an error loading " + elementName + ". Please Check the URL") };
document.head.appendChild(link);
}
function getBaseUrl() {
var pathArray = location.href.split('/');
var protocol = pathArray[0];
var host = pathArray[2];
return protocol + '//' + host;
}
/**
* On non-blink browsers (a.k.a Firefox , Edge, Internet Explorer)
* The event.srcElement is undefined. We need to search for it ourselves.
*
* The way we do that is that we get the current targetted element which is the iron form.
* Retrieve its selection mechanism and the supposed element's index.
*
* We proceed by query Selecting the element in the DOM all the way until we nab it.
* Then we are faced with the next challenge. We don't know if the element is using an
* index-based approach (0, 1, 2...) or an attribute approach(title="home", title="tournament",etc.)
*
* So we proceed to fetch its selection mechanism by grabbing the attrForSelected. If null, it means that
* it is using the index-based approach. We continue and get the children position at the element.
*
* Note that selectedAttr variable will return me either the index or the selected attribute's value.
* So it's going to be 0, 1, 2 if using the index based approach.
*
**/
function getSelectedElement(event) {
if (event.srcElement !== undefined)
return event.srcElement.selectedItem;
var element = event.target;
//Get the current selected attribute:
var selectedAttr = element.selected;
//Gets the attribute that is being used for selection:
var attrForSelected = element.attrForSelected;
//This means that it is not using index based
if (attrForSelected !== null) {
return element.querySelector('[' + attrForSelected + '="' + selectedAttr + '"]');
}
//Continues using index based:
var childelem = element.children[parseInt(selectedAttr)];
return childelem;
}
</script>
我们做的第一件事是定义 URL 相对于我拥有的文档。我通过定义一个 json 来实现这一点,其中一个键的名称是 iron-pages
的 title
属性,而值与此文档的相对 URL (pgarena-app ).
我的意思是,在我想要加载 pgarena-tournament-app
的情况下,我的 pgarena-app
(我的应用程序的主要入口点)在 www/polymer/pgarena-app.html
和我的 pgarena- tournament-app 在 www/polymer/routes/tournament/pgarena-tournament-app.html
中,因为这是相对的,我的 JSON 将是:
var PGArena = PGArena || {}; PGArena.LazyLoad = { "tournament" : "routes/tournament/pgarena-tournament-app.html", };
注意PGArena.LazyLoad可以是任何东西,这是我用PGArena命名空间定义的全局变量。
然后,我们看到调用了LazyLoad的代码:
function LazyLoad(Polymer, element, elementName, selectorTrigger) {
if (Polymer.isInstance(element)) {
// console.log(elementName + " is already registered ;)");
return;
} else {
//console.log(elementName+" isn't registered. On its way for Lazy Loading!");
}
//console.log("Lazy Load Started");
var hasProp = PGArena.LazyLoad.hasOwnProperty(elementName);
if (!hasProp) {
console.log("Property " + elementName + " not found for Lazy Loading");
return;
}
var href = PGArena.LazyLoad[elementName];
LoadImportAsync(href, elementName, selectorTrigger);
}
我在这里所做的是检查我要延迟加载的元素是否已在我定义的 JSON (PGarena.LazyLoad) 中被引用。如果它不在那里,那么我所做的就是记录该消息。如果它在那里,但尚未加载,那么我通过创建 HTML 导入并将其附加到头部来异步加载它:
/**
* Loads the required import and appends it to the document. It really doesn't
* matter where it is appended.
*
**/
function LoadImportAsync(href, elementName) {
var link = document.createElement('link');
link.rel = 'import';
link.href = getBaseUrl() + "/NodeJS/Polymer/app/elements/" + href;
link.setAttribute('async', ''); // make it async!
link.onload = function () { Spinner(elementName, false); }
link.onerror = function (e) { console.log("There was an error loading " + elementName + ". Please Check the URL") };
document.head.appendChild(link);
}
请注意(我不知道他们是否解决了这个问题)。有一个用于 Firefox、Edge 和 Safari(我相信)的 HTML 导入的 polyfill。 polyfill 使用 XHR (AJAX) 加载导入!!!我提到这个是因为一开始我试图拦截 HTML 导入,但在 Google Chrome 中它不起作用。
如果您还需要什么,请告诉我。如您所见,我尝试使用微调器,但没有成功。希望这对您有所帮助!