javascript
javascript
javascript
  • Lấy vị trí người dùng với javascript
  • [Problem] Lấy key đầu tiên tìm thấy chứa giá trị cần tìm (ok)
  • 🥸Đoạn mã JavaScript để thêm ký tự đặc biệt vào đầu mỗi dòng trong văn bản nhiều dòng (ok)
  • 😍Tạo ra font in đậm và copy đến website để sử dụng (ok)
  • Hiệu ứng mở sách cực đẹp
  • 🤩JS: Scroll Animation using Intersection Observer API 🤩 (ok)
  • 😅Draw svg on scroll Full (ok)
  • 😄Install Linguise on any domain dịch tự động (ok)
  • 😅Sử dụng ajax tạo popup cho các bài viết wordrpess mattervn.com (ok)
  • 😆PWA - beforeinstallprompt toplusgames.com (ok)
  • How to Use the HTML5 Full-Screen API (Again) (ok)
  • [ERROR GAME] fix lỗi không load iframe gamedistribution.com for toplusgames.com (ok)
  • 😅jQuery Plugin To Create Animated Placeholders - placeholderTypewriter (ok)
  • 😍Làm chức năng thông báo khách hàng đăng ký namkhoahanoi.vn (ok)
  • Tencent Captcha Demo (ok)
  • 😉Send Mail same javascript elasticemail (ok)
  • 🥳Các tool phong thuỷ (ok)
  • 😇Nice Select A lightweight Vanilla JavaScript plugin (ok)
  • Merge objects with the same id but sum values of the objects (ok)
  • 😅Page: DOMContentLoaded, load, beforeunload, unload phần 1 (ok)
  • 😍Scripts: async, defer phần 2(ok)
  • 😂Javascript Array chunkArrayInGroups(arr, size)
  • Sequentially Resolve Promises Works, Giải quyết tuần tự các lời hứa hoạt động (ok)
  • Using Async / Await with the Array Reduce Method API (ok)
  • Flatten an array of arrays,merge, làm phẳng một mảng các mảng (ok)
  • 😌Dependent Dropdown Full (ok)
  • 🥳Select Box Change Dependent Options dynamically (JavaScript Object)
  • 🤩Add elements dynamically full (ok)
  • 😅👌Multiple versions jquery (ok)
  • 😍Cách sử dụng jQuery trong sweetAlert2 là chúng ta phải sử dụng didOpen full (ok)
  • 😁😁 mdbgo.io, mdbootstrap.com full (ok)
  • 🤪Chú ý nếu lỗi cảnh báo từ khóa new nếu dùng trong js thường chúng ta sẽ sử dụng trong mudule (ok)
  • 😝reCAPTCHA javascript (ok)
  • Firework Simulator v2 Phao Hoa (ok)
  • Active scroll center (ok)
  • 🤪Sort array of objects by string property value (ok)
  • 😏findIndex, find index in Array object (ok)
  • 😂Sử dụng nhiều toán tử 3, multiple Ternary Operators (ok)
  • 😅A simple and easy to use library that creates fullscreen scrolling websites fullPage.js (ok)
  • Xây dựng ứng dụng CRUD sử dụng Vue.js trong Laravel (ok)
  • [Chart] Morris.js Line & Area Charts,Bar Charts, Donut Charts, graph (ok)
  • [Chart] Chart.js
  • Multi select checkbox table bootstrap (ok)
  • 😀jquery new, jquery old, jquery migrate (ok)
  • Popup slide up from the bottom overflowing other div blocks (ok)
  • ASYNC JavaScript (CALLBACK, PROMISES, ASYNC AWAIT) video (ok)
  • === START jQuery Mobile ===
  • Data Attributes full (ok)
  • Viết một ứng dụng Restaurant Picke sử dụng "back menu" (ok)
  • Viết một ứng dụng thời tiết, Weather sử dụng panel (ok)
  • jQuery Mobile Tutorial w3schools.com (ok)
  • jQuery Mobile
  • jQuery Mobile - Events (ok)
  • Back button in jquery mobile (ok)
  • === END jQuery Mobile ===
  • removeDuplicates, Remove duplicate values from JS array, remove all duplicates an array object (ok)
  • Sử dụng thư viện jquery.hoverdir.js để làm hiệu ứng hover tuyệt đẹp (ok)
  • Modernizr là gì ? Sử dụng nó cho những trình duyệt cũ ra sao? (ok)
  • Nhận biết tính năng CSS: Modernizr hay Feature Queries? (ok)
  • [SALESFORCE] Remote Action function in Visualforce Page (ok)
  • ScrollIt.js menu (ok)
  • Cách sử dụng scrollTo vanilla cực chất 😘 (ok)
  • Một bài toán xử lý bất đồng bộ trong kintone để lấy số requet quá giới hạn (OK)
  • hexagon thư viện tạo avatar Canvas (ok)
  • 😅Sử dụng Object.assign và để copy dữ liệu, edit, input, form (ok)
  • Một cách đặt và gán giá trị trong mảng, object cự ngắn gọn (ok)
  • [LAZY] jQuery.Lazy và tạo background-loading cực chất (ok)
  • Ví dụ Sử dụng sẵn thư viện masonry của wordpres (ok)
  • Ảnh base64 dùng làm src, placeholder (ok)
  • Kiểm tra hình ảnh đã được tải với thư viện imagesLoaded (ok)
  • Check if Function Exists before Calling? (ok)
  • Async/Await Javascript Full Example (ok)
  • Thenables in JavaScript phục vụ cho bài viết trên (ok)
  • Script distance, khoảng cách (ok)
  • Time, Date full (ok)
  • Function getAllDatesOfMonth (ok)
  • How do I make a placeholder for a 'select' box? (ok)
  • Library choise (ok)
  • jQuery - Redirect with post, Get data php (ok)
  • How to pass data from one page to another page html (ok)
  • how to send data onClick() to another php for processing using post or get?
  • draw grid, vẽ grid (ok)
  • Fullscreen Horizontal Page Slider with jQuery and CSS3 - HSlider scroll template html (ok)
  • _.template, UnderscoreJS Templates Full (ok)
  • Character limit on tag type input number (ok)
  • How to set maximum length in input type=number (ok)
  • ========= START JEST =======
  • Getting Started (ok)
  • Using Matchers (ok)
  • Testing Asynchronous Code
  • Setup and Teardown (ok)
  • Mock Functions
  • Jest Platform
  • Jest tutorial
  • Testing trong Javascript với Jest (Phần 1) (ok)
  • Testing trong Javascript với Jest (Phần 2)
  • Giới thiệu về Jest (Delightful JavaScript Testing)
  • Thử nghiệm phát triển theo hướng phản ứng với Jest và Enzyme
  • Cách kiểm tra các thành phần phản ứng với Jest và Enzyme, Phần 1
  • Cách kiểm tra thành phần phản ứng với Jest và Enzyme, Phần 2
  • Jest js mock jquey and lib
  • Unit testing Các thành phần React với Enzyme và Jest
  • Hướng dẫn viết unit test React với Jest và Enzyme (P1)
  • Tôi đã test các React component như thế nào? (phần 2)
  • Test component trong React với Jest
  • Test Component với Jest và Emzyme
  • Tổng quan về unit test cho dự án react redux saga với Jest Part 1
  • ========= END JEST =======
  • ======= START GULP TUTORIAL ======
  • [GULP] Tìm hiểu về Gulp.js
  • [GULP] Gulp Tutorial
  • [GULP] Gulp - Developing An Application (ok)
  • [GULP] Gulp - Combining Tasks (ok)
  • [GULP] Gulp - Watch (ok)
  • [GULP] Gulp - Live Reload
  • [GULP] Gulp - Optimizing CSS and JavaScript
  • [GULP] Gulp - Optimizing Images
  • [GULP] Gulp - Useful Plugins
  • [GULP] Gulp - Cleaning Unwanted Files
  • Đọc thêm những tài liệu trang khác
  • ======= END GULP TUTORIAL ======
  • Prevent form submission on Enter key press, keyCode (ok)
  • Lấy kích thước ảnh gốc image (ok)
  • 😆How to Center Carousel Slider (ok)
  • Putting Dots onto Owl Carousel Instead of below specialtouchgifts.com.au (ok)
  • Cách xây dựng một Full Screen Carousel với Owl.js
  • Lazy load với owl.carousel.js (ok)
  • Show half of the other item on Owl Carousel vinmec.com items: 1.5 (ok)
  • Show half of the other item on Owl Carousel vinmec.com stagePadding (ok)
  • ------------ Start Fetch -----------
  • Using Fetch Full
  • 😅Javascript Fetch JSON PHP Complete FormData phần 1(ok)
  • Một ví dụ quá đỉnh lấy dữ liệu của form submit trong js bằng đối tượng new FormData + php phần 2(ok)
  • Có một sự thật sử dụng async đồng nghĩa với trả về kết quả là PROMISE (ok)
  • 😅Promise.all full (ok)
  • All you need to know about Promise.all
  • [PROMISE] Promise.all()
  • [PROMISE] Tìm hiểu về promise trong ES6
  • [PROMISE] Introduction to Promises
  • jQuery off() Method (ok)
  • How to make HTTP requests with Axios
  • Axios vs Fetch - 2020 nên sử dụng thằng nào với những tính năng mới trong javascript
  • Get and Post method using Fetch API (ok)
  • Sử dụng JavaScript Fetch API với Async/Await (ok)
  • Xử lý lỗi cho fetch trong trường hợp không có kết nối hoặc kết nối lâu (ok)
  • ------------ End Fetch -----------
  • BigDataCloud Free Reverse Geocoding Javascript API Client (ok)
  • Vietmap API
  • 🥰Sử dụng API Giao hàng Nhanh để tính giá cước vận chuyển (ok)
  • photonsearch as you type with OpenStreetMap map (ok)
  • Leaflet - Một thư viện JS mã nguồn mở cho việc xây dụng ứng dụng bản đồ map (ok)
  • Xây dựng popup lấy vị trí map áp dụng pointfinder (ok)
  • Reverse Geocoding Convert Lat Long to Address map (ok)
  • Free Reverse Geocoding Javascript API map (ok)
  • [YAML] In Action Tutorial Series - General - Hướng dẫn sử dụng file YML YAML cơ bản
  • ----------------- Start Notification -----------------
  • Đối tượng caches object caches (ok)
  • Notification (ok)
  • Sử dụng indexedDB (ok)
  • Using the Notifications API (ok)
  • NotificationEvent (chưa có ví dụ :((
  • ServiceWorkerGlobalScope.onnotificationclick (ok)
  • ServiceWorkerRegistration.getNotifications(ok)
  • ServiceWorkerRegistration.showNotification(ok)
  • Giao tiếp giữa các cửa sổ với Window.postMessage API (ok)
  • Window open() Method (ok)
  • ----------------- End Notification -----------------
  • Example Cookie full (ok)
  • Thay đổi class active javascript bằng cách viết hàm (P1)
  • Thay đổi class active javascript bằng cách viết hàm (P2)
  • jQuery Mockjax Plugin (chưa học cách sử dụng)
  • jQuery Ajax X-editable bootstrap plugin (chưa học cách sử dụng)
  • Lọc theo điều kiện (filter) (ok)
  • Các ví dụ về filter
  • jQuery | grep() Method (ok)
  • Hai bài toán so sánh kinh điển trong javascript
  • Function random :)
  • Một cách sử dụng tab trong theme newspaper
  • Hiệu ứng scroll + animation + menu trượt mượt
  • Trigger a CSS animation on scroll xuongkhopbacninh.vn (ok)
  • App Css Loaded (scroll create link) (ok)
  • Hiệu tứng scroll cực chất (ok)
  • App Js Loaded (ok)
  • Sử dụng async và defer full (Oke)
  • Cách sử dụng Thuộc tính async và defer trong JavaScript hay
  • ReferenceError: Can't find variable: requestAnimationFrame
  • Đoạn code check lỗi PHP trong Ajax
  • [SELECT2] Sử dụng Select2 để thay thế select boxes
  • Một cách sử dụng lazyload khi addclass thật khó khăn...
  • Hiệu ứng croll chuột và % cực đẹp :_
  • Tạo chức năng tự động hoàn tất nhập liệu với thư viện jQuery UI Autocomplete (Phần 1)
  • Tạo chức năng tự động hoàn tất nhập liệu với thư viện jQuery UI Autocomplete (Phần 2)
  • JavaScript String split() Method (OK)
  • Sử dụng thư viện displace để làm menu kéo thả (ok):)))
  • Menu cực chất :)))
  • Sử dụng thư viện slick (ok)
  • vertical scroll, Vertical carousel (ok)
  • Google-like Thanos disintegration (ok)
  • Dùng thư viện jspdf
  • Công thức Toán học cho website
  • Fix lỗi tự động làm thay đổi độ cao :( vieclam123.vn :(
  • Sử dụng window.addEventListener để resize và responsive <3
  • Javascript create, read, and delete cookies (ok)
  • Tự động submit bằng javscript :))) (ok)
  • avoid form warning if user clicks refresh (ok)
  • Một cách truy cập phần tử bằng js thông qua id lạ :)))
  • Meta Refresh
  • Truyền dữ liệu từ javascript sang php
    • Sử dụng form để truyền sang php (ok)
    • Truyền giá trị theo file bằng đường dẫn (ok)
    • Dùng json để truyền sang php
  • auto-refresh page once only after first load – Using JavaScript / JQuery
    • auto-refresh page once only after first load – Using JavaScript / JQuery (ok)
  • Sticky Scroller
    • Sticky Scroller phần 1 (ok)
    • Sticky Scroller phần 2 (ok)
    • owl carousel with dotsContainer (Dots + Text) (ok)
    • Owl Carousel 2 Thumbnails plugin (ok)
  • easy_background Background Slideshow (ok) dev.vieclam123.vn
  • scroll cực chất timviec365.vn, vieclam123.vn (ok)
  • Thư viện lightslider-master gần giống với Owl Carousel
  • Thư viện lightGallery để làm những bộ Sưu tập Gallery
  • Tự viết click slide (ok)
  • Draggable & Touch-friendly Slider Carousel In Pure JS (ok)
  • Slider owl được viết dưới dạng Thumnail (0k)
  • jquery.js:5092 [Violation] Added non-passive event listener to a scroll-blocking 'touchstart' (ok)
  • Added non-passive event listener to a scroll-blocking 'touchstart' event (ok)
  • sticky-mobile-menu-burger-menu (ok)
  • How can I add class to the first and last item among the visible items of Owl Carousel 2? (ok)
  • Owl-carousel2 DEMO - items in 2 rows (oke)
  • How can I create a carousel slick with multiple rows? (ok)
  • Một cách sử dụng create <style> để thêm style (ok)
  • Two Rows Olw Carousel (ok) vieclam123.vn
  • Chức năng tự gọi Javascript (ok) tự động auto
  • Click Next Javascript Base (ok)
  • Slider owl được viết dưới dạng Thumnail viết trên jsfiddle (0k)
  • 😆Creating a Countdown Timer, dakhoathienhoa.com.vn (oK)
  • 🥸NumScroller, Counter From Zero To Value - Javascript Animation (ok)
  • Click Button background-hover white (ok)
  • CodePen HomeLazy Loading Images (Ok)
  • Custom Date Javasript (job247.vn)
  • Tooltip
  • button thay đổi thẻ tags button và span trong Owl Carousel thành thẻ khác :)) (ok)
  • Thêm class vào navigation Owl Carousel (ok)
  • Click lần đầu sử event.preventDefault(); lầu sau not event.preventDefault();
  • landscape && landscape (ok)
  • Landscape && Portrait (ok) job247.vn
  • Hammer thư viện JavaScript chạm cho màn hình cảm ứng
  • jQuery Plugin To Add CSS3 Scrolling Effects On Your Web Page - Smoove menu (ok)
  • 😃Auto Expanding Table Of Contents Plugin - Dynamic Content menu (ok)
  • Tornis - watch and respond
  • scroll-manager
  • Xem thêm
  • Hướng dẫn nấu món "Lazy loading image" theo chuẩn 5 sao Google
  • Welcome to jquery-confirm!
    • jQuery Message Box Plugin Demo Page
  • Magnific-Popup Popup img
  • Slider Swiper Slider-Swiper dùng viết slider giống app
  • Magnific Popup Documentation
  • filter search (ok)
  • Is it possible to convert a select menu to buttons? (ok)
  • Changing selected option on button click select (ok) homef.vn hoặc inop.vyanh.net
  • scrooll animation (job247.vn) (ok)
  • Select2 tutorial
    • Single select boxes (ok)
  • [SELECT2] Disabling a Select2 control (ok)
  • Disabling options (ok)
  • placeholder (ok)
  • Hiển thị nút xóa các giá trị đã chọn + allowClear (ok)
  • Đọc dữ liệu từ một mảng, Data sources (ok)
  • Sử dụng database + php (ok)
  • [SELECT2] Sử dụng form + select2 + ajax + get value (ok)
  • Đọc dữ liệu từ nguồn khác sử dụng AJAX (ok)
  • Thiết lập giá trị mặc định ban đầu trên HTML như bình thường (ok)
  • Sử dụng Ajax để tải dữ liệu từ một nguồn khác (ok)
  • change form
Powered by GitBook
On this page
  • defer
  • Thuộc tính defer chỉ dành cho các tập lệnh bên ngoài, Thuộc tính defer bị bỏ qua nếu thẻ không có src.
  • async
  • Scripts: async, defer
  • defer
  • Summary
  • async
  • Dynamic scripts
  • Summary

Was this helpful?

Scripts: async, defer phần 2(ok)

https://javascript.info/script-async-defer

PreviousPage: DOMContentLoaded, load, beforeunload, unload phần 1 (ok)NextJavascript Array chunkArrayInGroups(arr, size)

Last updated 2 years ago

Was this helpful?

Trong các trang web hiện đại, các tập lệnh thường “nặng” hơn HTML: kích thước tải xuống của chúng lớn hơn và thời gian xử lý cũng lâu hơn.

Khi trình duyệt tải HTML và bắt gặp thẻ ..., trình duyệt không thể tiếp tục xây dựng DOM. Nó phải thực thi tập lệnh ngay bây giờ. Điều tương tự cũng xảy ra đối với tập lệnh bên ngoài : trình duyệt phải đợi tập lệnh tải xuống, thực thi tập lệnh đã tải xuống và chỉ sau đó trình duyệt mới có thể xử lý phần còn lại của trang.

Điều đó dẫn đến hai vấn đề quan trọng:

  1. Tập lệnh không thể nhìn thấy các phần tử DOM bên dưới chúng, vì vậy chúng không thể thêm trình xử lý, v.v.

  2. Nếu có một tập lệnh cồng kềnh ở đầu trang, thì tập lệnh đó sẽ "chặn trang". Người dùng không thể xem nội dung trang cho đến khi nó tải xuống và chạy:

<p>...content before script...</p>
<script src="https://javascript.info/article/script-async-defer/long.js?speed=1"></script>
<!-- This isn't visible until the script loads -->
<p>...content after script...</p>

Có một số cách giải quyết cho điều đó. Chẳng hạn, chúng ta có thể đặt một đoạn script ở cuối trang. Sau đó, nó có thể nhìn thấy các phần tử phía trên nó và nó không chặn nội dung trang hiển thị:

<body>
  ...all content is above the script...
  <script src="https://javascript.info/article/script-async-defer/long.js?speed=1"></script>
</body>

Nhưng giải pháp này là xa. Ví dụ: trình duyệt chỉ nhận thấy tập lệnh (và có thể bắt đầu tải xuống) sau khi đã tải xuống toàn bộ tài liệu HTML. Đối với các tài liệu HTML dài, đó có thể là một độ trễ đáng chú ý.

Những thứ như vậy là vô hình đối với những người sử dụng kết nối rất nhanh, nhưng nhiều người trên thế giới vẫn có tốc độ internet chậm và sử dụng kết nối internet di động không hoàn hảo.

May mắn thay, có hai thuộc tính giải quyết vấn đề cho chúng ta: defer và async.

Thuộc tính defer yêu cầu trình duyệt không đợi tập lệnh. Thay vào đó, trình duyệt sẽ tiếp tục xử lý HTML, xây dựng DOM. Tập lệnh tải "trong nền" và sau đó chạy khi DOM được tạo hoàn chỉnh.

Đây là ví dụ tương tự như trên, nhưng với defer:

<p>...content before script...</p>

<script defer src="https://javascript.info/article/script-async-defer/long.js?speed=1"></script>

<!-- visible immediately -->
<p>...content after script...</p>

Nói cách khác:

  • Scripts with defer never block the page.

  • Scripts with defer always execute when the DOM is ready (but before DOMContentLoaded event).

Ví dụ sau minh họa phần thứ hai:

<p>...content before scripts...</p>

<script>
  document.addEventListener('DOMContentLoaded', () => alert("DOM ready after defer!"));
</script>

<script defer src="https://javascript.info/article/script-async-defer/long.js?speed=1"></script>

<p>...content after scripts...</p>

Nội dung trang hiển thị ngay lập tức.

Trình xử lý sự kiện DOMContentLoaded chờ tập lệnh bị trì hoãn. Nó chỉ kích hoạt khi tập lệnh được tải xuống và thực thi.

Các tập lệnh bị trì hoãn giữ thứ tự tương đối của chúng, giống như các tập lệnh thông thường.

Giả sử, chúng ta có hai tập lệnh bị trì hoãn: long.js và sau đó là small.js:

<script defer src="https://javascript.info/article/script-async-defer/long.js"></script>
<script defer src="https://javascript.info/article/script-async-defer/small.js"></script>

Trình duyệt quét trang để tìm tập lệnh và tải xuống song song để cải thiện hiệu suất. Vì vậy, trong ví dụ trên, cả hai tập lệnh đều tải xuống song song. Small.js có thể kết thúc trước.

…Nhưng thuộc tính defer, bên cạnh việc yêu cầu trình duyệt “không chặn”, đảm bảo rằng thứ tự tương đối được giữ nguyên. Vì vậy, mặc dù small.js tải trước nhưng nó vẫn chờ và chạy sau khi long.js thực thi.

Điều đó có thể quan trọng đối với các trường hợp khi chúng ta cần tải một thư viện JavaScript và sau đó là một tập lệnh phụ thuộc vào nó.

Thuộc tính defer chỉ dành cho các tập lệnh bên ngoài, Thuộc tính defer bị bỏ qua nếu thẻ không có src.

Thuộc tính async giống như defer. Nó cũng làm cho tập lệnh không bị chặn. Nhưng nó có sự khác biệt quan trọng trong hành vi.

Thuộc tính async có nghĩa là tập lệnh hoàn toàn độc lập:

  • The browser doesn’t block on async scripts (like defer).

  • Other scripts don’t wait for async scripts, and async scripts don’t wait for them.

Điều này có thể được thay đổi nếu chúng ta đặt script.async=false một cách rõ ràng. Sau đó, các tập lệnh sẽ được thực thi theo thứ tự tài liệu, giống như trì hoãn.

In this example, loadScript(src) function adds a script and also sets async to false.

So long.js always runs first (as it’s added first):

Nếu không có script.async=false, các tập lệnh sẽ thực thi theo mặc định, thứ tự tải đầu tiên (có thể là small.js trước).

Scripts: async, defer

In modern websites, scripts are often “heavier” than HTML: their download size is larger, and processing time is also longer.

When the browser loads HTML and comes across a <script>...</script> tag, it can’t continue building the DOM. It must execute the script right now. The same happens for external scripts <script src="..."></script>: the browser must wait for the script to download, execute the downloaded script, and only then can it process the rest of the page.

That leads to two important issues:

  1. Scripts can’t see DOM elements below them, so they can’t add handlers etc.

  2. If there’s a bulky script at the top of the page, it “blocks the page”. Users can’t see the page content till it downloads and runs:

<p>...content before script...</p>

<script src="https://javascript.info/article/script-async-defer/long.js?speed=1"></script>

<!-- This isn't visible until the script loads -->
<p>...content after script...</p>

There are some workarounds to that. For instance, we can put a script at the bottom of the page. Then it can see elements above it, and it doesn’t block the page content from showing:

<body>
  ...all content is above the script...

  <script src="https://javascript.info/article/script-async-defer/long.js?speed=1"></script>
</body>

But this solution is far from perfect. For example, the browser notices the script (and can start downloading it) only after it downloaded the full HTML document. For long HTML documents, that may be a noticeable delay.

Such things are invisible for people using very fast connections, but many people in the world still have slow internet speeds and use a far-from-perfect mobile internet connection.

Luckily, there are two <script> attributes that solve the problem for us: defer and async.

The defer attribute tells the browser not to wait for the script. Instead, the browser will continue to process the HTML, build DOM. The script loads “in the background”, and then runs when the DOM is fully built.

Here’s the same example as above, but with defer:

<p>...content before script...</p>

<script defer src="https://javascript.info/article/script-async-defer/long.js?speed=1"></script>

<!-- visible immediately -->
<p>...content after script...</p>

In other words:

  • Scripts with defer never block the page.

  • Scripts with defer always execute when the DOM is ready (but before DOMContentLoaded event).

The following example demonstrates the second part:

<p>...content before scripts...</p>

<script>
  document.addEventListener('DOMContentLoaded', () => alert("DOM ready after defer!"));
</script>

<script defer src="https://javascript.info/article/script-async-defer/long.js?speed=1"></script>

<p>...content after scripts...</p>
  1. The page content shows up immediately.

  2. DOMContentLoaded event handler waits for the deferred script. It only triggers when the script is downloaded and executed.

Deferred scripts keep their relative order, just like regular scripts.

Let’s say, we have two deferred scripts: the long.js and then small.js:

<script defer src="https://javascript.info/article/script-async-defer/long.js"></script>
<script defer src="https://javascript.info/article/script-async-defer/small.js"></script>

Cả async và defer đều có một điểm chung: việc tải xuống các tập lệnh như vậy không chặn hiển thị trang. Vì vậy, người dùng có thể đọc nội dung trang và làm quen với trang ngay lập tức.

Nhưng cũng có những khác biệt cơ bản giữa chúng:

Order
DOMContentLoaded

async

Thứ tự tài liệu của họ không thành vấn đề – cái nào tải trước sẽ chạy trước

không liên quan. Có thể tải và thực thi khi tài liệu chưa được tải xuống đầy đủ. Điều đó xảy ra nếu tập lệnh nhỏ hoặc được lưu trong bộ nhớ cache và tài liệu đủ dài.

defer

Document order (khi chúng đi vào tài liệu).

Thực thi sau khi tài liệu được tải và phân tích cú pháp (chúng đợi nếu cần), ngay trước DOMContentLoaded.

Trong thực tế, defer được sử dụng cho các tập lệnh cần toàn bộ DOM và/hoặc thứ tự thực thi tương đối của chúng là quan trọng.

Và async được sử dụng cho các tập lệnh độc lập, như bộ đếm hoặc quảng cáo. Và thứ tự thực hiện tương đối của họ không thành vấn đề.

Đừng quên đặt chỉ báo "loading" và tắt các nút chưa hoạt động. Hãy để người dùng thấy rõ những gì họ có thể làm trên trang và những gì vẫn chưa sẵn sàng.

Browsers scan the page for scripts and download them in parallel, to improve performance. So in the example above both scripts download in parallel. The small.js probably finishes first.

…But the defer attribute, besides telling the browser “not to block”, ensures that the relative order is kept. So even though small.js loads first, it still waits and runs after long.js executes.

That may be important for cases when we need to load a JavaScript library and then a script that depends on it.

The defer attribute is only for external scripts

The defer attribute is ignored if the <script> tag has no src.

The async attribute is somewhat like defer. It also makes the script non-blocking. But it has important differences in the behavior.

The async attribute means that a script is completely independent:

  • The browser doesn’t block on async scripts (like defer).

  • Other scripts don’t wait for async scripts, and async scripts don’t wait for them.

  • DOMContentLoaded and async scripts don’t wait for each other:

    • DOMContentLoaded may happen both before an async script (if an async script finishes loading after the page is complete)

    • …or after an async script (if an async script is short or was in HTTP-cache)

In other words, async scripts load in the background and run when ready. The DOM and other scripts don’t wait for them, and they don’t wait for anything. A fully independent script that runs when loaded. As simple, as it can get, right?

Here’s an example similar to what we’ve seen with defer: two scripts long.js and small.js, but now with async instead of defer.

They don’t wait for each other. Whatever loads first (probably small.js) – runs first:

<p>...content before scripts...</p>

<script>
  document.addEventListener('DOMContentLoaded', () => alert("DOM ready!"));
</script>

<script async src="https://javascript.info/article/script-async-defer/long.js"></script>
<script async src="https://javascript.info/article/script-async-defer/small.js"></script>

<p>...content after scripts...</p>
  • The page content shows up immediately: async doesn’t block it.

  • DOMContentLoaded may happen both before and after async, no guarantees here.

  • A smaller script small.js goes second, but probably loads before long.js, so small.js runs first. Although, it might be that long.js loads first, if cached, then it runs first. In other words, async scripts run in the “load-first” order.

Async scripts are great when we integrate an independent third-party script into the page: counters, ads and so on, as they don’t depend on our scripts, and our scripts shouldn’t wait for them:

<!-- Google Analytics is usually added like this -->
<script async src="https://google-analytics.com/analytics.js"></script>

The async attribute is only for external scripts

Just like defer, the async attribute is ignored if the <script> tag has no src.

There’s one more important way of adding a script to the page.

We can create a script and append it to the document dynamically using JavaScript:

let script = document.createElement('script');
script.src = "/article/script-async-defer/long.js";
document.body.append(script); // (*)

The script starts loading as soon as it’s appended to the document (*).

Dynamic scripts behave as “async” by default.

That is:

  • They don’t wait for anything, nothing waits for them.

  • The script that loads first – runs first (“load-first” order).

This can be changed if we explicitly set script.async=false. Then scripts will be executed in the document order, just like defer.

In this example, loadScript(src) function adds a script and also sets async to false.

So long.js always runs first (as it’s added first):

function loadScript(src) {
  let script = document.createElement('script');
  script.src = src;
  script.async = false;
  document.body.append(script);
}

// long.js runs first because of async=false
loadScript("/article/script-async-defer/long.js");
loadScript("/article/script-async-defer/small.js");

Without script.async=false, scripts would execute in default, load-first order (the small.js probably first).

Again, as with the defer, the order matters if we’d like to load a library and then another script that depends on it.

Both async and defer have one common thing: downloading of such scripts doesn’t block page rendering. So the user can read page content and get acquainted with the page immediately.

But there are also essential differences between them:

Order

DOMContentLoaded

async

Load-first order. Their document order doesn’t matter – which loads first runs first

Irrelevant. May load and execute while the document has not yet been fully downloaded. That happens if scripts are small or cached, and the document is long enough.

defer

Document order (as they go in the document).

Execute after the document is loaded and parsed (they wait if needed), right before DOMContentLoaded.

In practice, defer is used for scripts that need the whole DOM and/or their relative execution order is important.

And async is used for independent scripts, like counters or ads. And their relative execution order does not matter.

Page without scripts should be usable

Please note: if you’re using defer or async, then user will see the page before the script loads.

In such case, some graphical components are probably not initialized yet.

Don’t forget to put “loading” indication and disable buttons that aren’t functional yet. Let the user clearly see what he can do on the page, and what’s still getting ready.

😍
defer
async
defer
Summary
async
Dynamic scripts
Summary