The introduction of the script (script)
Script Inclusion (script)
There are multiple ways to include JavaScript scripts in HTML, each with its own use cases and considerations. The method of script inclusion directly impacts page load performance, execution order, and code maintainability.
Inline Scripts
The simplest way to include JavaScript is by embedding code directly within <script>
tags in the HTML file. This approach is suitable for small scripts or rapid prototyping.
<script>
console.log('Inline script executed');
document.addEventListener('DOMContentLoaded', () => {
alert('DOM fully loaded');
});
</script>
Inline scripts execute immediately, and their placement affects execution timing. Scripts in the <head>
execute as soon as they are parsed, potentially accessing DOM elements that haven't been parsed yet. Scripts placed before </body>
ensure the DOM is fully parsed.
External Script Inclusion
Using the src
attribute to reference external JS files is more common, promoting code reuse and maintainability. Browsers cache external script files, improving page load performance.
<script src="app.js"></script>
<script src="https://cdn.example.com/library.js"></script>
External scripts support cross-origin inclusion, but considerations include CDN resource availability and security. Modern development often uses modular approaches:
<script type="module" src="main.js"></script>
Script Loading Attributes
HTML5 introduced several attributes for <script>
tags to control loading behavior:
async
: Loads the script asynchronously, executing immediately after downloaddefer
: Defers execution until after document parsing, maintaining ordernomodule
: Fallback for browsers that don't support ES modules
<script src="analytics.js" async></script>
<script src="vendor.js" defer></script>
<script nomodule src="fallback.js"></script>
Common use case comparisons:
- Critical path scripts: No
async
/defer
, placed before</body>
- Analytics code: Use
async
to avoid render blocking - Dependency libraries: Use
defer
to ensure execution order
Dynamic Script Loading
Dynamically creating and inserting script elements allows for more flexible loading control:
const script = document.createElement('script');
script.src = 'dynamic.js';
script.onload = () => console.log('Script loaded');
document.head.appendChild(script);
Dynamic loading is often used for:
- On-demand loading of non-core features
- Conditional polyfill loading
- Implementing script queue management
function loadScript(url, callback) {
const script = document.createElement('script');
script.src = url;
script.onload = callback;
document.body.appendChild(script);
}
loadScript('first.js', () => {
loadScript('second.js', initApp);
});
Modular Scripts
The ES6 module system brings true modularity to frontend development:
<script type="module">
import { utils } from './utils.js';
utils.log('Module code');
</script>
Module scripts inherently behave like defer
and support static analysis. Key differences from regular scripts:
- Strict mode by default
- Separate scope
- Top-level
await
support - Cross-origin requests require CORS headers
// utils.js
export const utils = {
log: (msg) => console.log(`[LOG] ${msg}`)
};
Performance Optimization Practices
Script loading strategies directly affect page performance metrics:
- Inline critical scripts: For render-blocking core functionality
<script>
/* Inline critical CSS loading logic */
const loadCSS = (url) => {
const link = document.createElement('link');
link.rel = 'stylesheet';
link.href = url;
document.head.appendChild(link);
};
loadCSS('/css/main.css');
</script>
- Defer non-critical scripts:
<script defer src="lazy.js"></script>
- Preload important resources:
<link rel="preload" href="critical.js" as="script">
- Code splitting with dynamic imports:
button.addEventListener('click', async () => {
const module = await import('./dialog.js');
module.open();
});
Compatibility Handling
Legacy browser considerations include:
- ES5 syntax transformation:
<script src="es5-bundle.js"></script>
<script type="module" src="es6-bundle.js"></script>
- Feature detection for polyfills:
if (!window.Promise) {
document.write('<script src="promise-polyfill.js"><\/script>');
}
- Module fallback for older browsers:
<script type="module" src="app.js"></script>
<script nomodule src="legacy-app.js"></script>
Security Considerations
Script inclusion involves several security aspects:
- Subresource Integrity (SRI) verification:
<script
src="https://example.com/library.js"
integrity="sha384-oqVuAfXRKap7fdgcCY5uykM6+R9GqQ8K/ux..."
crossorigin="anonymous">
</script>
- CSP policies restricting inline scripts:
Content-Security-Policy: script-src 'self' https://trusted.cdn.com
- Avoid
document.write
:
// Avoid using
document.write('<script src="dangerous.js"><\/script>');
- Dynamic script content safety:
// Security risk
const script = document.createElement('script');
script.textContent = userGeneratedContent;
Modern Framework Script Handling
Mainstream frameworks have specialized script handling:
React code splitting:
const LazyComponent = React.lazy(() => import('./LazyComponent'));
Vue async components:
const AsyncComp = () => ({
component: import('./AsyncComp.vue'),
loading: LoadingComp,
error: ErrorComp
});
Webpack dynamic imports generate runtime loading logic:
import(/* webpackChunkName: "chart" */ './charting').then(module => {
// Use module
});
Debugging and Error Handling
Script loading issue debugging techniques:
- Check loading status in the Network panel
- Analyze console error messages
- Use waterfall charts to identify bottlenecks
Error handling patterns:
script.onerror = () => {
console.error('Script load failed');
loadFallbackScript();
};
Performance monitoring:
const start = performance.now();
import('./module.js').then(() => {
const loadTime = performance.now() - start;
reportAnalytics('module_load', loadTime);
});
本站部分内容来自互联网,一切版权均归源网站或源作者所有。
如果侵犯了你的权益请来信告知我们删除。邮箱:cc@cccx.cn