CSS Asynchronously कैसे लोड करें


94

मैं 2 सीएसएस फ़ाइलों को खत्म करने की कोशिश कर रहा हूं जो मेरी साइट पर ब्लॉकिंग रेंडर कर रहे हैं - वे Google पेज स्पीड इनसाइट्स पर दिखाई देते हैं। मैंने विभिन्न तरीकों का पालन किया है, जिनमें से कोई भी सफल नहीं था। लेकिन, हाल ही में, मुझे Async के बारे में एक पोस्ट मिली और जब मैंने इस कोड को लागू किया: <script async src="https://third-party.com/resource.js"></script>तो इसने समस्या को खत्म कर दिया।

हालांकि, प्रकाशन के बाद, पेज ने स्टाइल खो दिया। मुझे यकीन नहीं है कि क्या हो रहा है क्योंकि कोड काम करता है लेकिन अपलोड होने के बाद यह स्टाइल है जो काम नहीं करता है। इसके साथ आपकी मदद की सराहना करेंगे। धन्यवाद


2
क्या आप एसिंक्स को स्टाइल या स्क्रिप्ट पर लागू कर रहे हैं? पृष्ठ लोड करने के कुछ समय बाद शैली लोड होती है या यह कभी प्रकट नहीं होती है?
कमस

मैंने शैलियों में एसिंक्स विशेषता लागू की और उन्हें हेडर में रखा।
पॉलिना 994

2
शैलियों के साथ बात यह है कि यदि आप उन्हें देर से लोड करते हैं (जैसे शरीर में), तो पुन: रेंडरिंग चालू हो जाएगा, और मानकों में अनुमति नहीं है (लेकिन चूंकि ब्राउज़र बहुत क्षमा कर रहे हैं, यह वैसे भी काम करेगा)। यदि समस्या तीसरे पक्ष के सर्वर से धीमी प्रतिक्रिया समय है, तो शायद आप उन्हें केवल अपने सर्वर पर होस्ट कर सकते हैं?
जोसेफ एन्गेलफ्रॉस्ट

जवाबों:


131

एक अतुल्यकालिक स्टाइलशीट डाउनलोड को ट्रिगर करने की चाल एक <link>तत्व का उपयोग करना है और मीडिया विशेषता के लिए एक अमान्य मान सेट करना है (मैं मीडिया का उपयोग कर रहा हूं = "कोई नहीं", लेकिन कोई भी मूल्य करेगा)। जब कोई मीडिया क्वेरी झूठी का मूल्यांकन करती है, तो ब्राउज़र अभी भी स्टाइलशीट डाउनलोड करेगा, लेकिन यह पेज रेंडर करने से पहले सामग्री के उपलब्ध होने का इंतजार नहीं करेगा।

<link rel="stylesheet" href="css.css" media="none">

एक बार स्टाइलशीट डाउनलोड करने के बाद मीडिया विशेषता को एक वैध मान पर सेट किया जाना चाहिए ताकि शैली के नियम दस्तावेज़ पर लागू हो जाएं। ऑनलोड ईवेंट का उपयोग मीडिया की संपत्ति को सभी में बदलने के लिए किया जाता है:

<link rel="stylesheet" href="css.css" media="none" onload="if(media!='all')media='all'">

CSS को लोड करने की यह विधि आगंतुकों को मानक दृष्टिकोण की तुलना में बहुत जल्दी उपयोग करने योग्य सामग्री प्रदान करेगी। क्रिटिकल सीएसएस अभी भी सामान्य अवरुद्ध दृष्टिकोण के साथ परोसा जा सकता है (या आप इसे अंतिम प्रदर्शन के लिए इनलाइन कर सकते हैं) और गैर-महत्वपूर्ण शैलियों को पार्सिंग / रेंडरिंग प्रक्रिया में उत्तरोत्तर डाउनलोड और लागू किया जा सकता है।

यह तकनीक जावास्क्रिप्ट का उपयोग करती है, लेकिन आप <link>किसी <noscript>तत्व में समतुल्य अवरोधक तत्वों को लपेटकर गैर-जावास्क्रिप्ट ब्राउज़रों को पूरा कर सकते हैं :

<link rel="stylesheet" href="css.css" media="none" onload="if(media!='all')media='all'"><noscript><link rel="stylesheet" href="css.css"></noscript>

आप www.itcha.edu.sv में ऑपरेशन देख सकते हैं

यहां छवि विवरण दर्ज करें

में स्रोत http://keithclark.co.uk/


ठीक है .. मुझे नहीं पता था कि आप केवल अपने नाम का उल्लेख करके ऑन-हैंडलर में तत्व विशेषताओं को संदर्भित कर सकते हैं। मैंने हमेशा सोचा था कि 'घटना' एकमात्र अपवाद है।
तेमोह

1
तो आप अपने पेज को चमकती से कैसे रखें क्योंकि यह सब कुछ रेंडर करता है? इसके अलावा आप कोर ऐप शैल शैलियों को इनलाइन करते हैं ताकि आपके पेज में कुछ लिंक्स को प्रस्तुत करने के बजाय कुछ प्रारंभिक लेआउट हो, जिस पर लिंक्स को गर्व होगा?
क्रिस लव

2
अभी भी मेरे लिए काम करने लगता है। ऐसा करने के बाद मुझे पता है कि इस फाइल के लिए पेजस्पीड इनसाइट्स में एक चेतावनी दी गई है।
एंडीवेरेन

3
यह मेरे लिए (08-जुलाई -2018) काम कर रहा है। और पेजस्पेड अंतर्दृष्टि में यह अच्छा स्कोर दे रहा है
abilash एर

1
IMHO, "प्री-लोड" का उपयोग करते हुए , जबाचेता का नया उत्तर , संभवतः अब पसंदीदा समाधान है। यदि किसी के पास यह जवाब सोचने के लिए एक कारण है , तो अभी भी बेहतर है, कृपया एक टिप्पणी जोड़ें, जिसमें बताया गया है कि क्यों। आदर्श रूप से एक संसाधन से जोड़ना जो पुष्टि करता है कि क्यों / जब यह दृष्टिकोण अभी भी बेहतर हो सकता है। [मान लें कि आप preloadफ़ायरफ़ॉक्स और पुराने ब्राउज़रों पर समर्थन के लिए पॉलीफ़िल का उपयोग करते हैं - उस उत्तर की पहली टिप्पणी में लिंक देखें]।
टूलमेकरसेव

118

2020 अद्यतन


सरल उत्तर (पूर्ण ब्राउज़र समर्थन):

<link rel="stylesheet" href="style.css" media="print" onload="this.media='all'">

प्रलेखित उत्तर (वैकल्पिक प्रीलोडिंग और स्क्रिप्ट-अक्षम फ़ॉलबैक के साथ):

 <!-- Optional, if we want the stylesheet to get preloaded. Note that this line causes stylesheet to get downloaded, but not applied to the page. Use strategically — while preloading will push this resource up the priority list, it may cause more important resources to be pushed down the priority list. This may not be the desired effect for non-critical CSS, depending on other resources your app needs. -->
 <link rel="preload" href="style.css" as="style">

 <!-- Media type (print) doesn't match the current environment, so browser decides it's not that important and loads the stylesheet asynchronously (without delaying page rendering). On load, we change media type so that the stylesheet gets applied to screens. -->
 <link rel="stylesheet" href="style.css" media="print" onload="this.media='all'">

 <!-- Fallback that only gets inserted when JavaScript is disabled, in which case we can't load CSS asynchronously. -->
 <noscript><link rel="stylesheet" href="style.css"></noscript>

पूर्व लोड हो रहा है और async संयुक्त:

यदि आपको पहले से लोड किए गए और async सीएसएस की जरूरत है, तो यह समाधान ऊपर दिए गए प्रलेखित उत्तर से केवल दो पंक्तियों को जोड़ता है, जिससे यह थोड़ा साफ हो जाता है। लेकिन यह फ़ायरफ़ॉक्स में तब तक काम नहीं करेगा जब तक वे प्रीलोड कीवर्ड का समर्थन नहीं करते । और फिर, जैसा कि ऊपर वर्णित दस्तावेज में विस्तृत है, प्रीलोडिंग वास्तव में फायदेमंद नहीं हो सकता है।

<link href="style.css" rel="preload" as="style" onload="this.rel='stylesheet'">
<noscript><link rel="stylesheet" href="style.css"></noscript>

अतिरिक्त मुद्दो पर विचार करना:

ध्यान दें कि, यदि आप सीएसएस को अतुल्यकालिक रूप से लोड करने जा रहे हैं, तो आमतौर पर यह अनुशंसा की जाती है कि आप महत्वपूर्ण सीएसएस को इनलाइन करें , क्योंकि सीएसएस एक कारण के लिए रेंडर-ब्लॉकिंग संसाधन है ।

अपने कई async सीएसएस समाधान के लिए फिलामेंट समूह को क्रेडिट


3
लोडसीएसएस का उपयोग करने की कोई आवश्यकता नहीं है, पॉलीफिल पर्याप्त है: github.com/filamentgroup/loadCSS/blob/master/src/…
nathan

1
प्रीलोड की विशेष स्थिति आखिरकार [W3C कैंडिडेट की सिफारिश] है। ( w3.org/TR/preload/… ) फ़ायरफ़ॉक्स इसका समर्थन करता है, लेकिन फिर भी डिफ़ॉल्ट रूप से अक्षम है; फ़ायरफ़ॉक्स ध्वज के "कैन आई यूज़" विवरण के लिए उत्तर "व्यापक रूप से समर्थित" लिंक पर क्लिक करें जो इसे नियंत्रित करता है।
टूलमेकरसेव

1
अतिरिक्त स्पष्टीकरण के साथ, पूर्ण ब्राउज़र समर्थन के लिए समाधान प्रदान करने के लिए अपडेट किया गया उत्तर।
jabacchetta

1
@jabacchetta 2020 अपडेट को बहुत सराहा गया है, धन्यवाद। मैं हाल के दिनों में लिखे गए निर्देशों के लिए विशेष रूप से देख रहा था जहां ब्राउज़र समर्थन आमतौर पर बेहतर होता है। वेब पर 3 साल में बहुत कुछ बदल जाता है!
Brandito

2
जाहिर है, यह बेहतर है onload="this.rel='stylesheet'; this.onload = null"। जाहिरा तौर पर कुछ ब्राउज़रों में इसे दो बार कहा this.onloadजाने nullसे बचने के लिए सेट करना आवश्यक है ।
फ्लिम

10

का उपयोग कर media="print"औरonload

फिलामेंट समूह ने हाल ही में (जुलाई 2019) सीएसएस को अतुल्यकालिक रूप से लोड करने के लिए अपनी नवीनतम सिफारिश देते हुए एक लेख प्रकाशित किया । भले ही वे लोकप्रिय जावास्क्रिप्ट लाइब्रेरी लोडसीएसएस के डेवलपर हैं , लेकिन वे वास्तव में इस समाधान की सलाह देते हैं कि जावास्क्रिप्ट वेबसाइट की आवश्यकता नहीं है:

<link
  rel="stylesheet"
  href="/path/to/my.css"
  media="print"
  onload="this.media='all'; this.onload = null"
>

उपयोग करना media="print"ब्राउज़र को स्क्रीन पर इस स्टाइलशीट का उपयोग न करने के लिए इंगित करेगा, लेकिन प्रिंट पर। ब्राउज़र वास्तव में इन प्रिंट स्टाइलशीट को डाउनलोड करते हैं, लेकिन अतुल्यकालिक रूप से, जो हम चाहते हैं। हम यह भी चाहते हैं कि डाउनलोड होने के बाद स्टाइलशीट का उपयोग किया जाए और इसके लिए हम सेट करते हैं onload="this.media='all'; this.onload = null"। (कुछ ब्राउज़र onloadदो बार कॉल करेंगे , इसके आसपास काम करने के लिए, हमें सेट करने की आवश्यकता है this.onload = null।) यदि आप चाहें, तो आप उन <noscript>दुर्लभ उपयोगकर्ताओं के लिए कमबैक जोड़ सकते हैं जिनके पास जावास्क्रिप्ट सक्षम नहीं है।

मूल लेख के रूप में यह और अधिक विस्तार में चला जाता है की तुलना में मैं यहाँ हूँ, पढ़ने लायक है। Csswizardry.com का यह लेख भी पढ़ने लायक है।


5

आप इसे बहुत तरीकों से प्राप्त करने का प्रयास कर सकते हैं:

1. उपयोग media="bogus"और <link>पैर में

<head>
    <!-- unimportant nonsense -->
    <link rel="stylesheet" href="style.css" media="bogus">
</head>
<body>
    <!-- other unimportant nonsense, such as content -->
    <link rel="stylesheet" href="style.css">
</body>

2. पुराने तरीके से डोम लगाना

<script type="text/javascript">
(function(){
  var bsa = document.createElement('script');
     bsa.type = 'text/javascript';
     bsa.async = true;
     bsa.src = 'https://s3.buysellads.com/ac/bsa.js';
  (document.getElementsByTagName('head')[0]||document.getElementsByTagName('body')[0]).appendChild(bsa);
})();
</script>

3. यदि आप प्लग इन की कोशिश कर सकते हैं की कोशिश कर सकते loadCSS

<script>
  // include loadCSS here...
  function loadCSS( href, before, media ){ ... }
  // load a file
  loadCSS( "path/to/mystylesheet.css" );
</script>

3
उदाहरण 2 जावास्क्रिप्ट लोड करता है, लेकिन सवाल सीएसएस लोड करने के बारे में है। क्या आप जानते हैं अगर उदाहरण 2 सीएसएस के लिए भी काम करता है, अगर आप से बदलने <script>के लिए <style rel=stylesheet>? (बस जिज्ञासु। मैं loadCSSसीएसएस को लोड करने की आवश्यकता के बजाय (यानी आपके उदाहरण 3) का उपयोग करने जा रहा हूं , अगर मुझे बाद में सीएसएस लोड करने की आवश्यकता है।)
काजाग्नसस

5

नीचे दी गई कार्यविधि उन सभी शैलियों को दस्तावेज़ में बनाएगी और जोड़ेगी जिन्हें आप अतुल्यकालिक रूप से लोड करना चाहते हैं। (लेकिन, इसके लिए धन्यवाद Event Listener, यह सभी विंडो के अन्य संसाधनों को लोड करने के बाद ही ऐसा करेगा।)

निम्नलिखित देखें:

function loadAsyncStyleSheets() {

    var asyncStyleSheets = [
    '/stylesheets/async-stylesheet-1.css',
    '/stylesheets/async-stylesheet-2.css'
    ];

    for (var i = 0; i < asyncStyleSheets.length; i++) {
        var link = document.createElement('link');
        link.setAttribute('rel', 'stylesheet');
        link.setAttribute('href', asyncStyleSheets[i]);
        document.head.appendChild(link);
    }
}

window.addEventListener('load', loadAsyncStyleSheets, false);

1
यदि हम इसकी तुलना लोडसीएसएस दृष्टिकोण से करते हैं तो क्या इस पद्धति की कोई कमियां हैं? ऐसा लगता है, पृष्ठ निकाय में टैग के var newStyle = document.createElement("link"); newStyle.rel = "stylesheet"; newStyle.href = "stylesheet.css"; document.getElementsByTagName("head")[0].appendChild(newStyle);अंदर शास्त्रीय कोड <script>अपना काम उत्कृष्ट रूप से करता है - यहां तक ​​कि MSIE8 जैसे पुराने ब्राउज़रों में भी।
TecMan

2
@TecMan हाँ वहाँ हैं। जैसा कि आप देख सकते हैं, यह फ़ंक्शन window.loadईवेंट पर काम करता है । तो, डाउनलोड शुरू होता है जब सब कुछ डाउनलोड किया जाता है। वहां कोई किस्मत नहीं। जितनी जल्दी हो सके आपको गैर-अवरुद्ध लोडिंग की आवश्यकता है।
मिलोउ ovakonović

5

Async सीएसएस लोड हो रहा है दृष्टिकोण

एक ब्राउज़र लोड सीएसएस को अतुल्यकालिक रूप से बनाने के कई तरीके हैं, हालांकि कोई भी उतना सरल नहीं है जितना आप उम्मीद कर सकते हैं।

<link rel="preload" href="mystyles.css" as="style" onload="this.rel='stylesheet'">

1

यदि आपको प्रोग्रामेटिक और एसिंक्रोनस रूप से CSS लिंक लोड करने की आवश्यकता है:

// https://www.filamentgroup.com/lab/load-css-simpler/
function loadCSS(href, position) {
  const link = document.createElement('link');
  link.media = 'print';
  link.rel = 'stylesheet';
  link.href = href;
  link.onload = () => { link.media = 'all'; };
  position.parentNode.insertBefore(link, position);
}

0

यदि आपके पास एक सख्त सामग्री सुरक्षा नीति है जो @ vladimir-salguero के उत्तर की अनुमति नहीं देती है , तो आप इसका उपयोग कर सकते हैं (कृपया स्क्रिप्ट पर ध्यान दें nonce):

<script nonce="(your nonce)" async>
$(document).ready(function() {
    $('link[media="none"]').each(function(a, t) {
        var n = $(this).attr("data-async"),
            i = $(this);
        void 0 !== n && !1 !== n && ("true" == n || n) && i.attr("media", "all")
    })
});
</script>

बस अपनी स्टाइलशीट संदर्भ में निम्नलिखित जोड़ें media="none" data-async="true":। यहाँ एक उदाहरण है:

<link rel="stylesheet" href="../path/script.js" media="none" data-async="true" />

JQuery के लिए उदाहरण:

<link rel="stylesheet" href="https://ajax.googleapis.com/ajax/libs/jqueryui/1.12.1/themes/smoothness/jquery-ui.css" type="text/css" media="none" data-async="true" crossorigin="anonymous" /><noscript><link rel="stylesheet" href="https://ajax.googleapis.com/ajax/libs/jqueryui/1.12.1/themes/smoothness/jquery-ui.css" type="text/css" /></noscript>

मुझे लगता है कि asyncविशेषता को नजरअंदाज कर दिया गया है, क्योंकि स्क्रिप्ट टैग में srcएसिंक्रोनस रूप से लोड करने की आवश्यकता नहीं है ... या क्या यह वास्तव में यहां उपयोगी है? इसके अलावा क्या आप थोड़ा और अधिक विस्तार कर सकते हैं कि किस मूल्य को एक के रूप में उपयोग करना है nonce?
फिलिप

0

कृपया उत्तर को अपडेट करने के लिए ध्यान रखें क्योंकि उपरोक्त सभी अब Google पेजस्पीड अंतर्दृष्टि को प्रभावित करने में विफल हैं।

Google के अनुसार यह है कि आपको Css के async लोडिंग को कैसे लागू करना चाहिए

 < noscript id="deferred-styles" >
        < link rel="stylesheet" type="text/css" href="small.css"/ >
    < /noscript >

<script>
  var loadDeferredStyles = function() {
    var addStylesNode = document.getElementById("deferred-styles");
    var replacement = document.createElement("div");
    replacement.innerHTML = addStylesNode.textContent;
    document.body.appendChild(replacement)
    addStylesNode.parentElement.removeChild(addStylesNode);
  };
  var raf = window.requestAnimationFrame || window.mozRequestAnimationFrame ||
      window.webkitRequestAnimationFrame || window.msRequestAnimationFrame;
  if (raf) raf(function() { window.setTimeout(loadDeferredStyles, 0); });
  else window.addEventListener('load', loadDeferredStyles);
</script>

1
यदि आप मेरे द्वारा बताए गए प्रीलोड कीवर्ड दृष्टिकोण का उपयोग कर रहे हैं, तो एक गलत सकारात्मक (पेजस्पीड बग)। github.com/filamentgroup/loadCSS/issues/53
jabacchetta

1
अद्यतन: Google ने पदावनत किया है, और फिर शटडाउन, पेजस्पेड संस्करण 4 जिसमें यह समस्या थी - वह संस्करण था जिसके लिए इस async कोड की सिफारिश की गई थी। हालाँकि मैंने PageSpeed ​​5 में परीक्षण नहीं किया है : उन्होंने अब कैसे परीक्षण किया, और "लिंक" के "प्रीलोड" टैग के लिए उनके समर्थन का विवरण देते हुए, jabachetta का उत्तर संभवतः Google के लिए बेहतर उत्तर है।
टूलमेकरसेव

1
@ToolmakerSteve हाँ इस उत्तर को अक्सर संचालित करने की आवश्यकता है। लेकिन यह कोड अभी भी आपको पृष्ठ गति में 100 प्राप्त करने के लिए काम करता है।
कौशिक गान्धी

0

मेरे पास उपयोग करने की कोशिश है:

<link rel="preload stylesheet" href="mystyles.css" as="style">

यह जुर्माना काम करता है, लेकिन यह संचयी लेआउट बदलाव भी करता है क्योंकि जब हम rel = "प्रीलोड" का उपयोग करते हैं, तो यह बस सीएसएस डाउनलोड करता है, तत्काल लागू नहीं होता है।

उदाहरण जब DOM लोड की सूची में ul, li टैग होते हैं, तो डिफ़ॉल्ट रूप से li टैग से पहले एक बुलेट होता है, फिर CSS ने आवेदन किया कि मैं इन बुलेट्स को लिस्टिंग के लिए कस्टम स्टाइल में हटा देता हूं। तो, यहाँ संचयी लेआउट बदलाव हो रहा है।

क्या इसका कोई हल है?


0

rel="preload"इसे स्वतंत्र रूप से डाउनलोड करने के लिए उपयोग करें , फिर onload="this.rel='stylesheet'"इसे स्टाइलशीट पर लागू करने के लिए उपयोग करें ( as="style"इसे स्टाइलशीट पर लागू करने के लिए आवश्यक है अन्यथा onloadकाम नहीं करेगा)

<link rel="preload" as="style" type="text/css" href="mystyles.css" onload="this.rel='stylesheet'">
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.