About LazyLoad
In web application, sometimes the retrieve of data is really slow. Users will feel our web site is slow if we sent web page only after the data is fully processed.
For example, I'm doing a little web application project. It has a feature that sync with GMail inbox, and I want there is a badge on preference page, tell user if we connected to GMail IMAP server successfully.
In this case, its better show the page to user immediately, and update the connection status when the connection to IMAP is done.
Of course, this could be done via JavaScript / AJAX. But Lift has alreday provide us something called LazyLoad snippet. Using this snippet, we don't need to handle JavaScript ourself. We just foucs on the bussiness logic.
If there is no LazyLoad
At first, assuming we have a snippet that could get connection status of GMail IMAP:
class GMailStatus extends JSImplicit {
def render = {
println("Start receive...")
// We use Thread.sleep to simulate the connection to IMAP.
Thread.sleep(30 * 1000)
println("Done")
// Replace the text of HTML tag which has id="gmailStatus" in template to
// "Connection OK"
"#gmailStatus" #> "Connection OK"
}
}
When we implement the above snippet, we just wrap it in a <div> tag in our HTML template. Lift will passed its children HTML node to the snippet, and process it according to our replace rule in snippet.
<html>
<head>
<script src="/bootstrap/js/jquery.js"></script>
</head>
<body>
GMail Status:
<div data-lift="GMailStatus">
<div id="gmailStatus">This text will be replaced.</div>
</div>
</body>
</html>
Now, you should get a "Connection OK" message when you visit this page, but it will take 30 seconds before you could see anything.
Using LazyLoad to prevent waiting
Of course, let user wait 30 seconds is not practical in any web application.
But don't worried about that, Lift provides us a called LazyLoad let make your snippet lazy loading. It is just a normal snippet like our GMailStatus, that means it is easily to use:
BTW, you need include jQuery library to your page if you want using LazyLoad. LazyLoad use jQuery to do JavaScript / AJAX work.
<html>
<head>
<script src="/bootstrap/js/jquery.js"></script>
</head>
<body>
GMail Status:
<div data-lift="LazyLoad">
<div data-lift="GMailStatus2">
<div id="gmailStatus">This text will be replaced.</div>
</div>
</div>
</body>
</html>
Yap, just wrapping it outside our snippet. We don't need to change any code of our snippet, we just called LazyLoad, and put our snippet invoke inside it.
Now if we visit that page, we will get our web page immediately, and there will be a Loading message appears on the div block of LazyLoad.
When GMailStatus is finished, it will update the loading message to our content.
Custom Template of LazyLoad
Well, that Loading message is ugly. But that is fine, LazyLoad allows you using a custom loading message template. Just like other templates, you just put it under webapps/template-hidden/.
If we want replace the Loading text to Ajax spinner, what we need to do is create a file named webapps/template-hidden/lazyLoading.html, which has the following content:
<img src="/img/loading.gif" alt="讀取中"/>
And when we call LazyLoad, give it a template attribute:
<html>
<head>
<script src="/bootstrap/js/jquery.js"></script>
</head>
<body>
GMail Status:
<div data-lift="LazyLoad?template=lazyLoading">
<div data-lift="GMailStatus">
<div id="gmailStatus">This text will be replaced.</div>
</div>
</div>
</body>
</html>
After that, we will get a spinner image instead of text when we visit that page.
Conclusion
- When your snippet is time-consuming, it's better wrap it using LazyLoad.
- Include jQuery library to your page when you use LazyLoad.
- You could use template attribute to customize your loading message.
回響