รวมสำหรับเว็บ
เหตุผลที่ควรนําเข้า
ลองนึกถึงวิธีโหลดทรัพยากรประเภทต่างๆ ในเว็บ สำหรับ JS เรามี <script src>
สําหรับ CSS ตัวเลือกที่เหมาะสําหรับคุณน่าจะเป็น <link rel="stylesheet">
สำหรับรูปภาพจะเป็น <img>
วิดีโอมี <video>
เสียง <audio>
… เข้าประเด็นเลย เนื้อหาส่วนใหญ่ของเว็บมีวิธีโหลดตัวเองที่ง่ายและชัดเจน แต่ไม่ใช่สำหรับ HTML ตัวเลือกของคุณมีดังนี้
<iframe>
- ได้ผลดีแต่มีน้ำหนักมาก เนื้อหาของ iframe จะอยู่ในบริบทที่แยกจากหน้าเว็บของคุณโดยสิ้นเชิง แม้ว่าฟีเจอร์นี้จะยอดเยี่ยม แต่ก็ยังทำให้เกิดปัญหาเพิ่มเติม (การปรับขนาดเฟรมให้พอดีกับเนื้อหานั้นทำได้ยากมาก เขียนสคริปต์เข้า/ออกจากเฟรมได้ยากมาก และแทบจะจัดสไตล์ไม่ได้)- AJAX - ฉันชอบ
xhr.responseType="document"
แต่คุณบอกว่าฉันต้องใช้ JS เพื่อโหลด HTML ใช่ไหม ข้อมูลนี้ไม่ถูกต้อง - CrazyHacks™ - ฝังอยู่ในสตริง ซ่อนอยู่ในรูปแบบความคิดเห็น (เช่น
<script type="text/html">
) น่าขยะแขยง
เข้าใจความย้อนแย้งไหม เนื้อหาพื้นฐานที่สุดของเว็บอย่าง HTML ต้องใช้ความพยายามมากที่สุดในการดำเนินการ แต่โชคดีที่เรามีคอมโพเนนต์ของเว็บที่จะช่วยเรากลับมาทำงานได้ตามปกติ
เริ่มต้นใช้งาน
การนําเข้า HTML ซึ่งเป็นส่วนหนึ่งของการแคสต์ Web Components เป็นวิธีรวมเอกสาร HTML ไว้ในเอกสาร HTML อื่นๆ นอกจากนี้ คุณยังใช้มาร์กอัปได้อีกด้วย การนําเข้ายังอาจรวมถึง CSS, JavaScript หรือสิ่งอื่นๆ ที่ไฟล์ .html
อาจมี กล่าวคือ การดำเนินการนี้ทำให้การนําเข้าเป็นเครื่องมือที่ยอดเยี่ยมสําหรับการโหลด HTML/CSS/JS ที่เกี่ยวข้อง
ข้อมูลพื้นฐาน
รวมการนําเข้าไว้ในหน้าเว็บโดยประกาศ <link rel="import">
ดังนี้
<head>
<link rel="import" href="/path/to/imports/stuff.html">
</head>
URL ของการนําเข้าเรียกว่าสถานที่นําเข้า หากต้องการโหลดเนื้อหาจากโดเมนอื่น ตำแหน่งการนําเข้าต้องเปิดใช้ CORS โดยทำดังนี้
<!-- Resources on other origins must be CORS-enabled. -->
<link rel="import" href="http://example.com/elements.html">
การตรวจหาและรองรับฟีเจอร์
หากต้องการตรวจสอบการรองรับ ให้ตรวจสอบว่า .import
อยู่ในองค์ประกอบ <link>
หรือไม่
function supportsImports() {
return 'import' in document.createElement('link');
}
if (supportsImports()) {
// Good to go!
} else {
// Use other libraries/require systems to load files.
}
การรองรับเบราว์เซอร์ยังอยู่ในขั้นเริ่มต้น Chrome 31 เป็นเบราว์เซอร์แรกที่เริ่มใช้งาน แต่ผู้ให้บริการเบราว์เซอร์รายอื่นๆ กำลังรอดูว่า ES Modules จะทำงานได้ดีเพียงใด อย่างไรก็ตาม Polyfill ของ webcomponents.js จะใช้งานได้ดีในเบราว์เซอร์อื่นๆ จนกว่าจะมีการใช้งานอย่างแพร่หลาย
การรวมทรัพยากร
การนําเข้ามีรูปแบบการรวม HTML/CSS/JS (รวมถึงการนําเข้า HTML อื่นๆ) ไว้ในไฟล์นำส่งไฟล์เดียว ฟีเจอร์นี้เป็นฟีเจอร์พื้นฐานที่มีประสิทธิภาพ หากคุณกำลังสร้างธีม ไลบรารี หรือเพียงแค่ต้องการแบ่งแอปออกเป็นส่วนๆ ตามความเหมาะสม การให้ URL เดียวแก่ผู้ใช้ก็เป็นสิ่งที่น่าสนใจ คุณยังส่งแอปทั้งแอปผ่านการนําเข้าได้ด้วย ลองคิดดูสักครู่
ตัวอย่างการใช้งานจริงคือ Bootstrap Bootstrap ประกอบด้วยไฟล์เดี่ยวๆ (bootstrap.css, bootstrap.js, แบบอักษร) ต้องใช้ JQuery สําหรับปลั๊กอิน และแสดงตัวอย่างมาร์กอัป นักพัฒนาแอปชอบความยืดหยุ่นแบบเลือกได้ตามต้องการ ซึ่งช่วยให้องค์กรซื้อส่วนต่างๆ ของเฟรมเวิร์กที่ต้องการใช้ อย่างไรก็ตาม เราขอเดาว่านักพัฒนาซอฟต์แวร์ทั่วไปอย่าง JoeDeveloper™ จะเลือกวิธีที่ง่ายและดาวน์โหลด Bootstrap ทั้งหมด
การนําเข้าเหมาะสําหรับสิ่งต่างๆ เช่น Bootstrap เราขอนำเสนออนาคตของการโหลด Bootstrap
<head>
<link rel="import" href="bootstrap.html">
</head>
ผู้ใช้เพียงโหลดลิงก์การนําเข้า HTML ผู้ใช้ไม่จำเป็นต้องกังวลกับไฟล์ที่กระจัดกระจาย แต่ระบบจะจัดการและรวม Bootstrap ทั้งหมดไว้ในไฟล์ bootstrap.html ที่จะนําเข้า
<link rel="stylesheet" href="bootstrap.css">
<link rel="stylesheet" href="fonts.css">
<script src="jquery.js"></script>
<script src="bootstrap.js"></script>
<script src="bootstrap-tooltip.js"></script>
<script src="bootstrap-dropdown.js"></script>
...
<!-- scaffolding markup -->
<template>
...
</template>
โปรดรอสักครู่ เป็นเรื่องที่น่าตื่นเต้น
เหตุการณ์การโหลด/ข้อผิดพลาด
องค์ประกอบ <link>
จะเรียกเหตุการณ์ load
เมื่อการนําเข้าโหลดสําเร็จ และ onerror
เมื่อการพยายามนําเข้าล้มเหลว (เช่น ทรัพยากรแสดงผลเป็น 404)
การนําเข้าจะพยายามโหลดทันที วิธีง่ายๆ ในการหลีกเลี่ยงความยุ่งยากคือการใช้สําหรับแอตทริบิวต์ onload
/onerror
<script>
function handleLoad(e) {
console.log('Loaded import: ' + e.target.href);
}
function handleError(e) {
console.log('Error loading import: ' + e.target.href);
}
</script>
<link rel="import" href="file.html"
onload="handleLoad(event)" onerror="handleError(event)">
หรือหากจะสร้างการนําเข้าแบบไดนามิก ให้ทําดังนี้
var link = document.createElement('link');
link.rel = 'import';
// link.setAttribute('async', ''); // make it async!
link.href = 'file.html';
link.onload = function(e) {...};
link.onerror = function(e) {...};
document.head.appendChild(link);
การใช้เนื้อหา
การรวมการนําเข้าในหน้าเว็บไม่ได้หมายความว่า "วางเนื้อหาของไฟล์นั้นไว้ที่นี่" ซึ่งหมายความว่า "ไปดึงข้อมูลเอกสารนี้มาให้เราใช้" หากต้องการใช้เนื้อหาจริง คุณต้องดำเนินการและเขียนสคริปต์
aha!
ช่วงเวลาสําคัญคือการตระหนักว่าการนําเข้าเป็นเพียงเอกสาร เนื้อหาของการนําเข้าเรียกว่าเอกสารนําเข้า คุณสามารถจัดการข้อมูลการนําเข้าโดยใช้ DOM API มาตรฐาน
link.import
หากต้องการเข้าถึงเนื้อหาของการนําเข้า ให้ใช้พร็อพเพอร์ตี้ .import
ขององค์ประกอบลิงก์ ดังนี้
var content = document.querySelector('link[rel="import"]').import;
link.import
คือ null
ภายใต้เงื่อนไขต่อไปนี้
- เบราว์เซอร์ไม่รองรับการนําเข้า HTML
<link>
ไม่มีrel="import"
- ยังไม่ได้เพิ่ม
<link>
ลงใน DOM - ระบบนำ
<link>
ออกจาก DOM แล้ว - ทรัพยากรไม่ได้เปิดใช้ CORS
ตัวอย่างแบบเต็ม
สมมติว่า warnings.html
มีข้อมูลต่อไปนี้
<div class="warning">
<style>
h3 {
color: red !important;
}
</style>
<h3>Warning!
<p>This page is under construction
</div>
<div class="outdated">
<h3>Heads up!
<p>This content may be out of date
</div>
ผู้นำเข้าสามารถคัดลอกส่วนที่ต้องการของเอกสารนี้ไปวางในหน้าเว็บของตนได้
<head>
<link rel="import" href="warnings.html">
</head>
<body>
...
<script>
var link = document.querySelector('link[rel="import"]');
var content = link.import;
// Grab DOM from warning.html's document.
var el = content.querySelector('.warning');
document.body.appendChild(el.cloneNode(true));
</script>
</body>
สคริปต์ในการนําเข้า
การนําเข้าไม่ได้อยู่ในเอกสารหลัก ข้อมูลดังกล่าวเป็นข้อมูลรอง อย่างไรก็ตาม การนําเข้าจะยังคงทํางานในหน้าหลักได้ แม้ว่าเอกสารหลักจะเป็นผู้ควบคุม การนําเข้าสามารถเข้าถึง DOM ของตนเองและ/หรือ DOM ของหน้าเว็บที่นําเข้าได้ ดังนี้
ตัวอย่าง - import.html ที่เพิ่มสไตล์ชีตรายการใดรายการหนึ่งไปยังหน้าหลัก
<link rel="stylesheet" href="http://www.example.com/styles.css">
<link rel="stylesheet" href="http://www.example.com/styles2.css">
<style>
/* Note: <style> in an import apply to the main
document by default. That is, style tags don't need to be
explicitly added to the main document. */
#somecontainer {
color: blue;
}
</style>
...
<script>
// importDoc references this import's document
var importDoc = document.currentScript.ownerDocument;
// mainDoc references the main document (the page that's importing us)
var mainDoc = document;
// Grab the first stylesheet from this import, clone it,
// and append it to the importing document.
var styles = importDoc.querySelector('link[rel="stylesheet"]');
mainDoc.head.appendChild(styles.cloneNode(true));
</script>
สังเกตสิ่งที่เกิดขึ้น สคริปต์ภายในการนําเข้าจะอ้างอิงเอกสารที่นําเข้า (document.currentScript.ownerDocument
) และเพิ่มส่วนหนึ่งของเอกสารนั้นต่อท้ายหน้าการนําเข้า (mainDoc.head.appendChild(...)
) ค่อนข้างซับซ้อน
กฎของ JavaScript ในการนําเข้า
- สคริปต์ในการนําเข้าจะทํางานในบริบทของหน้าต่างที่มี
document
ที่นําเข้า ดังนั้นwindow.document
จึงหมายถึงเอกสารหน้าแรก ผลที่ตามมาที่เป็นประโยชน์ 2 ประการ ได้แก่- ฟังก์ชันที่กําหนดในการนําเข้าจะปรากฏใน
window
- คุณไม่ต้องดำเนินการใดๆ ที่ยุ่งยาก เช่น เพิ่มบล็อก
<script>
ของการนําเข้าต่อท้ายหน้าหลัก สคริปต์จะทำงานอีกครั้ง
- ฟังก์ชันที่กําหนดในการนําเข้าจะปรากฏใน
- การนําเข้าจะไม่บล็อกการแยกวิเคราะห์หน้าหลัก อย่างไรก็ตาม ระบบจะประมวลผลสคริปต์ภายในตามลําดับ ซึ่งหมายความว่าคุณจะได้รับลักษณะการทำงานแบบเลื่อนเวลาไว้ขณะที่รักษาลําดับสคริปต์ที่เหมาะสม ดูข้อมูลเพิ่มเติมด้านล่าง
การนำส่งคอมโพเนนต์เว็บ
การออกแบบการนําเข้า HTML เหมาะสําหรับการโหลดเนื้อหาที่นํามาใช้ซ้ำบนเว็บ โดยเฉพาะอย่างยิ่ง นี่เป็นวิธีที่เหมาะอย่างยิ่งในการเผยแพร่คอมโพเนนต์เว็บ ทุกอย่างตั้งแต่ HTML <template>
พื้นฐานไปจนถึงองค์ประกอบที่กำหนดเองอย่างเต็มรูปแบบที่มี Shadow DOM [1, 2, 3] เมื่อใช้เทคโนโลยีเหล่านี้ร่วมกัน การนําเข้าจะกลายเป็น #include
สําหรับคอมโพเนนต์ของเว็บ
รวมถึงเทมเพลต
องค์ประกอบเทมเพลต HTML เหมาะสําหรับการนําเข้า HTML <template>
เหมาะอย่างยิ่งสำหรับการสร้างโครงสร้างส่วนต่างๆ ของมาร์กอัปเพื่อให้แอปที่นำเข้านำไปใช้ได้ตามต้องการ การรวมเนื้อหาใน <template>
ยังให้คุณได้รับประโยชน์เพิ่มเติมในการทำให้เนื้อหาไม่มีผลจนกว่าจะใช้งาน กล่าวคือ สคริปต์จะไม่ทํางานจนกว่าจะเพิ่มเทมเพลตลงใน DOM) ตูม
import.html
<template>
<h1>Hello World!</h1>
<!-- Img is not requested until the <template> goes live. -->
<img src="world.png">
<script>alert("Executed when the template is activated.");</script>
</template>
index.html
<head>
<link rel="import" href="import.html">
</head>
<body>
<div id="container"></div>
<script>
var link = document.querySelector('link[rel="import"]');
// Clone the <template> in the import.
var template = link.import.querySelector('template');
var clone = document.importNode(template.content, true);
document.querySelector('#container').appendChild(clone);
</script>
</body>
การลงทะเบียนองค์ประกอบที่กําหนดเอง
องค์ประกอบที่กําหนดเองเป็นเทคโนโลยี Web Components อีกอย่างหนึ่งที่ทํางานร่วมกับ HTML Imports ได้อย่างยอดเยี่ยม การนําเข้าสามารถเรียกใช้สคริปต์ได้ ดังนั้นคุณจึงควรกําหนด + ลงทะเบียนองค์ประกอบที่กําหนดเองเพื่อไม่ให้ผู้ใช้ต้องดำเนินการ เราเรียกกระบวนการนี้ว่า "การลงทะเบียนอัตโนมัติ"
elements.html
<script>
// Define and register <say-hi>.
var proto = Object.create(HTMLElement.prototype);
proto.createdCallback = function() {
this.innerHTML = 'Hello, <b>' +
(this.getAttribute('name') || '?') + '</b>';
};
document.registerElement('say-hi', {prototype: proto});
</script>
<template id="t">
<style>
::content > * {
color: red;
}
</style>
<span>I'm a shadow-element using Shadow DOM!</span>
<content></content>
</template>
<script>
(function() {
var importDoc = document.currentScript.ownerDocument; // importee
// Define and register <shadow-element>
// that uses Shadow DOM and a template.
var proto2 = Object.create(HTMLElement.prototype);
proto2.createdCallback = function() {
// get template in import
var template = importDoc.querySelector('#t');
// import template into
var clone = document.importNode(template.content, true);
var root = this.createShadowRoot();
root.appendChild(clone);
};
document.registerElement('shadow-element', {prototype: proto2});
})();
</script>
การนําเข้านี้จะกําหนด (และลงทะเบียน) องค์ประกอบ 2 รายการ ได้แก่ <say-hi>
และ <shadow-element>
รายการแรกแสดงองค์ประกอบที่กำหนดเองพื้นฐานที่ลงทะเบียนตัวเองภายในการนําเข้า ตัวอย่างที่ 2 แสดงวิธีใช้องค์ประกอบที่กําหนดเองซึ่งสร้าง Shadow DOM จาก <template>
จากนั้นลงทะเบียนตัวเอง
สิ่งที่ยอดเยี่ยมที่สุดเกี่ยวกับการลงทะเบียนองค์ประกอบที่กำหนดเองภายในการนําเข้า HTML คือผู้นําเข้าเพียงต้องประกาศองค์ประกอบของคุณในหน้าเว็บ ไม่ต้องเดินสายไฟ
index.html
<head>
<link rel="import" href="elements.html">
</head>
<body>
<say-hi name="Eric"></say-hi>
<shadow-element>
<div>( I'm in the light dom )</div>
</shadow-element>
</body>
เราคิดว่าเวิร์กโฟลว์นี้เพียงอย่างเดียวทำให้การนําเข้า HTML เป็นวิธีที่เหมาะสําหรับแชร์คอมโพเนนต์เว็บ
การจัดการทรัพยากร Dependency และการนําเข้าย่อย
การนําเข้าย่อย
ซึ่งอาจมีประโยชน์สำหรับการนําเข้ารายการหนึ่งเพื่อรวมรายการอื่น เช่น หากต้องการนําคอมโพเนนต์อื่นมาใช้ซ้ำหรือขยาย ให้ใช้การนําเข้าเพื่อโหลดองค์ประกอบอื่นๆ
ด้านล่างนี้คือตัวอย่างจริงจาก Polymer คอมโพเนนต์นี้เป็นคอมโพเนนต์แท็บใหม่ (<paper-tabs>
) ที่ใช้เลย์เอาต์และคอมโพเนนต์ตัวเลือกซ้ำ จัดการทรัพยากร Dependency โดยใช้การนําเข้า HTML
paper-tabs.html (แบบง่าย)
<link rel="import" href="iron-selector.html">
<link rel="import" href="classes/iron-flex-layout.html">
<dom-module id="paper-tabs">
<template>
<style>...</style>
<iron-selector class="layout horizonta center">
<content select="*"></content>
</iron-selector>
</template>
<script>...</script>
</dom-module>
นักพัฒนาแอปจะนำเข้าองค์ประกอบใหม่นี้โดยใช้วิธีต่อไปนี้
<link rel="import" href="paper-tabs.html">
<paper-tabs></paper-tabs>
เมื่อ <iron-selector2>
ใหม่และเจ๋งกว่าเดิมเปิดตัวในอนาคต คุณสามารถเปลี่ยน <iron-selector>
และเริ่มใช้งานได้ทันที คุณจะไม่ต้องทำให้ผู้ใช้เสียประสบการณ์การใช้งานด้วยฟีเจอร์การนําเข้าและคอมโพเนนต์เว็บ
การจัดการการขึ้นต่อกัน
เราทุกคนทราบดีว่าการโหลด JQuery มากกว่า 1 ครั้งต่อหน้าเว็บทำให้เกิดข้อผิดพลาด การดำเนินการนี้จะไม่ก่อให้เกิดปัญหาใหญ่สำหรับคอมโพเนนต์เว็บเมื่อคอมโพเนนต์หลายรายการใช้ไลบรารีเดียวกันใช่ไหม ไม่ หากใช้การนําเข้า HTML ซึ่งสามารถใช้เพื่อจัดการการพึ่งพาได้
การรวมไลบรารีในการนําเข้า HTML จะเป็นการกรองทรัพยากรที่ซ้ำกันออกโดยอัตโนมัติ ระบบจะแยกวิเคราะห์เอกสารเพียงครั้งเดียว สคริปต์จะทำงานเพียงครั้งเดียว ตัวอย่างเช่น สมมติว่าคุณกำหนดการนําเข้า jquery.html ที่โหลดสําเนา JQuery
jquery.html
<script src="http://cdn.com/jquery.js"></script>
คุณนําการนําเข้านี้มาใช้ซ้ำในการนําเข้าครั้งต่อๆ ไปได้ดังนี้
import2.html
<link rel="import" href="jquery.html">
<div>Hello, I'm import 2</div>
ajax-element.html
<link rel="import" href="jquery.html">
<link rel="import" href="import2.html">
<script>
var proto = Object.create(HTMLElement.prototype);
proto.makeRequest = function(url, done) {
return $.ajax(url).done(function() {
done();
});
};
document.registerElement('ajax-element', {prototype: proto});
</script>
แม้แต่หน้าหลักเองก็สามารถมี jquery.html ได้หากต้องใช้ไลบรารีนี้
<head>
<link rel="import" href="jquery.html">
<link rel="import" href="ajax-element.html">
</head>
<body>
...
<script>
$(document).ready(function() {
var el = document.createElement('ajax-element');
el.makeRequest('http://example.com');
});
</script>
</body>
แม้ว่า jquery.html จะรวมอยู่ในต้นไม้การนําเข้าหลายรายการ แต่เบราว์เซอร์จะดึงข้อมูลและประมวลผลเอกสารเพียงครั้งเดียว การตรวจสอบแผงเครือข่ายยืนยันข้อมูลนี้

ข้อพิจารณาด้านประสิทธิภาพ
การนําเข้า HTML นั้นยอดเยี่ยมมาก แต่คุณควรใช้อย่างชาญฉลาดเช่นเดียวกับเทคโนโลยีเว็บใหม่ๆ แนวทางปฏิบัติแนะนำสำหรับการพัฒนาเว็บยังคงใช้ได้อยู่ สิ่งที่ควรคำนึงถึงมีดังนี้
นำเข้าแบบต่อท้าย
การลดคำขอเครือข่ายเป็นสิ่งสำคัญเสมอ หากคุณมีลิงก์การนําเข้าระดับบนสุดจํานวนมาก ให้ลองรวมลิงก์เหล่านั้นเป็นทรัพยากรเดียวแล้วนําเข้าไฟล์นั้น
Vulcanize เป็นเครื่องมือสร้าง npm จากทีม Polymer ซึ่งจะยุบชุดการนําเข้า HTML ซ้ำๆ ให้เป็นไฟล์เดียว ขั้นตอนนี้เปรียบเสมือนขั้นตอนการสร้างการต่อเชื่อมสําหรับคอมโพเนนต์เว็บ
การนําเข้าใช้ประโยชน์จากการแคชของเบราว์เซอร์
หลายคนลืมไปว่าแพ็กเกจเครือข่ายของเบราว์เซอร์ได้รับการปรับแต่งอย่างละเอียดมาตลอดหลายปี การนําเข้า (และการนําเข้าย่อย) ใช้ประโยชน์จากตรรกะนี้ด้วย การนําเข้า http://cdn.com/bootstrap.html
อาจมีทรัพยากรย่อย แต่ระบบจะแคชไว้
เนื้อหาจะมีประโยชน์ก็ต่อเมื่อคุณเพิ่มเนื้อหานั้นเท่านั้น
โปรดทราบว่าเนื้อหาจะทำงานไม่ได้จนกว่าคุณจะเรียกใช้บริการ มาดูสไตล์ชีตปกติที่สร้างขึ้นแบบไดนามิกกัน
var link = document.createElement('link');
link.rel = 'stylesheet';
link.href = 'styles.css';
เบราว์เซอร์จะไม่ขอ styles.css จนกว่าจะมีการเพิ่ม link
ลงใน DOM
document.head.appendChild(link); // browser requests styles.css
อีกตัวอย่างหนึ่งคือมาร์กอัปที่สร้างขึ้นแบบไดนามิก
var h2 = document.createElement('h2');
h2.textContent = 'Booyah!';
h2
จะไม่มีความหมายใดๆ จนกว่าคุณจะเพิ่มลงใน DOM
แนวคิดเดียวกันนี้ใช้กับเอกสารที่นำเข้าได้ เว้นแต่คุณจะเพิ่มเนื้อหาของไฟล์ต่อท้าย DOM การดำเนินการนี้จะใช้งานไม่ได้ ความจริงแล้ว <script>
เป็นเพียงสิ่งเดียวที่ "ทำงาน" ในเอกสารการนําเข้าโดยตรง ดูสคริปต์ในการนําเข้า
การเพิ่มประสิทธิภาพสําหรับการโหลดแบบไม่ซิงค์
การนําเข้าบล็อกการแสดงผล
การนําเข้าบล็อกการแสดงผลของหน้าหลัก ซึ่งคล้ายกับสิ่งที่ <link rel="stylesheet">
ทำ เหตุผลที่เบราว์เซอร์บล็อกการแสดงผลในสไตล์ชีตตั้งแต่แรกคือการลด FOUC การนําเข้าทํางานคล้ายกันเนื่องจากอาจมีสไตลชีต
หากต้องการให้เป็นแบบไม่พร้อมกันโดยสมบูรณ์และไม่บล็อกโปรแกรมแยกวิเคราะห์หรือการเรนเดอร์ ให้ใช้แอตทริบิวต์ async
ดังนี้
<link rel="import" href="/path/to/import_that_takes_5secs.html" async>
async
ไม่ได้เป็นค่าเริ่มต้นสำหรับการนําเข้า HTML เนื่องจากนักพัฒนาซอฟต์แวร์ต้องทํางานมากขึ้น การทำงานแบบซิงค์โดยค่าเริ่มต้นหมายความว่าการนําเข้า HTML ที่มีคําจํากัดความขององค์ประกอบที่กําหนดเองจะได้รับการรับประกันว่าจะโหลดและอัปเกรดตามลําดับ ในโลกแบบแอซิงค์ทั้งหมด นักพัฒนาแอปจะต้องจัดการการเต้นและเวลาอัปเกรดด้วยตนเอง
นอกจากนี้ คุณยังสร้างการนําเข้าแบบไม่พร้อมกันแบบไดนามิกได้ด้วย โดยทําดังนี้
var l = document.createElement('link');
l.rel = 'import';
l.href = 'elements.html';
l.setAttribute('async', '');
l.onload = function(e) { ... };
การนําเข้าจะไม่บล็อกการแยกวิเคราะห์
การนําเข้าจะไม่บล็อกการแยกวิเคราะห์หน้าหลัก ระบบจะประมวลผลสคริปต์ภายในการนําเข้าตามลําดับ แต่ไม่บล็อกหน้าการนําเข้า ซึ่งหมายความว่าคุณจะได้รับลักษณะการทำงานแบบเลื่อนเวลาไว้ขณะที่รักษาลําดับสคริปต์ที่เหมาะสม ประโยชน์อย่างหนึ่งของการวางการนําเข้าใน <head>
คือช่วยให้โปรแกรมแยกวิเคราะห์เริ่มทํางานกับเนื้อหาโดยเร็วที่สุด อย่างไรก็ตาม โปรดทราบว่า <script>
ในเอกสารหลักยังคงบล็อกหน้าเว็บต่อไป <script>
แรกหลังจากการนําเข้าจะบล็อกการแสดงผลหน้าเว็บ เนื่องจากการนําเข้าอาจมีสคริปต์อยู่ภายในที่ต้องเรียกใช้ก่อนสคริปต์ในหน้าหลัก
<head>
<link rel="import" href="/path/to/import_that_takes_5secs.html">
<script>console.log('I block page rendering');</script>
</head>
การเพิ่มประสิทธิภาพลักษณะการทำงานแบบแอซิงค์ทำได้หลายวิธี โดยขึ้นอยู่กับโครงสร้างแอปและกรณีการใช้งาน เทคนิคด้านล่างจะช่วยบรรเทาการบล็อกการแสดงผลหน้าหลัก
สถานการณ์ที่ 1 (แนะนำ): คุณไม่มีสคริปต์ใน <head>
หรือแทรกใน <body>
คําแนะนําของเราสําหรับการวาง <script>
คือหลีกเลี่ยงการวางไว้ทันทีหลังจากการนําเข้า ย้ายสคริปต์ในช่วงท้ายเกมให้มากที่สุด แต่คุณก็ใช้แนวทางปฏิบัติแนะนำนี้อยู่แล้วใช่ไหม ;)
เช่น
<head>
<link rel="import" href="/path/to/import.html">
<link rel="import" href="/path/to/import2.html">
<!-- avoid including script -->
</head>
<body>
<!-- avoid including script -->
<div id="container"></div>
<!-- avoid including script -->
...
<script>
// Other scripts n' stuff.
// Bring in the import content.
var link = document.querySelector('link[rel="import"]');
var post = link.import.querySelector('#blog-post');
var container = document.querySelector('#container');
container.appendChild(post.cloneNode(true));
</script>
</body>
ทุกอย่างอยู่ที่ด้านล่าง
สถานการณ์ 1.5: การนําเข้าเพิ่มตัวเอง
อีกทางเลือกหนึ่งคือการนําเข้าเนื้อหาของตนเอง หากผู้เขียนการนําเข้าทำสัญญาให้นักพัฒนาแอปปฏิบัติตาม การนําเข้าจะเพิ่มตัวเองไปยังพื้นที่ของหน้าหลักได้ ดังนี้
import.html:
<div id="blog-post">...</div>
<script>
var me = document.currentScript.ownerDocument;
var post = me.querySelector('#blog-post');
var container = document.querySelector('#container');
container.appendChild(post.cloneNode(true));
</script>
index.html
<head>
<link rel="import" href="/path/to/import.html">
</head>
<body>
<!-- no need for script. the import takes care of things -->
</body>
สถานการณ์ #2: คุณมีสคริปต์ใน <head>
หรือแทรกใน <body>
หากคุณมีการนําเข้าที่ใช้เวลาโหลดนาน <script>
รายการแรกที่ตามหลังมาจะบล็อกไม่ให้หน้าเว็บแสดงผล ตัวอย่างเช่น Google Analytics แนะนำให้ใส่โค้ดติดตามใน <head>
หากหลีกเลี่ยงไม่ได้ที่จะใส่ <script>
ใน <head>
การเพิ่มการนําเข้าแบบไดนามิกจะช่วยป้องกันไม่ให้มีการบล็อกหน้าเว็บ
<head>
<script>
function addImportLink(url) {
var link = document.createElement('link');
link.rel = 'import';
link.href = url;
link.onload = function(e) {
var post = this.import.querySelector('#blog-post');
var container = document.querySelector('#container');
container.appendChild(post.cloneNode(true));
};
document.head.appendChild(link);
}
addImportLink('/path/to/import.html'); // Import is added early :)
</script>
<script>
// other scripts
</script>
</head>
<body>
<div id="container"></div>
...
</body>
หรือจะเพิ่มการนําเข้าไว้ใกล้ๆ ท้าย <body>
ก็ได้ โดยทําดังนี้
<head>
<script>
// other scripts
</script>
</head>
<body>
<div id="container"></div>
...
<script>
function addImportLink(url) { ... }
addImportLink('/path/to/import.html'); // Import is added very late :(
</script>
</body>
สิ่งที่ต้องจดจำ
Mimetype ของการนําเข้าคือ
text/html
ทรัพยากรจากต้นทางอื่นๆ ต้องเปิดใช้ CORS
ระบบจะดึงข้อมูลและแยกวิเคราะห์การนําเข้าจาก URL เดียวกันเพียงครั้งเดียว ซึ่งหมายความว่าสคริปต์ในการนําเข้าจะทํางานเฉพาะครั้งแรกที่ระบบเห็นการนําเข้าเท่านั้น
ระบบจะประมวลผลสคริปต์ในการนําเข้าตามลําดับ แต่ไม่บล็อกการแยกวิเคราะห์เอกสารหลัก
ลิงก์การนําเข้าไม่ได้หมายถึง "#include the content here" ซึ่งหมายความว่า "ไปดึงข้อมูลเอกสารนี้มาเพื่อให้ฉันใช้ภายหลัง" ขณะที่สคริปต์ทำงานเมื่อนำเข้า คุณต้องเพิ่มสไตล์ชีต มาร์กอัป และทรัพยากรอื่นๆ ลงในหน้าหลักอย่างชัดเจน โปรดทราบว่าคุณไม่จำเป็นต้องเพิ่ม
<style>
อย่างชัดเจน ความแตกต่างที่สำคัญระหว่างการนําเข้า HTML กับ<iframe>
คือ<iframe>
จะระบุว่า "โหลดและแสดงผลเนื้อหานี้ที่นี่"
บทสรุป
การนําเข้า HTML ช่วยให้คุณสามารถรวม HTML/CSS/JS เป็นทรัพยากรรายการเดียวได้ แม้ว่าแนวคิดนี้จะมีประโยชน์ในตัวของมันเอง แต่แนวคิดนี้กลับมีประสิทธิภาพอย่างยิ่งในโลกของคอมโพเนนต์ของเว็บ นักพัฒนาแอปสามารถสร้างคอมโพเนนต์ที่นํากลับมาใช้ซ้ำได้เพื่อให้ผู้อื่นนำไปใช้ในแอปของตนเองได้ โดยส่งผ่าน <link rel="import">
การนําเข้า HTML เป็นแนวคิดที่เรียบง่าย แต่เปิดโอกาสให้แพลตฟอร์มมีกรณีการใช้งานที่น่าสนใจหลายกรณี
กรณีการใช้งาน
- เผยแพร่ HTML/CSS/JS ที่เกี่ยวข้องเป็นกลุ่มเดียว ในทางทฤษฎี คุณสามารถนําเข้าเว็บแอปทั้งแอปไปยังอีกแอปหนึ่งได้
- การจัดระเบียบโค้ด - จัดแบ่งแนวคิดออกเป็นไฟล์ต่างๆ อย่างมีเหตุผล ซึ่งจะช่วยส่งเสริมความเป็นโมดูลและความสามารถในการนํากลับมาใช้ใหม่**
- ส่งคําจํากัดความองค์ประกอบที่กําหนดเองอย่างน้อย 1 รายการ คุณสามารถนําเข้าเพื่อregisterและรวมไว้ในแอปได้ แนวทางนี้เป็นไปตามรูปแบบซอฟต์แวร์ที่ดี ซึ่งแยกอินเทอร์เฟซ/คําจํากัดความขององค์ประกอบออกจากวิธีการใช้งาน
- จัดการทรัพยากรที่เกี่ยวข้อง - ระบบจะกรองทรัพยากรที่ซ้ำกันออกโดยอัตโนมัติ
- แยกสคริปต์เป็นกลุ่ม - ก่อนที่จะนําเข้า ไลบรารี JS ขนาดใหญ่จะแยกวิเคราะห์ไฟล์ทั้งหมดเพื่อเริ่มทํางาน ซึ่งทําให้ช้า เมื่อนำเข้าแล้ว ไลบรารีจะเริ่มทํางานทันทีที่แยกวิเคราะห์ข้อมูลส่วน A เวลาในการตอบสนองน้อยลง
// TODO: DevSite - Code sample removed as it used inline event handlers
แยกวิเคราะห์ HTML แบบขนาน - เป็นครั้งแรกที่เบราว์เซอร์สามารถเรียกใช้โปรแกรมแยกวิเคราะห์ HTML 2 รายการ (หรือมากกว่า) พร้อมกัน
เปิดใช้การสลับระหว่างโหมดแก้ไขข้อบกพร่องและโหมดที่ไม่แก้ไขข้อบกพร่องในแอปได้ง่ายๆ เพียงเปลี่ยนเป้าหมายการนําเข้า แอปไม่จำเป็นต้องทราบว่าเป้าหมายการนําเข้าคือทรัพยากรที่รวมไว้/คอมไพล์แล้วหรือเป็นต้นไม้การนําเข้า