среда, 23 июня 2010 г.

Загрузка .js-файлов в html коде – best practicies от Nokia

  • Использование lazy-loading для .js-файлов

При генерации страницы среда последовательно считывает содержимое html-кода. Если в процессе генерации попадается тег <script> с указанием на загрузку скрипта из внешнего источника – парсинг страницы прекращается до момента загрузки и выполнения попавшего скрипта. Тем самым, если скрипты объемные либо соединение нестабильное и медленное, построение страницы может затянутся на длительное время, даже если скрипт используется совсем для других целей. Для избежания проблем с залипанием процесса рендеринга страницы используется механизм, так называемого, динамической загрузки скриптов или иньекции скриптов. Данный механизм позволяет последовательно генерировать страницу без ожидания загрузки скриптов, в том время как сами скрипты автоматически будут выполнены после загрузки, паралельно построению layout-а.

   1: //bad
   2: <div id="splash"/>
   3: <script src="my-script-file.js" type="text/javascript"></script>
   4:  
   5: //good
   6: <div id="splash"/>
   7: // JavaScript
   8: function loadScript(src, callback) {
   9:     var head = document.getElementsByTagName('head')[0],
  10:         script = document.createElement('script');
  11:     done = false;
  12:     script.setAttribute('src', src);
  13:     script.setAttribute('type', 'text/javascript');
  14:     script.setAttribute('charset', 'utf-8');
  15:     script.onload = script.onreadstatechange = function() {
  16:         if (!done && (!this.readyState || this.readyState == 'loaded' || this.readyState == 'complete')) {
  17:             done = true;
  18:             script.onload = script.onreadystatechange = null;
  19:                 if (callback) {
  20:                     callback();
  21:                 }
  22:             }
  23:     }
  24:     head.insertBefore(script, head.firstChild);
  25: }
  26:  
  27: // load the my-script-file.js and display an alert dialog once the script has been loaded
  28: loadScript('my-script-file.js', function() { alert('my-script-file.js loaded.'); });


  • Использование http-заголовков Expires для загружаемых скриптов

Данный механизм позволяет не загружать скрипты, если локальная копия еще имеет не просроченное время срока жизни. Тем самым, после первого посещения сайта загруженные и сохраненные в локальном кеше скрипты можно будет повторно использовать без перезагрузки.



  • Сжатие передаваемых скриптов посредстов Gzip-компрессии

  • Объединение нескольких скриптов в один – это позволит уменьшить количество http-запросов к серверу, а, соответственно, и время ожидания загрузки всех скриптов

  • Использовать при возможности несколько мест хранения скриптов с разными адрессами, что позволит распаралелить загрузку

  • Не использовать inline-скрипты – встроенные в страницу, выносите их в отдельных файл. При последующей загрузке страницы будет использована локальная копия скриптового файла, а не загружать регулярно при загрузке страницы

  • Для уменьшения скорости построения страницы старайтесь использовать минимально возможное количество DOM-элементов


   1: //получить количество DOM-элементов на странице
   2: var n = document.getElementsByTagName('*').length;



  • Если есть возможность – изменяйте свойства DOM-объекта в состоянии – не видим.


   1: var subElem = document.createElement('div'),
   2:     elem = document.getElementById('animated');
   3: elem.style.display = 'none';
   4: elem.appendChild(subElem);
   5: elem.style.width = '320px';
   6: elem.style.display = 'block';



  • Не считывайте следующие свойства без необходимости – это приводит к изменению положения элемента и перепроверке положения последующих: getComputedStyle, offsetWidth, scrollWidth и clientWidth


   1: //slow
   2: var elem = document.getElementById('animated');
   3: elem.style.fontSize = (elem.offsetWidth / 10) + 'px';
   4: elem.firstChild.style.marginleft = (elem.offsetWidth / 20) + 'px';
   5:  
   6: //faster
   7: var elem = document.getElementById('animated'),
   8:     elemWidth = elem.offsetWidth;
   9: elem.style.fontSize = (elemWidth / 10) + 'px';
  10: elem.firstChild.style.marginleft = (elemWidth / 20) + 'px';



  • Вместо измнения нескольких стилей элемента последовально, лучше использовать назвачение отдельного css-класса


   1: //slow
   2: var elem = document.getElementById('styled');
   3: elem.style.background = 'blue';
   4: elem.style.color = 'white';
   5:  
   6: //Faster 
   7: <style type="text/css">
   8: div { background: white; color: black; }
   9: div.active { background: blue; color: white; }
  10: </style>
  11: var elem = document.getElementById('styled').className = 'active';



  • Чтобы не создавать отдельный css-класс – можно использовать метод setAttribute для назначения нескольких свойст за раз


   1: var elem = document.getElementById('styled');
   2: elemStyle = 'background: blue; color: white;';
   3: elem.setAttribute('style', elemStyle);



  • сохранять найденные элементы в переменные при необходимости повторного их использования


   1: //slow
   2: document.getElementById('elem').propertyOne = 'value of first property';
   3: document.getElementById('elem').propertyTwo = 'value of second property';
   4: document.getElementById('elem').propertyThree = 'value of third property';
   5:  
   6: //faster
   7: var elem = document.getElementById('elem');
   8: elem.propertyOne = 'value of first property';
   9: elem.propertyTwo = 'value of second property';
  10: elem.propertyThree = 'value of third property'

Комментариев нет:

Отправить комментарий