<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>Разработка &#187; оптимизация</title>
	<atom:link href="http://www.job-blog.bullgare.ru/category/%d0%be%d0%bf%d1%82%d0%b8%d0%bc%d0%b8%d0%b7%d0%b0%d1%86%d0%b8%d1%8f/feed/" rel="self" type="application/rss+xml" />
	<link>http://www.job-blog.bullgare.ru</link>
	<description>о программировании и работе</description>
	<lastBuildDate>Wed, 08 Feb 2012 09:39:48 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.0.4</generator>
		<item>
		<title>Дизассемблирование и минификация javascript</title>
		<link>http://www.job-blog.bullgare.ru/2012/01/%d0%b4%d0%b8%d0%b7%d0%b0%d1%81%d1%81%d0%b5%d0%bc%d0%b1%d0%bb%d0%b8%d1%80%d0%be%d0%b2%d0%b0%d0%bd%d0%b8%d0%b5-%d0%b8-%d0%bc%d0%b8%d0%bd%d0%b8%d1%84%d0%b8%d0%ba%d0%b0%d1%86%d0%b8%d1%8f-javascript/</link>
		<comments>http://www.job-blog.bullgare.ru/2012/01/%d0%b4%d0%b8%d0%b7%d0%b0%d1%81%d1%81%d0%b5%d0%bc%d0%b1%d0%bb%d0%b8%d1%80%d0%be%d0%b2%d0%b0%d0%bd%d0%b8%d0%b5-%d0%b8-%d0%bc%d0%b8%d0%bd%d0%b8%d1%84%d0%b8%d0%ba%d0%b0%d1%86%d0%b8%d1%8f-javascript/#comments</comments>
		<pubDate>Mon, 30 Jan 2012 08:47:04 +0000</pubDate>
		<dc:creator>bullgare</dc:creator>
				<category><![CDATA[javascript]]></category>
		<category><![CDATA[клиентская оптимизация]]></category>
		<category><![CDATA[ссылка]]></category>

		<guid isPermaLink="false">http://www.job-blog.bullgare.ru/?p=1405</guid>
		<description><![CDATA[http://pimpmyjs.com/ &#8211; Uglify or Beautify your JavaScript, it&#8217;s your choice&#8230; (minify js online) На jquery.min.js выдал ошибку, но в общем работает, и причём быстро.]]></description>
			<content:encoded><![CDATA[<p><a href="http://pimpmyjs.com/">http://pimpmyjs.com/</a> &#8211; Uglify or Beautify your JavaScript, it&#8217;s your choice&#8230; (minify js online)</p>
<p>На jquery.min.js выдал ошибку, но в общем работает, и причём быстро.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.job-blog.bullgare.ru/2012/01/%d0%b4%d0%b8%d0%b7%d0%b0%d1%81%d1%81%d0%b5%d0%bc%d0%b1%d0%bb%d0%b8%d1%80%d0%be%d0%b2%d0%b0%d0%bd%d0%b8%d0%b5-%d0%b8-%d0%bc%d0%b8%d0%bd%d0%b8%d1%84%d0%b8%d0%ba%d0%b0%d1%86%d0%b8%d1%8f-javascript/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Реализация счётчика на memcached</title>
		<link>http://www.job-blog.bullgare.ru/2012/01/%d1%80%d0%b5%d0%b0%d0%bb%d0%b8%d0%b7%d0%b0%d1%86%d0%b8%d1%8f-%d1%81%d1%87%d1%91%d1%82%d1%87%d0%b8%d0%ba%d0%b0-%d0%bd%d0%b0-memcached/</link>
		<comments>http://www.job-blog.bullgare.ru/2012/01/%d1%80%d0%b5%d0%b0%d0%bb%d0%b8%d0%b7%d0%b0%d1%86%d0%b8%d1%8f-%d1%81%d1%87%d1%91%d1%82%d1%87%d0%b8%d0%ba%d0%b0-%d0%bd%d0%b0-memcached/#comments</comments>
		<pubDate>Fri, 13 Jan 2012 13:30:00 +0000</pubDate>
		<dc:creator>bullgare</dc:creator>
				<category><![CDATA[Программирование]]></category>
		<category><![CDATA[оптимизация]]></category>
		<category><![CDATA[memcached]]></category>
		<category><![CDATA[ссылка]]></category>

		<guid isPermaLink="false">http://www.job-blog.bullgare.ru/?p=1367</guid>
		<description><![CDATA[http://habrahabr.ru/blogs/webdev/43282/]]></description>
			<content:encoded><![CDATA[<p><a href="http://habrahabr.ru/blogs/webdev/43282/">http://habrahabr.ru/blogs/webdev/43282/</a></p>
]]></content:encoded>
			<wfw:commentRss>http://www.job-blog.bullgare.ru/2012/01/%d1%80%d0%b5%d0%b0%d0%bb%d0%b8%d0%b7%d0%b0%d1%86%d0%b8%d1%8f-%d1%81%d1%87%d1%91%d1%82%d1%87%d0%b8%d0%ba%d0%b0-%d0%bd%d0%b0-memcached/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Вёрстка под мобильные устройства</title>
		<link>http://www.job-blog.bullgare.ru/2012/01/%d0%b2%d1%91%d1%80%d1%81%d1%82%d0%ba%d0%b0-%d0%bf%d0%be%d0%b4-%d0%bc%d0%be%d0%b1%d0%b8%d0%bb%d1%8c%d0%bd%d1%8b%d0%b5-%d1%83%d1%81%d1%82%d1%80%d0%be%d0%b9%d1%81%d1%82%d0%b2%d0%b0/</link>
		<comments>http://www.job-blog.bullgare.ru/2012/01/%d0%b2%d1%91%d1%80%d1%81%d1%82%d0%ba%d0%b0-%d0%bf%d0%be%d0%b4-%d0%bc%d0%be%d0%b1%d0%b8%d0%bb%d1%8c%d0%bd%d1%8b%d0%b5-%d1%83%d1%81%d1%82%d1%80%d0%be%d0%b9%d1%81%d1%82%d0%b2%d0%b0/#comments</comments>
		<pubDate>Wed, 11 Jan 2012 09:09:45 +0000</pubDate>
		<dc:creator>bullgare</dc:creator>
				<category><![CDATA[Программирование]]></category>
		<category><![CDATA[клиентская оптимизация]]></category>
		<category><![CDATA[вёрстка]]></category>
		<category><![CDATA[вёрстка под мобильные устройства]]></category>

		<guid isPermaLink="false">http://www.job-blog.bullgare.ru/?p=1362</guid>
		<description><![CDATA[Хороший доклад &#8211; Прокрустовы окна. Как вписаться в устройства с минимальными потерями (ссылка на видео &#8211; http://mediadl.microsoft.com/mediadl/www/r/rus/html5camp2011/4005_800_2.wmv, слайды на http://pepelsbey.net/pres/procrustes/). Главное &#8211; это понять viewport и dpi. Для примера: &#60;meta name="viewport" content="width=device-width, target-densitydpi=device-dp, user-scalable=no, initial-scale=1.0, maximum-scale=1.0i" /&#62; Советуют удобные сервисы для тестирования мобильных сайтов (&#171;firebug для мобильных устройств&#187;) &#8211; Opera Mini Simulator и Opera Mobile [...]]]></description>
			<content:encoded><![CDATA[<p>Хороший доклад &#8211; <a href="http://www.microsoft.com/ru-ru/events/html5camp/#video">Прокрустовы окна. Как вписаться в устройства с минимальными потерями</a> (ссылка на видео &#8211; <a href="http://mediadl.microsoft.com/mediadl/www/r/rus/html5camp2011/4005_800_2.wmv">http://mediadl.microsoft.com/mediadl/www/r/rus/html5camp2011/4005_800_2.wmv</a>,  слайды на <a href="http://pepelsbey.net/pres/procrustes/">http://pepelsbey.net/pres/procrustes/</a>).<br />
Главное &#8211; это понять viewport и dpi.<br />
Для примера:</p>
<pre class="code">
&lt;meta name="viewport"
content="width=device-width, target-densitydpi=device-dp, user-scalable=no, initial-scale=1.0, maximum-scale=1.0i" /&gt;
</pre>
<p>Советуют удобные сервисы для тестирования мобильных сайтов (&laquo;firebug для мобильных устройств&raquo;) &#8211; <a href="http://www.opera.com/developer/tools/mini/">Opera Mini Simulator</a> и <a href="http://dev.opera.com/articles/view/opera-mobile-emulator/">Opera Mobile Emulator for desktop</a>.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.job-blog.bullgare.ru/2012/01/%d0%b2%d1%91%d1%80%d1%81%d1%82%d0%ba%d0%b0-%d0%bf%d0%be%d0%b4-%d0%bc%d0%be%d0%b1%d0%b8%d0%bb%d1%8c%d0%bd%d1%8b%d0%b5-%d1%83%d1%81%d1%82%d1%80%d0%be%d0%b9%d1%81%d1%82%d0%b2%d0%b0/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
<enclosure url="http://mediadl.microsoft.com/mediadl/www/r/rus/html5camp2011/4005_800_2.wmv" length="211077374" type="video/asf" />
		</item>
		<item>
		<title>Интересный доклад про разработку API</title>
		<link>http://www.job-blog.bullgare.ru/2011/12/%d0%b8%d0%bd%d1%82%d0%b5%d1%80%d0%b5%d1%81%d0%bd%d1%8b%d0%b9-%d0%b4%d0%be%d0%ba%d0%bb%d0%b0%d0%b4-%d0%bf%d1%80%d0%be-%d1%80%d0%b0%d0%b7%d1%80%d0%b0%d0%b1%d0%be%d1%82%d0%ba%d1%83-api/</link>
		<comments>http://www.job-blog.bullgare.ru/2011/12/%d0%b8%d0%bd%d1%82%d0%b5%d1%80%d0%b5%d1%81%d0%bd%d1%8b%d0%b9-%d0%b4%d0%be%d0%ba%d0%bb%d0%b0%d0%b4-%d0%bf%d1%80%d0%be-%d1%80%d0%b0%d0%b7%d1%80%d0%b0%d0%b1%d0%be%d1%82%d0%ba%d1%83-api/#comments</comments>
		<pubDate>Fri, 02 Dec 2011 12:32:25 +0000</pubDate>
		<dc:creator>bullgare</dc:creator>
				<category><![CDATA[клиентская оптимизация]]></category>
		<category><![CDATA[проектирование]]></category>
		<category><![CDATA[серверная оптимизация]]></category>
		<category><![CDATA[API]]></category>
		<category><![CDATA[cache]]></category>
		<category><![CDATA[ссылка]]></category>

		<guid isPermaLink="false">http://www.job-blog.bullgare.ru/?p=1334</guid>
		<description><![CDATA[На конференции &#171;.Тостер&#187; попал на доклад Jordi Romero API design and more (слайды). Говорил про создание API, про кеширование, про масштабирование, клиентскую оптимизацию. Понемножку, сжато. Понравилось. Странно только, что у них три уровня хранения данных: mySQL master-slave Redis для сложного кеша, чтобы не нагружать mySQL memcache для простого кеша]]></description>
			<content:encoded><![CDATA[<p>На конференции &laquo;.Тостер&raquo; попал на доклад Jordi Romero API design and more (<a href="http://jrom.net/api-design-and-more">слайды</a>).<br />
Говорил про создание API, про кеширование, про масштабирование, клиентскую оптимизацию.<br />
Понемножку, сжато.<br />
Понравилось.<br />
Странно только, что у них три уровня хранения данных:</p>
<ol>
<li>mySQL master-slave</li>
<li>Redis для сложного кеша, чтобы не нагружать mySQL</li>
<li>memcache для простого кеша</li>
</ol>
]]></content:encoded>
			<wfw:commentRss>http://www.job-blog.bullgare.ru/2011/12/%d0%b8%d0%bd%d1%82%d0%b5%d1%80%d0%b5%d1%81%d0%bd%d1%8b%d0%b9-%d0%b4%d0%be%d0%ba%d0%bb%d0%b0%d0%b4-%d0%bf%d1%80%d0%be-%d1%80%d0%b0%d0%b7%d1%80%d0%b0%d0%b1%d0%be%d1%82%d0%ba%d1%83-api/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Самый хороший способ подгрузки яваскриптов – тегом script</title>
		<link>http://www.job-blog.bullgare.ru/2011/11/%d1%81%d0%b0%d0%bc%d1%8b%d0%b9-%d1%85%d0%be%d1%80%d0%be%d1%88%d0%b8%d0%b9-%d1%81%d0%bf%d0%be%d1%81%d0%be%d0%b1-%d0%bf%d0%be%d0%b4%d0%b3%d1%80%d1%83%d0%b7%d0%ba%d0%b8-%d1%8f%d0%b2%d0%b0%d1%81%d0%ba/</link>
		<comments>http://www.job-blog.bullgare.ru/2011/11/%d1%81%d0%b0%d0%bc%d1%8b%d0%b9-%d1%85%d0%be%d1%80%d0%be%d1%88%d0%b8%d0%b9-%d1%81%d0%bf%d0%be%d1%81%d0%be%d0%b1-%d0%bf%d0%be%d0%b4%d0%b3%d1%80%d1%83%d0%b7%d0%ba%d0%b8-%d1%8f%d0%b2%d0%b0%d1%81%d0%ba/#comments</comments>
		<pubDate>Fri, 25 Nov 2011 07:24:51 +0000</pubDate>
		<dc:creator>bullgare</dc:creator>
				<category><![CDATA[javascript]]></category>
		<category><![CDATA[клиентская оптимизация]]></category>
		<category><![CDATA[проектирование]]></category>

		<guid isPermaLink="false">http://www.job-blog.bullgare.ru/?p=1309</guid>
		<description><![CDATA[Использовали мы на проекте одну лебедевскую библиотеку &#8211; include.js. Умеет она интересные вещи, вроде последовательной загрузки зависимых библиотек в нужном порядке. Нужно в яваскрипте написать js.include( &#8216;my/coolwiidget&#8217; );. Работает она, если на пальцах, следующим образом: делается ajax-запрос, которым грузится текст нужного скрипта, потом ищутся в тексте все js.include, делается их подгрузка, после чего делается eval [...]]]></description>
			<content:encoded><![CDATA[<p>Использовали мы на проекте одну лебедевскую библиотеку &#8211; <a href="http://www.artlebedev.ru/tools/technogrette/js/include/">include.js</a>. Умеет она интересные вещи, вроде последовательной загрузки зависимых библиотек в нужном порядке. Нужно в яваскрипте написать <strong>js.include( &#8216;my/coolwiidget&#8217; );</strong>. Работает она, если на пальцах, следующим образом: делается ajax-запрос, которым грузится текст нужного скрипта, потом ищутся в тексте все <strong>js.include</strong>, делается их подгрузка, после чего делается <strong>eval</strong> полученных текстов в обратном порядке. При этом ещё и отсекаются попытки по несколько раз грузить один и тот же яваскрипт.<br />
Работал он очень неплохо, хотя и неудобно было в firebug-е искать скрипт по его имени.<br />
Основная проблема встала, когда стало нужно вынести все яваскрипты на отдельный домен. Вот тут-то и проявились проблемы &#8211; ajax-ом нельзя грузить код с других доменов. Помогает заголовок <strong>Access-Control-Allow-Origin</strong>, но его понимают только современные браузеры (к примеру, firefox с версии 3.5), а на проекте критична максимально возможная совместимость (как обычно и бывает). Так что этот способ может быть актуален года через 3-5.<br />
Посмотрели на другие способы, в итоге пришли к динамическому добавлению тега <strong>script</strong> в <strong>head</strong>, но особого смысла в этом нет, т.к. зависимости, для которых и городился изначально огород, при этом способе не отслеживаются (JSONP с колбэками не подошёл, т.к. в проекте много legacy-кода, который использует глобальные переменные, причём даже не как константы).<br />
В итоге было принято гениальное в своей простоте решение &#8211; отказаться от всех этих изысков нафик и грузить скрипты как раньше &#8211; при загрузке страницы.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.job-blog.bullgare.ru/2011/11/%d1%81%d0%b0%d0%bc%d1%8b%d0%b9-%d1%85%d0%be%d1%80%d0%be%d1%88%d0%b8%d0%b9-%d1%81%d0%bf%d0%be%d1%81%d0%be%d0%b1-%d0%bf%d0%be%d0%b4%d0%b3%d1%80%d1%83%d0%b7%d0%ba%d0%b8-%d1%8f%d0%b2%d0%b0%d1%81%d0%ba/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Lazy load баннеров</title>
		<link>http://www.job-blog.bullgare.ru/2011/11/lazy-load-%d0%b1%d0%b0%d0%bd%d0%bd%d0%b5%d1%80%d0%be%d0%b2/</link>
		<comments>http://www.job-blog.bullgare.ru/2011/11/lazy-load-%d0%b1%d0%b0%d0%bd%d0%bd%d0%b5%d1%80%d0%be%d0%b2/#comments</comments>
		<pubDate>Fri, 11 Nov 2011 07:58:18 +0000</pubDate>
		<dc:creator>bullgare</dc:creator>
				<category><![CDATA[javascript]]></category>
		<category><![CDATA[клиентская оптимизация]]></category>

		<guid isPermaLink="false">http://www.job-blog.bullgare.ru/?p=1282</guid>
		<description><![CDATA[Сегодня из-за очередных проблем с sol.adbureau.net было решено реализовать ленивую загрузку баннеров. Начальное решение было использовать iframe, но идея была не очень удачной, т. к. могут быть проблемы с подсчётом кликов, да и модные картинки, увеличивающиеся при наведении, будут вести себя странно. А как этот iframe смотрится в разных браузерах &#8211; это вообще сказка) В [...]]]></description>
			<content:encoded><![CDATA[<p>Сегодня из-за очередных проблем с sol.adbureau.net было решено реализовать ленивую загрузку баннеров.<br />
Начальное решение было использовать iframe, но идея была не очень удачной, т. к. могут быть проблемы с подсчётом кликов, да и модные картинки, увеличивающиеся при наведении, будут вести себя странно. А как этот iframe смотрится в разных браузерах &#8211; это вообще сказка)<br />
В итоге родилась идея: при генерации страницы размещать в нужных местах, к примеру, пустые дивы с id с нужным префиксом (<strong>&lt;div id=&raquo;js-advert-place-{num}&raquo;&gt;&lt;/div&gt;</strong>), а сами баннеры загружать в футер вот в такую, к примеру, разметку:</p>
<pre class="code">
&lt;div id="js-all-advert-block" class="all-advert-block"&gt;
	&lt;div class="js-advert-block-content" data-number="1"&gt;
		{баннер}
	&lt;/div&gt;
	&lt;div class="js-advert-block-content" data-number="5"&gt;
		{баннер}
	&lt;/div&gt;
	&lt;div class="js-advert-block-content" data-number="15"&gt;
		{баннер}
	&lt;/div&gt;
&lt;/div&gt;
{здесь грузится счётчик показов}
</pre>
<p>После загрузки страницы размещаем все баннеры на нужных местах:</p>
<pre class="code">
	(function( $ ) {
		function moveAdvert() {
			$( '#js-all-advert-block' ).find( '.js-advert-block-content' ).each( function() {
				var $oldContent = $( this );

			// в ие перемещаем
				if ( $.browser.msie ) {
					$( "#js-advert-place-" + $oldContent.data( "number" ) ).append( $oldContent );
				}
			// в других браузерах убираем лишнее и вставляем заново
				else
				{
					var cleanedContent = $oldContent.html().replace( /document\.write/gi, 'function a__(){}' );

					$( "#js-advert-place-" + $oldContent.data( "number" ) ).html( cleanedContent );
					$oldContent.remove();
				}

			// этот вариант менее хороший - глюки в ие и проблемы с яндекс.директ

			//	var $newContent = $.browser.msie ? $( $oldContent.html() ) : $oldContent.clone( true );

			//// не надо заново создавать скрипты - они заново выполнятся, а там document.write
			//	$newContent.find( "script, link" ).each( function() {
			//		$( this ).remove();
			//	} );

			//// вставляем
			//	$( "#js-advert-place-" + $oldContent.data( "number" ) ).html( $newContent );

			//// на старом месте нужно убить всё, кроме скриптов
			//// (в скриптах могут быть необходимые для правильного подсчёта кликов переменные)
			//	$oldContent.find( '*' ).each( function() {
			//		var $el = $( this );
			//		if ( ! $( 'script, link', $el ).length &#038;&#038; this.tagName.toLowerCase() != 'script' &#038;&#038; this.tagName.toLowerCase() != 'link' ) {
			//			$el.remove();
			//		}
			//	} );
			} );
		}

		$( document ).ready( function() {
			moveAdvert();
		} );
	}( jQuery ));
</pre>
<p>В итоге отвалившаяся внешняя баннерная площадка позволяет корректно отображать сайт без лишних задержек.<br />
За рамками осталась работа сервер-сайда, где нужно собрать данные по всем отображаемым на странице баннерам, а потом вывести их все сразу внизу.</p>
<p>UP:<br />
Всё-таки проблем оказалась куча. К примеру, opera 10.10 (хотя у меня 11.52) некорректно понимает тег <strong>script</strong> при <strong>.html( cleanedContent )</strong>, поэтому приходится чистить все теги <strong>script</strong>, но тогда умирает yandex.direct. К сожалению, на проекте нет нормальной возможности отделить директ от остальной рекламы (нет возможности объяснить тем людям, как что нужно настраивать), поэтому этот способ подходит с большими оговорками.<br />
UP2: Наткнулся на гениальное решение &#8211; переопределить <strong>document.write</strong>, потом немного доработал и вот что получилось:</p>
<pre class="code">
(function ( $ )
{
	// для собирания тега script
	var previousValue = '',
	// для проверки, собрали ли уже полный тег script
		reTestIfScript = new RegExp( '&lt;\/scr' + 'ipt&gt;$', 'i' ),
	// чтобы найти id дива, куда вставлять код соли
		reGetSolId = new RegExp( "sol\\.adbureau\\.net[^&gt;]+aamsz=(\\d+x\\d+)", 'i' ),
	// для проверки, что это относится к яндекс-директу
		reYandexDirect = new RegExp( "an\\.yandex\\.ru", 'i' );

// заменяем стандартные методы
	document.writeln = document.write = function(value)
	{
	// если последовательно пишут в документ для получения тега script (document.write( '&lt;SCR' ); document.write( '&lt;IPT src="...' );)
		try {
			$( value );
		}
		catch ( e )
		{
			var joinedValue = previousValue + value;
		// сли собрали полный тег скрипт, то вставляем его, куда надо
			if ( reTestIfScript.test( joinedValue ) )
			{
				value = joinedValue;
				previousValue = '';
			}
		// если начали писать тег скрипт, продолжаем до сбора всего тега
			else if ( joinedValue.toLowerCase().indexOf( '&lt;sc' ) == 0 )
			{
				previousValue = joinedValue;
				return;
			}
		// непонятно что это - ничего не делаем
			else {
				return;
			}
		}

		var parentNodeId,
			matches;
	// если в строке есть упоминание яндекса - вставляем в яндекс
		if ( reYandexDirect.test( value ) ) {
			parentNodeId = 'adv_media';
		}
	// если в строке есть упоминание соли - ищем id и вставляем в нужный div
		else if ( matches = value.match( reGetSolId ) ) {
			parentNodeId = 'sol' + matches[1];
		}

	// скрипт вставляем только в нужный элемент
		if ( $( value )[0].tagName == "SCRIPT" &#038;&#038; parentNodeId )
		{
			var js = document.createElement( 'SCRIPT' );
			var obj = document.getElementById( parentNodeId ).appendChild( js );

		// подгрузка внешнего скрипта
			if ( $( value ).attr( 'src' ) !== "undefined" ) {
				$( obj ).attr( {type: 'text/javascript', 'src': $( value ).attr( "src" )} );
			}
		// выполнение скрипта
			else
			{
				var reReplaceWrite = new RegExp( '(document\\.write[a-zA-Z]{0,2}\\([^)]+)(\\))', 'ig' );
				eval( $( value ).text().replace( reReplaceWrite, "$`$1, '" + parentNodeId + "'$2$'" ) );
			}
		}
	// стили ставим в head
		else if ( $( value )[0].tagName == "LINK" )
		{
			var js = document.createElement( 'LINK' );
			var obj = document.getElementsByTagName( 'head' )[0].appendChild( js );
			$( obj ).attr( {rel: 'stylesheet', 'href': $( value ).attr( "href" ) , type: 'text/css'} );
		}
		else if ( $( value )[0].tagName == "STYLE" )
		{
			if ( $.browser.msie ) {
				var css = document.createElement( 'STYLE' );
				document.documentElement.firstChild.appendChild( css );
				$( obj ).attr( {type: "text/css"} );
				css.styleSheet.cssText = $( value ).html();
			}
			else {
				$( value ).appendTo( $( "head" ) );
			}
		}
	// любой другой элемент вставляем в DOM, только если поняли, в какой элемент вставлять
		else if (  parentNodeId ) {
			$( value ).appendTo( $( "#" + parentNodeId ) );
		}
	};
}( jQuery ));
</pre>
<p>Всё бы ничего с этим решением, и даже знает, как собирать тег <strong>script</strong> из кусочков, но всё-таки мы не можем знать, в какое место DOM должна была производится запись, так что там есть костыли с определением места по контенту, и это решение не универсально.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.job-blog.bullgare.ru/2011/11/lazy-load-%d0%b1%d0%b0%d0%bd%d0%bd%d0%b5%d1%80%d0%be%d0%b2/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Использование VIEW в mySQL 5.0. Проблемы с производительностью.</title>
		<link>http://www.job-blog.bullgare.ru/2009/10/%d0%b8%d1%81%d0%bf%d0%be%d0%bb%d1%8c%d0%b7%d0%be%d0%b2%d0%b0%d0%bd%d0%b8%d0%b5-view-%d0%b2-mysql-5-0-%d0%bf%d1%80%d0%be%d0%b1%d0%bb%d0%b5%d0%bc%d1%8b-%d1%81-%d0%bf%d1%80%d0%be%d0%b8%d0%b7%d0%b2%d0%be/</link>
		<comments>http://www.job-blog.bullgare.ru/2009/10/%d0%b8%d1%81%d0%bf%d0%be%d0%bb%d1%8c%d0%b7%d0%be%d0%b2%d0%b0%d0%bd%d0%b8%d0%b5-view-%d0%b2-mysql-5-0-%d0%bf%d1%80%d0%be%d0%b1%d0%bb%d0%b5%d0%bc%d1%8b-%d1%81-%d0%bf%d1%80%d0%be%d0%b8%d0%b7%d0%b2%d0%be/#comments</comments>
		<pubDate>Mon, 26 Oct 2009 10:34:58 +0000</pubDate>
		<dc:creator>bullgare</dc:creator>
				<category><![CDATA[Базы данных]]></category>
		<category><![CDATA[серверная оптимизация]]></category>
		<category><![CDATA[mysql]]></category>
		<category><![CDATA[mysql 5]]></category>
		<category><![CDATA[оптимизация]]></category>

		<guid isPermaLink="false">http://www.job-blog.bullgare.ru/?p=448</guid>
		<description><![CDATA[Для тех, кто не знает, что это такое &#8211; ссылка Вкратце: созздаёт, фактически, &#171;временную таблицу&#187; (более правильно сказать &#8211; виртуальную таблицу или результат выборки в виде таблицы), в которой могут храниться данные из других таблиц и результаты применения аггрегирующих функций к ним. При этом если хранятся только данные, то эта таблица обновляется при обновлении входящих [...]]]></description>
			<content:encoded><![CDATA[<p>Для тех, кто не знает, что это такое &#8211; <a href="http://dev.mysql.com/tech-resources/articles/mysql-views.html">ссылка</a><br />
Вкратце: созздаёт, фактически, &laquo;временную таблицу&raquo; (более правильно сказать &#8211; виртуальную таблицу или результат выборки в виде таблицы), в которой могут храниться данные из других таблиц и результаты применения аггрегирующих функций к ним. При этом если хранятся только данные, то эта таблица обновляется при обновлении входящих в её состав таблиц.<br />
Но оказывается, что, как и многие нововведения (хранимые процедуры должны перекомпилироваться заново при начале сессии, если использовать подзапросы &#8211; очень много запросов получается), это тоже имеет очень большие проблемы с производительностью (<a href="http://www.mysqlperformanceblog.com/2007/08/12/mysql-view-as-performance-troublemaker/">ссылка</a>).<br />
Вкратце:<br />
неудобно искать проблемы в запросах (вроде как обращаешься к одной таблице, а на деле &#8211; нет), создаётся временная таблица без индексов. Также есть проблемы у mySQL при оптимизации запросов при обращении к VIEW.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.job-blog.bullgare.ru/2009/10/%d0%b8%d1%81%d0%bf%d0%be%d0%bb%d1%8c%d0%b7%d0%be%d0%b2%d0%b0%d0%bd%d0%b8%d0%b5-view-%d0%b2-mysql-5-0-%d0%bf%d1%80%d0%be%d0%b1%d0%bb%d0%b5%d0%bc%d1%8b-%d1%81-%d0%bf%d1%80%d0%be%d0%b8%d0%b7%d0%b2%d0%be/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>MySQL Profiler: простой и удобный инструмент профилирования запросов</title>
		<link>http://www.job-blog.bullgare.ru/2009/09/mysql-profiler-%d0%bf%d1%80%d0%be%d1%81%d1%82%d0%be%d0%b9-%d0%b8-%d1%83%d0%b4%d0%be%d0%b1%d0%bd%d1%8b%d0%b9-%d0%b8%d0%bd%d1%81%d1%82%d1%80%d1%83%d0%bc%d0%b5%d0%bd%d1%82-%d0%bf%d1%80%d0%be%d1%84%d0%b8/</link>
		<comments>http://www.job-blog.bullgare.ru/2009/09/mysql-profiler-%d0%bf%d1%80%d0%be%d1%81%d1%82%d0%be%d0%b9-%d0%b8-%d1%83%d0%b4%d0%be%d0%b1%d0%bd%d1%8b%d0%b9-%d0%b8%d0%bd%d1%81%d1%82%d1%80%d1%83%d0%bc%d0%b5%d0%bd%d1%82-%d0%bf%d1%80%d0%be%d1%84%d0%b8/#comments</comments>
		<pubDate>Thu, 24 Sep 2009 09:42:09 +0000</pubDate>
		<dc:creator>admin</dc:creator>
				<category><![CDATA[Базы данных]]></category>
		<category><![CDATA[администрирование]]></category>
		<category><![CDATA[серверная оптимизация]]></category>
		<category><![CDATA[mysql]]></category>
		<category><![CDATA[база данных]]></category>
		<category><![CDATA[бд]]></category>
		<category><![CDATA[оптимизация]]></category>
		<category><![CDATA[профилирование]]></category>

		<guid isPermaLink="false">http://www.job-blog.bullgare.ru/?p=339</guid>
		<description><![CDATA[оригинал; полная цитата: Сегодня был неожиданно удивлен, какие удобные штуки таит в себе MySQL. Хочу представить вашему вниманию фичу MySQL — профайлинг. Появилась она начиная с версии 5.0.37. Всего парой запросов можно узнать, какими запросами формируется страница (для веб-девелоперов) и почему она тормозит. И раньше подобный функционал был доступен, но пользоваться журналом запросов не в [...]]]></description>
			<content:encoded><![CDATA[<p><a href="http://habrahabr.ru/blogs/mysql/70435/">оригинал</a>; полная цитата:<br />
Сегодня был неожиданно удивлен, какие удобные штуки таит в себе MySQL.</p>
<p>Хочу представить вашему вниманию фичу MySQL — профайлинг.<br />
Появилась она начиная с версии 5.0.37.</p>
<p>Всего парой запросов можно узнать, какими запросами формируется страница (для веб-девелоперов)<br />
и почему она тормозит.</p>
<p>И раньше подобный функционал был доступен, но пользоваться журналом запросов не в пример сложнее.</p>
<p>Итак, как пользоваться:</p>
<p>mysql> set profiling=1;<br />
mysql> select count(*) from comment;<br />
mysql> select count(*) from message;<br />
mysql> show profiles;</p>
<p>+&#8212;&#8212;&#8212;-+&#8212;&#8212;&#8212;&#8212;+&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;+<br />
| Query_ID | Duration   | Query                        |<br />
+&#8212;&#8212;&#8212;-+&#8212;&#8212;&#8212;&#8212;+&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;+<br />
|        1 | 0.00012700 | select count(*) from comment |<br />
|        2 | 0.00014200 | select count(*) from message |<br />
+&#8212;&#8212;&#8212;-+&#8212;&#8212;&#8212;&#8212;+&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;+<br />
2 rows in set (0.00 sec)</p>
<p>Вуаля! Все выполненные запросы за сессию с временем выполнения.</p>
<p>На мой взгляд очень просто и сверх-удобно.</p>
<p>Можно пойти дальше, и узнать подробно на что тратилось время по каждому запросу:</p>
<p>mysql> show profile for query 1;<br />
+&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8211;+&#8212;&#8212;&#8212;-+<br />
| Status                         | Duration |<br />
+&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8211;+&#8212;&#8212;&#8212;-+<br />
| starting                       | 0.000015 |<br />
| checking query cache for query | 0.000021 |<br />
| checking permissions           | 0.000003 |<br />
| Opening tables                 | 0.000007 |<br />
| System lock                    | 0.000004 |<br />
| Table lock                     | 0.000023 |<br />
| init                           | 0.000005 |<br />
| optimizing                     | 0.000005 |<br />
| executing                      | 0.000025 |<br />
| end                            | 0.000003 |<br />
| end                            | 0.000001 |<br />
| query end                      | 0.000002 |<br />
| storing result in query cache  | 0.000003 |<br />
| freeing items                  | 0.000003 |<br />
| closing tables                 | 0.000004 |<br />
| logging slow query             | 0.000002 |<br />
| cleaning up                    | 0.000001 |<br />
+&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8211;+&#8212;&#8212;&#8212;-+<br />
17 rows in set (0.00 sec)</p>
<p>Подробнее о профайлинге в статье: <a href="http://dev.mysql.com/tech-resources/articles/using-new-query-profiler.html">Using the New MySQL Query Profiler</a></p>
<p>Upd: как точно подметил zayceslavshow profiles по умолчанию показывает профили для 15 запросов. Кол-во запрсов можно увеличить с помощью параметра profiling_history_size, но не более чем до 100.</p>
<p>mysql> set profiling=1;<br />
mysql> set profiling_history_size=100;</p>
]]></content:encoded>
			<wfw:commentRss>http://www.job-blog.bullgare.ru/2009/09/mysql-profiler-%d0%bf%d1%80%d0%be%d1%81%d1%82%d0%be%d0%b9-%d0%b8-%d1%83%d0%b4%d0%be%d0%b1%d0%bd%d1%8b%d0%b9-%d0%b8%d0%bd%d1%81%d1%82%d1%80%d1%83%d0%bc%d0%b5%d0%bd%d1%82-%d0%bf%d1%80%d0%be%d1%84%d0%b8/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Профилирование php-проекта: Xdebug</title>
		<link>http://www.job-blog.bullgare.ru/2009/09/%d0%bf%d1%80%d0%be%d1%84%d0%b8%d0%bb%d0%b8%d1%80%d0%be%d0%b2%d0%b0%d0%bd%d0%b8%d0%b5-php-%d0%bf%d1%80%d0%be%d0%b5%d0%ba%d1%82%d0%b0-xdebug/</link>
		<comments>http://www.job-blog.bullgare.ru/2009/09/%d0%bf%d1%80%d0%be%d1%84%d0%b8%d0%bb%d0%b8%d1%80%d0%be%d0%b2%d0%b0%d0%bd%d0%b8%d0%b5-php-%d0%bf%d1%80%d0%be%d0%b5%d0%ba%d1%82%d0%b0-xdebug/#comments</comments>
		<pubDate>Fri, 18 Sep 2009 11:47:45 +0000</pubDate>
		<dc:creator>admin</dc:creator>
				<category><![CDATA[php]]></category>
		<category><![CDATA[Программирование]]></category>
		<category><![CDATA[серверная оптимизация]]></category>
		<category><![CDATA[bottle-neck]]></category>
		<category><![CDATA[debug]]></category>
		<category><![CDATA[xdebug]]></category>
		<category><![CDATA[бутылочное горлышко]]></category>
		<category><![CDATA[отладка]]></category>
		<category><![CDATA[профилирование]]></category>

		<guid isPermaLink="false">http://www.job-blog.bullgare.ru/?p=240</guid>
		<description><![CDATA[Установка Скачать После помещения библиотеки в папку с расширениями в php.ini надо написать zend_extension = \ext\php_xdebug.dll Далее ставим плагин для firefox &#8211; Xdebug Helper, настройка всего инструментария &#8211; в базе знаний Google Работа с Xdebug под Eclipse ещё про установку и настройку xdebug, Профилирование с Xdebug на habrahabr. Самое основное &#8211; параметр в php.ini xdebug.profiler_enable_trigger=On [...]]]></description>
			<content:encoded><![CDATA[<p><a href="http://www.xdebug.org/docs/install">Установка</a><br />
<a href="http://www.xdebug.org/download.php">Скачать</a><br />
После помещения библиотеки в папку с расширениями в <em>php.ini</em> надо написать</p>
<pre class="code">
zend_extension = <путь-к-php>\ext\php_xdebug.dll
</pre>
<p>Далее ставим плагин для firefox &#8211; <a href="https://addons.mozilla.org/ru/firefox/addon/3960">Xdebug Helper</a>, настройка всего инструментария &#8211; <a href="http://code.google.com/p/syslogr-utils/wiki/XdebugHelper">в базе знаний Google</a><br />
<a href="http://www.phpeclipse.com/wiki/Howto/XDebugAndPHPEclipse">Работа с Xdebug под Eclipse</a><br />
ещё про установку и <a href="http://www.ibm.com/developerworks/ru/library/os-php-xdebug/index.html">настройку xdebug</a>,<br />
<a href="http://habrahabr.ru/blogs/php/31468/">Профилирование с Xdebug на habrahabr</a>.<br />
Самое основное &#8211; параметр в php.ini</p>
<pre class="code">
xdebug.profiler_enable_trigger=On
</pre>
<p>В итоге у меня получилось (php5.3)</p>
<pre class="code">
zend_extension = путь-к-php53\ext\php_xdebug.dll
xdebug.remote_enable=1
xdebug.remote_handler=dbgp
xdebug.remote_mode=req
xdebug.remote_port=9000
xdebug.remote_host=localhost
xdebug.idekey=default

;xdebug.dump_once = On
;xdebug.dump_globals = On
;xdebug.dump_undefined = On
;xdebug.dump.REQUEST = *
;xdebug.dump.SERVER = REQUEST_METHOD,REQUEST_URI,HTTP_USER_AGENT

xdebug.profiler_enable=Off
xdebug.profiler_output_dir="c:\traces"
xdebug.profiler_enable_trigger=On
xdebug.profiler_output_name="cachegrind.out.%R-%t"
</pre>
<p>Теперь достаточно передать в GET-параметре <em>?XDEBUG_PROFILE</em> (вот как раз тут полезен XdebugHelper &#8211; там это можно включить для определённого сайта).<br />
<a href="http://tigor.com.ua/blog/2008/07/21/php-profiler-debugger-xdebug/">много ссылок на полезные статьи</a>.<br />
<a href="http://code.google.com/p/webgrind/">Инструмент для анализа логов Xdebug</a> от создателя.</p>
<p><a href="http://forums.netbeans.org/post-9585.html"><strong>Дебаг проекта</strong> через NetBeans совместно с XdebugHelper</a>:<br />
запустить отладчик в NetBeans и затем нажать кнопку &laquo;run&raquo; (это NetBeans заставит слушать Xdebug), а затем открыть сайт с активированным на нём XdebugHelper&#8217;ом.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.job-blog.bullgare.ru/2009/09/%d0%bf%d1%80%d0%be%d1%84%d0%b8%d0%bb%d0%b8%d1%80%d0%be%d0%b2%d0%b0%d0%bd%d0%b8%d0%b5-php-%d0%bf%d1%80%d0%be%d0%b5%d0%ba%d1%82%d0%b0-xdebug/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Профилирование php-проекта: APD</title>
		<link>http://www.job-blog.bullgare.ru/2009/09/%d0%bf%d1%80%d0%be%d1%84%d0%b8%d0%bb%d0%b8%d1%80%d0%be%d0%b2%d0%b0%d0%bd%d0%b8%d0%b5-php-%d0%bf%d1%80%d0%be%d0%b5%d0%ba%d1%82%d0%b0/</link>
		<comments>http://www.job-blog.bullgare.ru/2009/09/%d0%bf%d1%80%d0%be%d1%84%d0%b8%d0%bb%d0%b8%d1%80%d0%be%d0%b2%d0%b0%d0%bd%d0%b8%d0%b5-php-%d0%bf%d1%80%d0%be%d0%b5%d0%ba%d1%82%d0%b0/#comments</comments>
		<pubDate>Tue, 08 Sep 2009 12:48:26 +0000</pubDate>
		<dc:creator>admin</dc:creator>
				<category><![CDATA[php]]></category>
		<category><![CDATA[Программирование]]></category>
		<category><![CDATA[серверная оптимизация]]></category>
		<category><![CDATA[APD]]></category>
		<category><![CDATA[bottle-neck]]></category>
		<category><![CDATA[бутылочное горлышко]]></category>
		<category><![CDATA[отладка]]></category>
		<category><![CDATA[профилирование]]></category>

		<guid isPermaLink="false">http://www.job-blog.bullgare.ru/?p=192</guid>
		<description><![CDATA[При разработке сайта под большую нагрузку нужно постоянно искать слабые места в коде. К примеру, при добавлении нового функционала на частопосещаемой странице появился кусок кода (функция, метод), который заметно замедляет работу проекта в целом. Нет пределов совершенству, и проект можно вылизывать до бесконечности, но на что стоит обратить внимание &#8211; подскажет профайлер кода. Лично я [...]]]></description>
			<content:encoded><![CDATA[<p>При разработке сайта под большую нагрузку нужно постоянно искать слабые места в коде. К примеру, при добавлении нового функционала на частопосещаемой странице появился кусок кода (функция, метод), который заметно замедляет работу проекта в целом. Нет пределов совершенству, и проект можно вылизывать до бесконечности, но на что стоит обратить внимание &#8211; подскажет профайлер кода. Лично я использую в работе <a href="http://pecl.php.net/package/apd">APD (Advanced PHP Debugger)</a>. Во-первых, он хранится в репозитории модулей PHP, во-вторых, мне понравилось им пользоваться, в-третьих, у автора есть достаточно подробное описание в <a href="http://www.ozon.ru/context/detail/id/2527057/">книге &laquo;Профессиональное программирование на PHP&raquo;</a>, в-четвёртых, простота использования. Из минусов &#8211; давно не обновлялся и, видимо, уже заброшен разработчиком.<br />
<strong>Установка</strong> производится с помощью инсталлятора PEAR</p>
<pre class="code">
#pear install apd
</pre>
<p>После чего в файл php.ini необходимо добавить установленное расширение и произвести настройку. (Приведу для примера параметры для Windows)</p>
<pre class="code">
zend_extension = <Путь к установленному php>\ext\php_apd.dll
apd.dumpdir = c:\apd_traces\ ; здесь будут храниться промежуточные файлы трассировок
apd.statement_trace = 1
</pre>
<p>Если вызвать phpinfo(), должен появиться раздел с параметрами APD.<br />
<strong>Использование</strong>.<br />
Активизируется трассировка путём включения в нужный php-файл вызова функции</p>
<pre class="code">
apd_set_pprof_trace('c:\TEMP\apd_traces');
</pre>
<p>Протоколируется следующие события:</p>
<ul>
<li>вход в функцию</li>
<li>выход из функции</li>
<li>использование инструкций <em>include</em> и <em>require</em></li>
</ul>
<p>.<br />
При этом ведутся 3 счётчика:</p>
<ul>
<li>Real Time &#8211; прошедшее реальное время</li>
<li>User Time &#8211; время, затраченное на пользовательский код</li>
<li>System Time &#8211; время, затраченное на системные вызовы</li>
</ul>
<p>.<br />
После того, как файлы созданы (т.е. скрипт отработал), можно, к примеру, закомментировать строку вызова</p>
<pre class="code">
apd_set_pprof_trace('c:\TEMP\apd_traces');
</pre>
<p>(она больше не нужна).<br />
При установке APD из репозитория в папке<br />
<em><Путь к php>\PEAR\Console\</em> появится файл <em>pprofp</em>.<br />
Далее можно создать файл, к примеру, <em>run.bat</em>:</p>
<pre class="code">
php.exe pprofp -r c:\TEMP\apd_traces\pprof.00288.53 > c:\TEMP\apd_out_rmT.txt
</pre>
<p>где <em>c:\TEMP\apd_traces\pprof.00288.53</em> &#8211; это промежуточный файл трассировок, созданный при выполнении скрипта, а <em>c:\TEMP\apd_out_rmT.txt</em> будет создан и будет содержать полезную информацию в удобной форме.<br />
Можно, конечно, создать и более &laquo;умный&raquo; батник, котороый бы принимал имя промежуточного файла параметром, но статья не об этом.<br />
В итоге в файле увидим время выполнения функций и количество вызовов, что в дальнейшем должно помочь писать более &laquo;быстрый&raquo; код.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.job-blog.bullgare.ru/2009/09/%d0%bf%d1%80%d0%be%d1%84%d0%b8%d0%bb%d0%b8%d1%80%d0%be%d0%b2%d0%b0%d0%bd%d0%b8%d0%b5-php-%d0%bf%d1%80%d0%be%d0%b5%d0%ba%d1%82%d0%b0/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
	</channel>
</rss>

