<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0">
    <channel>
        <title>eduardolundgren.com - JavaScript, Web, Programming, Life.</title>
        <description><![CDATA[eduardolundgren.com - JavaScript, Web, Programming, Life.]]></description>
        <link>http://eduardolundgren.com/</link>
        <lastBuildDate>Fri, 27 Mar 2009 11:43:12 +0100</lastBuildDate>
        <generator>eduardolundgren.com</generator>
        <image>
            <url>http://eduardolundgren.com/img/logo-blog-estrela.png</url>
            <title>eduardolundgren.com</title>
            <link>http://eduardolundgren.com/</link>
        </image>
        <webMaster>Eduardo Lundgren</webMaster>
        <item>
            <title>Liferay PortletURL in JavaScript</title>
            <link>/blog/2009/03/27/liferay-portleturl-in-javascript</link>
            <description><![CDATA[<p>Each more we feel the need of becoming more and more web 2.0, it
sounds like a physics law to the "guys" that are trying to survivor
arround the amazing applications that surround us across the urls.</p><p>Since
few months ago I want to blog post about the new Liferay functionality
that let you build PortletURLs using JavaScript only.</p><p>There are
many places you can apply this new way of generating PortletURLs.
Imagine a big list of links on your portlet, instead of download
repeated hundreds urls from the server site you can simply create a
javascript function that retuns a PortletURL instance and set on the
fly the parameters you need. And now, you can simply integrate your
pure javascript files (.js) with PortletURLs, without over passing it
as parameter for your javascript constructor or another work-arround
came from our misterious mind.</p><p>The usage of this functionality using JavaScript is very simple:</p><div class="colored javascript"><pre>var portletURL = new Liferay.PortletURL();
portletURL.setParameter("key1", "value");
portletURL.setParameter("key2", "value");
portletURL.setPortletId(86);

alert( "that is the url: " + portletURL.toString() );</pre></div><p>&nbsp;</p><p>If
you want to know what methods you can play with the JavaScript
Liferay.PortletURL you can take a quick look on the methods below:</p><p>&nbsp;</p><div class="colored javascript"><pre>setCopyCurrentRenderParameters: function(copyCurrentRenderParameters);
setDoAsUserId: function(doAsUserId);
setEncrypt: function(encrypt);
setEscapeXML: function(escapeXML);
setLifecycle: function(lifecycle);
setName: function(name);
setParameter: function(key, value);
setPlid: function(plid);
setPortletConfiguration: function(portletConfiguration);
setPortletId: function(portletId);
setPortletMode: function(portletMode);
setResourceId: function(resourceId);
setSecure: function(secure);
setWindowState: function(windowState);
toString: function();</pre></div><p>&nbsp;</p><p>I've also created some shortcuts for diferent kind of urls on the portal:</p><p>&nbsp;</p><div class="colored javascript"><pre>var actionURL = Liferay.PortletURL.createActionURL(); // = new Liferay.PortletURL('ACTION_PHASE');

var renderURL = Liferay.PortletURL.createRenderURL(); // = new Liferay.PortletURL('RENDER_PHASE');

var resourceURL = Liferay.PortletURL.createResourceURL(); // = new Liferay.PortletURL('RESOURCE_PHASE');

var permissionURL = Liferay.PortletURL.createPermissionURL(portletResource, modelResource, modelResourceDescription, resourcePrimKey);<pre></pre></pre></div><p>&nbsp;</p><p>&nbsp;I hope it helps. </p>]]></description>
            <author>Eduardo Lundgren</author>
            <category>Liferay</category>
            <pubDate>Fri, 27 Mar 2009 16:43:11 +0100</pubDate>
            <guid>42</guid>
        </item>
        <item>
            <title>Best Practices for Speeding Up Liferay</title>
            <link>/blog/2009/03/27/best-practices-for-speeding-up-liferay</link>
            <description><![CDATA[<p>Only 5% of the end-user response time is spent fetching the HTML document. This result holds true for almost all web sites. The most part of websites spend less than 20% of the total response time getting the HTML document. The other 80+% of the time is spent dealing with what's in the HTML document, namely, the front-end. That's why the key to faster web sites is to focus on improving front-end performance. (thanks <a href="http://developer.yahoo.com/performance/" target="_blank">YAHOO!</a>)<br />
<br />
There are three main reasons why front-end performance is the place to start.</p>
<ul>
    <li>There is more potential for improvement by focusing on the front-end. Cutting it in half reduces response times by 40% or more, whereas cutting back-end performance in half results in less than a 10% reduction.</li>
    <li>Front-end improvements typically require less time and resources than back-end projects (redesigning application architecture and code, finding and optimizing critical code paths, adding or modifying hardware, distributing databases, etc.).</li>
    <li>Front-end performance tuning has been proven to work.</li>
</ul>
<p><br />
The performance golden rule is: optimize front-end performance first, that's where 80% or more of the end-user response time is spent.</p>
<p>Based on this "golden rules" me and Brian Chan decided (while the New Year's Eve party) to give a New Year's present for Liferay community and start a serie of performance improvements on our front-end.</p>
<p>&nbsp;</p>
<p><b><span style="font-size: larger;">1. Using CSS Sprites</span></b></p>
<p>CSS&nbsp;Sprites are the preferred method for reducing the number of image requests. Combine your background images into a single image and use the CSS <code>background-image</code> and <code>background-position</code> properties to display the desired image segment.</p>
<p>We have a new property called <code>theme.images.fast.load</code>. Defaults to true in normal usage and false in development. When the server startups, two files are automatically created on each image folder of your theme ".sprite.png" and ".sprite.properties". These files are only recreated if needed. The taglibs are programmed to know to automatically read the "packed.sprite" and display that relative file on the "packed.png" if this feature is enabled.</p>
<p><b>packed.png</b>:</p>
<div style="overflow: auto; width: 100px; height: 100px;"><img src="http://cdn.www.liferay.com/image/image_gallery?uuid=674803c1-001c-44b9-a564-fdef5cadfdaf&amp;groupId=981120&amp;t=1231204379375" height="276" width="16" /></div>
<p>&nbsp;</p>
<p>&nbsp;<br />
<b> packed.sprite</b>:<br />
arrows/01_down.png=0,16,16<br />
arrows/01_left.png=16,16,16<br />
arrows/01_minus.png=32,16,16<br />
arrows/01_plus.png=48,16,16<br />
...</p>
<p><br />
This will significantly enhance load time (<a href="http://css-tricks.com/css-sprites-what-they-are-why-theyre-cool-and-how-to-use-them/">http://css-tricks.com/css-sprites-what-they-are-why-theyre-cool-and-how-to-use-them/</a>).</p>
<p>You can perceive the benefits when you see <code>theme.images.fast.load</code> in action, In a very simple page the number of requests decrease from 59 to 33 and the load time from 885ms to 811ms, in a big page with a lot of contents and hundreds of images it will cause a huge difference.</p>
<p style="text-align: center; overflow:auto;"><img src="http://cdn.www.liferay.com/image/image_gallery?uuid=87aac1ab-931c-4f00-b878-6730d44c338f&amp;groupId=981120&amp;t=1231203255784" height="242" width="735" /><br />
&nbsp;( without using <code>theme.images.fast.load</code> )</p>
<p style="text-align: center; overflow:auto;"><br />
<img src="http://cdn.www.liferay.com/image/image_gallery?uuid=bd7a282c-b178-48a5-aade-1f2805a9bdc8&amp;groupId=981120&amp;t=1231203913204" height="239" width="733" /><br />
&nbsp; ( using <code>theme.images.fast.load</code> )</p>
<p style="text-align: center;">&nbsp;</p>
<p style="text-align: left;"><b><span style="font-size: larger;">&nbsp;2. Cache Filter: Caching Strip Filter and Compress filter</span></b></p>
<p style="text-align: left;">Liferay Portal take advantage of server filters to manipulate headers, strip spaces from the content and even for gzip the content. These filters are doing a good job actually, however, these filters can run us into a problem. Filters are applied on each file on each request, it's very expensive for the server for both processing and memory.</p>
<p style="text-align: left;">In the old scenario, basically, the first filter applied was the Header Filter that is the most important because it saves the cache on the client-side, after the Strip&nbsp;Filter and the Compress Filter were being applied.</p>
<p style="text-align: center;"><img src="http://cdn.www.liferay.com/image/image_gallery?uuid=b715deca-f99d-4bfe-8a94-863ac078b146&amp;groupId=981120&amp;t=1231355049511" height="209" width="323" /><br />
( Old scenario - Represents the priority/order without CacheFilter )</p>
<p style="text-align: left;">Now, in the new scenario, the CacheFilter instead of compressing / stripping per request on static data that has not changed, we know cache the bytes and content encoding and fetch it if the original data has not changed.</p>
<p style="text-align: center;"><img src="http://cdn.www.liferay.com/image/image_gallery?uuid=82da1715-5b65-4b9b-bc2d-4ee029516bc7&amp;groupId=981120&amp;t=1231206659410" height="214" width="469" /><br />
( New scenario - Represents the priority with CacheFilter )</p>
<p style="text-align: left;">This brings significant performance improvements to the server. This filter is cached on the server, it means - all users will take advantage of this technics, for instance, saving 50ms per request, and if the server has an avarage of 10000 request/hour this server will save 500000ms/hour (8.3 minutes/hour) of processing.</p>
<p style="text-align: left;">The graphic below resumes local tests I did today. Basically, the graphic compares how many milliseconds are spent when the filter are being used and when it's not, for different file sizes requests.</p>
<p style="text-align: center; overflow:auto;"><img src="http://cdn.www.liferay.com/image/image_gallery?uuid=9239b3b7-ed40-457d-9721-022cb96bbf60&amp;groupId=981120&amp;t=1231207599217" height="349" width="612" /></p>
<p style="text-align: left;">The results are promising, we need the community's help to test and see this improvements in action on live websites on a real enviroment.</p>
<p style="text-align: left;">&nbsp;</p>
<p style="text-align: left;"><b><span style="font-size: larger;">3. Put Scripts at the Bottom<br />
</span></b></p>
<p style="text-align: left;">The problem caused by scripts is that they block parallel downloads. The <a href="http://www.w3.org/Protocols/rfc2616/rfc2616-sec8.html#sec8.1.4">HTTP/1.1 specification</a> suggests that browsers download no more than two components in parallel per hostname. If you serve your images from multiple hostnames, you can get more than two downloads to occur in parallel. While a script is downloading, however, the browser won't start any other downloads, even on different hostnames.</p>
<p style="text-align: left;">We recommend if possible you use <footer-portlet-javascript> instead of <header-portlet-javascript> in your liferay-portlet.xml. By this way, we download the unecessary JavaScripts as after as possible.</header-portlet-javascript></footer-portlet-javascript></p>
<p style="text-align: left;">It's important to remember that Stylesheets should be on top (<a href="http://developer.yahoo.com/performance/rules.html#css_top" target="_blank">vide, YAHOO</a>).</p>
<p style="text-align: left;">&nbsp;</p>
<p style="text-align: left;"><b><span style="font-size: larger;">4. For static components using "Never expire" header</span></b></p>
<p>There are two things in this rule:</p>
<ul>
    <li class="bullist">For static components: implement "Never expire" policy by setting far future <code>Expires</code> header</li>
    <li class="bullist">For dynamic components: use an appropriate <code>Cache-Control</code> header to help the browser with conditional requests</li>
</ul>
<p>A first-time visitor to your page may have to make several HTTP requests, but by using the Expires header you make those components cacheable. This avoids unnecessary HTTP requests on subsequent page views. Expires headers are most often used with images, but they should be used on <i>all</i> components including scripts, stylesheets, and Flash components.</p>
<p>Browsers use a cache to reduce the number and size of HTTP requests, making web pages load faster. A web server uses the Expires header in the HTTP response to tell the client how long a component can be cached. Keep in mind, if you use a far future Expires header you have to change the component's filename whenever the component changes. Or concatenate timestamps to the url.</p>
<p>Using a far future Expires header affects page views only after a user has already visited your site. It has no effect on the number of HTTP requests when a user visits your site for the first time and the browser's cache is empty. Therefore the impact of this performance improvement depends on how often users hit your pages with a primed cache. (A "primed cache" already contains all of the components in the page.) The number of page views with a primed cache is 75-85%. By using a far future Expires header, you increase the number of components that are cached by the browser and re-used on subsequent page views without sending a single byte over the user's Internet connection.</p>
<p>&nbsp;</p>
<p>These are the most important stuffs we worked on these first days of 2009.<br />
I'm sure these are important steps for improving the UI&nbsp;performance and they sounds like prosperation for our product.</p>
<p>Thank you guys!</p><p><a target="_blank" href="http://www.liferay.com/web/elundgren/blog/-/blogs/best-practices-for-speeding-up-liferay">Click here to see the original post on my Liferay Blog</a></p>]]></description>
            <author>Eduardo Lundgren</author>
            <category>Liferay</category>
            <pubDate>Fri, 27 Mar 2009 16:28:37 +0100</pubDate>
            <guid>41</guid>
        </item>
        <item>
            <title>Blog is up again with a new domain</title>
            <link>/blog/2009/03/24/blog-is-up-again-with-a-new-domain</link>
            <description><![CDATA[<p>Hi all, after few months with the blog down, I decided to buy a new server and put it up again in a new domain (eduardolundgren.com), I would like to share my ideas and projects with the JavaScript community again.</p><p>Thank you.</p>]]></description>
            <author>Eduardo Lundgren</author>
            <category>Blog</category>
            <pubDate>Tue, 24 Mar 2009 07:15:56 +0100</pubDate>
            <guid>40</guid>
        </item>
        <item>
            <title>What is the best way to inject wbr tags inside a long word?</title>
            <link>/blog/2008/05/15/what-is-the-best-way-to-inject-wbr-tags-inside-a-long-word</link>
            <description><![CDATA[<p>The <wbr /> tag means: <span style="font-style: italic;">"The browser may insert a line break here, if it wishes." It the browser does not think a line break necessary nothing happens"</span> - <a target="_blank" href="http://www.quirksmode.org/oddsandends/wbr.html">Check the overhauling on ppk</a>.</p><p>If you type a <span style="font-weight: bold;">looooooooooooooooong </span>word
on google talk of Gmail it injects <wbr /> tags from 15 by 15. We
know there is a lot of ways to write a solution to do it, some of them
looking for a better performance another looking for elegance.<br /><br />I
was wondering how is the best way to insert <wbr /> tags inside a
long string, off course, the solution can be used to insert any piece
of string inside another.<br /><br />

The first solution I found have a better performance:</p>

<div class="colored javascript"><code></code><pre>function wbr(str, r) {<br />	r = r || 15;<br />    var t = str.length, out = "";<br />   <br />    for (var i = 0; i &lt; Math.ceil(t/r); i++)<br />        out = [ out, [str.slice(i*r, i*r+r), i*r+r &gt;= t ? "" : "<wbr />"].join("") ].join("");<br />   <br />    return out;<br />};<br /></pre></div><p>

<br /><br />

The second, is more elegant, but have a worse performance:</p>

<div class="colored javascript"><code></code><pre>function wbr2(str) {<br />	var wbr = "<wbr />", r = arguments[1] || 15, i = 1, out = "";<br />	<br />	str.replace(/(.{1})/g, function(piece) {<br />		out = [out, piece, i++%r==0 ? wbr : "" ].join("");<br />	});<br />	<br />	return out;<br />} <br /></pre></div><p>

<br /><br />Trying some of the functions above:</p>

<div class="colored javascript">// the first solution
//alert( wbr("abcdefghij", 5) );

// the second
alert( wbr2("abcdefghij", 5) );
</div><p>

<br /><span style="font-weight: bold; font-size: x-small;">Do you have another intresting way to do this injection?</span> <br />I'm eager to know your ideas!<br /></p>

<hr /><p><br />

After a quick chat with <a target="_blank" href="http://ejohn.org/">John Resig</a> he gave me in amazing <span style="font-weight: bold;">3 minutes</span> another way to do it, check his idea below: (thanks John!)</p>

<div class="colored javascript">function wbr_john(str, num) { 
	return str.replace(RegExp("(\\w{" + num + "})([^\\b])", "g"), function(all,text,char){
		return text + "<wbr />" + char;
	});
}
</div>]]></description>
            <author>Eduardo Lundgren</author>
            <category>jQuery UI</category>
            <pubDate>Tue, 24 Mar 2009 07:07:32 +0100</pubDate>
            <guid>39</guid>
        </item>
    </channel>
</rss>
