Thành viên:Hide on Rosé/Làm cho user script tải nhanh hơn

Bách khoa toàn thư mở Wikipedia

Bằng sự trợ giúp của bộ nhớ đệm, các tập lệnh người dùng (user script) có thể được tải nhanh hơn. Tuy nhiên, đây chỉ là một thử nghiệm, và hãy cho tác giả của snippet này (SD0001Wikipedia tiếng Anh) biết vấn đề bạn gặp phải tại trang thảo luận.

Thêm snippet ở dạng minified vào đầu trang common.js page:

// Enable caching for resource loads, see [[User:SD0001/Making_user_scripts_load_faster]], @revision 6
if(!/\bnocache=\b/.test(location.href)){let e=(e,t,n)=>(e=e.replace(/special:mypage/i,"User:"+mw.config.get("wgUserName")),$.get("https://"+t+"/w/api.php?titles="+e+"&origin=*&format=json&formatversion=2&uselang=content&maxage=86400&smaxage=86400&action=query&prop=revisions|info&rvprop=content&rvlimit=1").then((r=>{let o=r.query.pages[0];if(o.missing)return;let a=o.revisions[0].content;if(n&&"text/javascript"!==n||"javascript"!==o.contentmodel){if("text/css"!==n||"css"!==o.contentmodel)return $.Deferred().reject('Refused to load "'+e+'"@'+t+": content type mismatch");mw.loader.addStyleTag(a)}else{let e=document.createElement("script");e.innerHTML=a,document.head.appendChild(e)}}))),t=e=>{let t=/^(?:(?:https:)?\/\/(.*))?\/w\/index.php/.exec(e),n=/\btitle=([^=?&]*)/.exec(e);return t&&n&&/\baction=raw\b/.test(e)&&/\bctype=/.test(e)?[n[1],t[1]||mw.config.get("wgServerName")]:null};window.importScript=t=>{e(encodeURIComponent(t),mw.config.get("wgServerName"),"text/javascript")},window.importStyleSheet=t=>{e(encodeURIComponent(t),mw.config.get("wgServerName"),"text/css")};let n=mw.loader.load;mw.loader.load=function(r,o){let a=t(r);a?e(a[0],a[1],o):n.apply(mw.loader,[...arguments])};let r=mw.loader.getScript;mw.loader.getScript=function(n){let o=t(n);return o?e(o[0],o[1],"text/javascript"):r.apply(mw.loader,[...arguments])}}

Nếu bạn không thích một đoạn mã xấu xí và khó hiểu này, thay vào đó, bạn có thể dùng đoạn mã ở dạng đầy đủ và đẹp mắt dưới đây (nhưng đoạn mã này sẽ chiếm rất nhiều dòng):

(Hai snippet ở trên hoạt động giống nhau).

Lưu ý rằng đoạn mã phải ở đầu trang common.js của bạn để nó có hiệu lực.

Snippet này thay thế cách triển khai script trên tài khoản người dùng hiện có của mw.loader.load, mw.loader.getScript, importScriptimportStyleSheet. Snippet không làm thay đổi cách bạn cài đặt user script.

Cải thiện[sửa | sửa mã nguồn]

Bạn có thể xem hiệu quả của snippet bằng cách mở Công cụ Nhà phát triển (DevTools), đi tới thẻ Network mở các trang khác nhau. (Đừng tải lại trang vì trong một số trình duyệt, nó sẽ tải lại cứng (hard reload) và gây ra tình trạng bypassing of cache (bỏ qua bộ nhớ đệm).) Ngoài ra hãy đảm bảo rằng bạn đã bỏ tick "Disable cache" (Tắt bộ nhớ đệm) trong DevTools. Trong Chrome, bạn sẽ thấy rằng hầu hết các lần tìm nạp script được giải quyết bởi chính bộ nhớ đệm trên đĩa, rất nhanh chóng.

Không lưu vào bộ đệm. Mỗi một user script mất 400–500 mili giây để tải. Một script cỡ lớn có thể mất tới 1.11 giây! Tốc độ tải xuống là 50 Mbps.
Đã kích hoạt lưu vào bộ nhớ đệm. Mỗi một tập lệnh chỉ mất tới 1-2 mili giây để tải.

Cẩn trọng[sửa | sửa mã nguồn]

  • Snippet này sẽ làm cho script và bảng định kiểu của bạn được lưu vào bộ đệm trong 1 ngày (86400 giây).
    Nếu có script nào được cập nhật, có thể phải mất tới một ngày để chúng được cập nhật trên máy tính của bạn. Tải cứng có thể xóa bộ nhớ đệm của bạn. Trên trình duyệt Chrome, chỉ cần nhấn nút "Tải lại" trên bất kỳ trang nào sẽ tiến hành tải cứng. Trên các trình duyệt khác, bạn có thể cần phải nhấn Ctrl+F5.

Thông tin kỹ thuật[sửa | sửa mã nguồn]

Đối với hàm loadResource:

  • API sẽ được sử dụng thay vì index.php vì các yêu cầu gửi đến index.php dường như không bao giờ được lưu trữ trong bộ nhớ đệm đối với thành viên đã đăng nhập. Với các tham số lưu trữ của API, phản hồi sẽ nhận được header Cache-Control s-maxage=86400, max-age=86400, public, trong khi header do index.php đặt là private, max-age=0, s-maxage=0.
  • Thuộc tính uselang=content cho phép lưu trữ bộ đệm dùng chung trong Varnish, v.v. Xem phab:T97096. Tuy nhiên, không có bộ đệm dùng chung nào được thực hiện đối với các yêu cầu của người dùng có khả năng xem nội dung đã bị xóa hoặc bị chặn do sửa đổi (tham khảo:[1]).
  • origin=* khiến cho API đặt header là Access-Control-Allow-Origin: * để ngăn ngừa vấn đề CORS khi tải các script từ wiki khác.
  • Kiểu nội dung của một trang sẽ được kiểm tra trước khi mã JS/CSS được thực thi. Các kiểu nội dung không-phải-javascript sẽ không được coi là JS, và việc gọi index.php với ctype=text/javascript đối với trang không được coi là JS sẽ trả về lỗi 403.
  • Sử dụng mw.loader.getScript để tải một trang bị thiếu sẽ trả về resolved promise. Điều này tương tự như việc gọi index.php để tải JS từ một trang không tồn tại và có tiêu đề bị khóa tự động (ví dụ: tiêu đề không gian thành viên có tên kết thúc bằng ".js" hoặc tiêu đề trong không gian tên MediaWiki) trả về response 200.
    • Sử dụng index.php để tải JS từ một trang có tiêu đề không tồn tại và không bị khóa tự động sẽ trả về 403. loadResource() will sẽ trả về resolved promise thay cho index.php.