Posts Tagged: ‘Performance’

High Performance REST Applications (3) – Importing the Starter Project

24. April 2017 Posted by Sven Hasselbach

Now you can import the projects required from Git.

First, go to „File > Import…

Import Project

Then select „Projects from Git“

Projects from Git

and „Clone URI“ to clone an existing repository:

Clone existing respository

To get the URI, you have to open https://github.com/hasselbach/ and select the repository „ch.hasselba.concurrent„. Click the „Clone or download„-Button and copy the URI from the opening box:

Get the repository URI

Paste the URI into the location in Eclipse

Add the URI to Eclipse

In the next dialog, you can choose the branch to import. In this case, only „master“ exists

Select the branch to import

Now you have to choose a local destination where the cloned repository will be stored

Select the local destination

Select „Import existing Eclipse projects„…

Import existing projects

… and select all projects of the repository:

Select all projects

With „Finish„, the sources are downloaded. In the „Project Explorer„, you can see the three imported projects. And you can see the original repository name and the current branch you are working on:

Repository & Branch

The JRE used for the project can be seen if you expand one of the projects. „Sometimes“ this changes magically, and the build will fail – that is one of the first things you have to check if you have errors in a OSGi project.

JRE / Target used for this project

Now, do the same for the „domino-rest-servlet“ repository. But instead importing the „master“ branch, select the „highperformance“ branch only.

Import HighPerformance Branch

That’s it. In the next post, we have take a look in what you have downloaded.

High Performance REST Applications (2) – Dev Environment

23. April 2017 Posted by Sven Hasselbach

Before you can start developing a Servlet as an OSGi Plugins, you must set up a development environment first. To do this, download Eclipse IDE (Eclipse IDE for Java EE Developers) and XPages SDK from OpenNTF (The XPages SDK is a helper to create the JRE environment and the Target Platform). For development it is the best to have a (local) development server, because during development you might want to restart and/or modify it, and debugging is a lot easier if have control over the whole server.

After unpacking Eclipse and the XPages SDK, you have to install it and set up the JRE and the Target Platform. Go to „Help > Install New Software“. With „Add…“, you can add the UpdateSite of the XPages SDK to Eclipse:

Install New Software

Add Update Site

Click on „Local…“, and choose the folder „org.openntf.xsp.sdk.updatesite“ from the unpacked archive. Then give it a name for identification. You can choose whatever you want.

Choose the XPages SDK UpdateSite

Now, choose the plugin, click „OK“, accept the license, allow the installation from unsigned content and restart Eclipse after installation is complete.

Install the Plugin

Next step ist to configure the JRE: Go to „Help > Preferences“, „XPages SDK“, and choose the pathes were your Domino Server is installed. Also choose „Automatically create JRE for Domino“:

Then apply it.

If you have FP8 installed, you don’t need the next step: Change the Complier compliance level to 1.6. Again, apply the setting and allow a full rebuild of the Workspace.

Change the compliance level

Switch the default JRE to the newly created XPages Domino JRE:

Now you have to add the target platform: Enter „target“ in the search field, select the „Target Platform“, and click on „Add“. Choose the „Domino Install Target“, create it and choose it as active platform.

Target Definition: „Domino Install Target“

OK, that’s it. You have a working IDE and you are ready to import the starter project from GitHub.

High Performance REST Applications (1) – Intro

21. April 2017 Posted by Sven Hasselbach

This is a new serie about developing high performance REST applications on top of Domino. It will contain my presentations from SNoUG and EntwicklerCamp this year and describes all required steps to develop, build and deploy these servlets on a basic level.

The code used in this serie is already available at GitHub:

(The high performance part is in a branch of my example Domino REST Servlet described earlier in this blog.)

The serie will start with setting up the development environment, explaining OSGi plugin basics and will then go over how to implement the REST API. Some details about concurrency developments and their problems will also be included. Hopefully it is easy to understand.

Don’t hold back to ask a question in the comments or to contact me directly. I have kicked out the buggy comment plugin last month, so you should be able to post them even when I have updated my wordpress installation.

Relax and enjoy the upcoming posts.

Re: Domino REST performance analysis

16. März 2017 Posted by Sven Hasselbach

I have created a Quick-n-Dirty performance test for Csaba’s „10K record test“:

Loading time 200 ms overall, 60 ms TTFB.

Do you want to know how this works? Feel free to come to SNoUG next week or to Rudi’s EntwicklerCamp and join my sessions about „High Performance REST Applications“.

Mit SoftLayer, an IBM company hoch hinaus im Gaming

26. Oktober 2015 Posted by frank eisenhardt

Was IBMs Cloud-Lösungen wirklich drauf haben

image

 

 

 

 

 

von Salina Gilbert und Christina Pongratz

 

 

 

Performance, das A&O beim Gamen

Performance, Performance, Performance – darauf kommt’s beim Gamen an. Mehr als 140 Millionen Gamer nutzen unbewusst die SoftLayer-Infrastruktur und genau das macht SoftLayer bei Gaming-Unternehmen so beliebt.

Für Spieleentwickler und Publisher kommt es darauf an, dass sie weltweit Gamer erobern, zufrieden stellen und von ihnen profitieren. Wohingegen Gamer erwarten, dass sich die Entwicklungszyklen verkürzen, kein Lagging auftritt und das Spiel auch bei einer hohen Anzahl von Mitspielern reibungslos läuft. Um genau diesen Ansprüchen gerecht zu werden, brauchen Gaming Anbieter eine Infrastruktur mit Performance, Skalier- und Hochverfügbarkeit. IBM macht es möglich!

Mit der SoftLayer Cloud zur perfekten Gaming Lösung

SoftLayer ist die Cloud-Plattform für highperformance Zocker. Games sind einzigartig – so sollten die Server auch sein. Virtualisierte Server sind nicht nur dynamisch skalierbar, sieie bieten auch die Möglichkeit die Anzahl der Kerne, des Speichers,  die Speichertypen und die Kapazität je nach Bedarf anzupassen. Im Gegenzug  kommen die Bare Metal Server dann ins Spiel, wenn es um Gaming Performance geht. Diese steht beim Gamen ganz weit vorne auf der Liste. Vor allem besteht ein Performance-Vorteil, da kein Virtualisierungsoverhead entsteht.  Die Performance kann durch den Einsatz von Bare Metal Servern verbessert werden, welche zudem noch individuell mit Prozessoren, RAM, SSD Festplatten und Netwerkdurchsatz erweitert werden können. Bare Metal ist ein physisch-vorhanderner Server, der dem Nutzer ganz allein zur Verfügung steht. Dadurch entfällt das „Noisy Neighbours“-Phänomen, wo eine unfaire Ressourcenverteilung bei höheren Auslastungen entstehen kann. Was ist noch besser als hervorragende Performance? Wenn sie darüberhinaus noch berechenbar und konsistent ist!

Alle SoftLayer Server und Dienste stehen im Onlineportal per Selbstbedienung oder durch die Programmierschnittstelle (API) zur Verfügung. Dadurch ist es kinderleicht zwischen den virtuellen und Bare Metal Servern zu switchen. Auch zusätzliche Server können hochgefahren werden, um beispielsweise bei hohem Traffic der Nachfrage in Echtzeit gerecht zu werden. Wie sieht’s mit Firewall und Load Balancer aus? Bei SoftLayer sind diese mit nur wenigen Klicks und ohne Downtime installiert.

Wie sehen mögliche Herausforderungen aus und was bietet die IBM Cloud?

Ihr braucht mehr Ressourcen, um den Download-Ansturm beim Launch standzuhalten? Mit SoftLayer ist das kein Problem: Zusätzliche Server stehen auf Abruf bei hohem Datenverkehr bereit und erhöhen somit die Gesamtleistung.

Erstellung von einer Spielumgebung zum Testen, die mit der Produktivversion übereinstimmt? SoftLayer macht’s möglich: In derselben Umgebung kann das Game mit passender Hardware und Konfigurationen auf dem Testsystem getestet und ohne großen Aufwand und Downtime in der Produktivumgebung live geschaltt werden.

Und warum gerade SoftLayer? High Performance und tolle Hardware. Zudem sind die Serverzentren auch global repliziert, was kürzere Antwortzeiten (Latency) für Gamer bedeutet.  Außerdem werden die Server und Dienste pro Stunde oder Monat ohne Vetragslaufzeit abgerechnet – man zahlt nur für das, was man wirklich nutzt. Klingt interessant?

Dann los und ausprobieren – die ersten 30 Tage sind kostenlos: https://ibm.biz/SLTrialATCT

image

 

 

 

 

 

Noch nicht überzeugt? Um euch einen besseren Eindruck zu verschaffen, besucht doch einen von den IBM Gamingdays 2015 in Hamburg, München oder Berlin, unter anderem berichten Koch Media und Big Point  live von ihren erfolgreichen Projekten.

Chance nicht verpassen und jetzt anmelden!

Hamburg am 11. November 2015 – 17 Uhr im Betahaus, Coworking Hamburg – Eifflerstraße 43, 22769 Hamburg. Anmeldung unter http://www.eventbrite.de/e/ibm-gamingday-hamburg-tickets-18843660897

München am 18. November 2015 – 17 Uhr im Wer 1 – Grafinger Straße 6, 81671 München. Anmeldung unter https://www.eventbrite.de/e/ibm-gamingday-munchen-tickets-18843230610

Berlin am 03. Dezember 2015 – 17 Uhr im Ahoy Berlin UG (haftungsbeschränkt) – Windscheidstraße 18, 10627 Berlin. Anmeldung unter https://www.eventbrite.de/e/ibm-gamingday-berlin-tickets-19220439853

Kontakte knüpfen? Austauschen? Dann schauen Sie doch auf unserem nächsten Blog vorbei „Watson, (k)eine Figur aus Sherlock Holmes“.

xsp.application.context.proxy

17. Juni 2015 Posted by Sven Hasselbach

Just a reminder for myself: To use a CDN for XPage resources, you can add a leading slash to the xsp.application.context.proxy property.

xsp.application.context.proxy=/cdn.hasselba.ch

2015-06-17 10_52_08-view-source

 

Performance Optimierung in React

17. April 2015 Posted by Henning Schmidt

Wir bei hedersoft haben lange mit angular gearbeitet und unsere Web- und mobilen Applikationen mit diesem Framework entwickelt. Zuletzt sind wir aber auf erhebliche Performance Probleme gestoßen im Zuge der Entwicklung des User-Cockpits im hs.Crawler. Das User-Cockpit ist ein Frontent zur Bearbeitung von Aufgaben im Scrum Stil. Bei einer geringen Anzahl an zu verwaltenden Aufgaben […]

XPages: Execute Events with HTTP Get

30. September 2014 Posted by Sven Hasselbach

To execute an event on the server, you normally have to send a POST request, because actions will be executed in the Invoke Application phase of the JSF lifecycle. A GET request will only process the Restore View and the Render Response phase, that why you can not execute an event with a GET request.

But with the help of a PhaseListener, the execution can be done earlier in the Restore View phase:

package ch.hasselba.xpages.util;

import javax.faces.event.PhaseEvent;
import javax.faces.event.PhaseId;
import javax.faces.event.PhaseListener;
import com.ibm.xsp.component.xp.XspEventHandler;
import javax.faces.context.ExternalContext;
import javax.faces.context.FacesContext;
import com.ibm.xsp.util.FacesUtil;

public class ExecuteOnServerPhaseListener implements PhaseListener {

    private static final long serialVersionUID = 1L;

    public void beforePhase(PhaseEvent event) {}

    public PhaseId getPhaseId() {
        return PhaseId.RESTORE_VIEW;
    }

    public void afterPhase(PhaseEvent event) {
        
        FacesContextExImpl = FacesContextExImpl.getCurrentInstance();
        ExternalContext ec = fc.getExternalContext();
        String url = ec.getRequestPathInfo();
        String[] pathes = url.split( "/" );
        
        try{
            if( pathes.length > 2 ){
                if( "executeOnServer".equals( pathes[pathes.length -2 ] ) ){
                    String[] fullId = pathes[ pathes.length - 1 ].split(":");
                    String actionId = fullId[ fullId.length - 1 ];
                    XspEventHandler eventHandler = (XspEventHandler)
                        FacesUtil.findComponentWithFullId( fc.getViewRoot(), actionId );
                    if( eventHandler != null ){
                        eventHandler.getAction().invoke( fc, null );
                        fc.responseComplete();
                    }
                }
            }
        }catch(Exception e){
            e.printStackTrace();
        }
        
    }

}

To activate the PhaseListener, it has to be enabled in the faces-config.xml:

<?xml version="1.0" encoding="UTF-8"?>
<faces-config>
   <lifecycle>
      <phase-listener>ch.hasselba.xpages.util.ExecuteOnServerPhaseListener</phase-listener>
   </lifecycle>
</faces-config>

The following Javascript snippet extends the XSP object and adds the new function executeOnServerGet to it. The parameter is the if of the event to invoke.

XSP.executeOnServerGet = function( eventId ){
    var viewId = dojo.query('[name="$$viewid"]')[0].value;
    var url = document.forms[0].action;
    url += "/executeOnServer/" + eventId;
    url += "?$$viewid=" + viewId;
    url += "&$$ajaxid=@none";
    dojo.xhrGet({url: url});
}

When calling the function, it sends a GET request and adds the current view id to the request. With the parameter $$ajaxId set to @none, the XPages Engine is forced to send no HTML code back to the client.

And here is an example XPage:

<?xml version="1.0" encoding="UTF-8"?>
<xp:view xmlns:xp="http://www.ibm.com/xsp/core">

    <xp:eventHandler id="helloworld" event="helloworld" submit="false">
        <xp:this.action>
            <![CDATA[#{javascript:
               print("hello world " + java.lang.System.currentTimeMillis() );
            }]]>
        </xp:this.action>
    </xp:eventHandler>


    <xp:scriptBlock id="scriptBlock1">
        <xp:this.value><![CDATA[
            dojo.addOnLoad( function(){
                XSP.executeOnServerGet = function( eventId ){
                      var viewId = dojo.query('[name="$$viewid"]')[0].value;
                    var url = document.forms[0].action;
                    url += "/executeOnServer/" + eventId;
                    url += "?$$viewid=" + viewId;
                    url += "&$$ajaxid=@none";
                    dojo.xhrGet({url: url});
                  }
            });
        ]]></xp:this.value>
    </xp:scriptBlock>
    
    <xp:button value="Execute" id="button1">
        <xp:eventHandler event="onclick" submit="false">
            <xp:this.script>
                <![CDATA[XSP.executeOnServerGet( "#{id:helloworld}" );]]>
            </xp:this.script>
        </xp:eventHandler>
    </xp:button>
</xp:view>

When clicking the button, the following URL is opened in the background:

http://example.com/db.nsf/EventGet.xsp/executeOnServer/view:_id1:helloworld?$$viewid=!dwjldz64w0!&$$ajaxid=@none

A GET request was sent to the server:If you look on the server console, you will see that the Action was invoked:

IBM i Disk Performance

26. August 2014 Posted by Ralf Petter

One of the most important components of a server is the Disk subsystem. If you need information's how to optimize or analyze the IO performance of your Power System with IBM i, i recommend to watch the presentation "IBM i Disk Performance" from Satid Singkorapoom.

Abstract: This presentation provides technical performance information on Power Systems' internal disk HW subsystem when managed by IBM i and OS/400. You can learn about how IBM i manages disk allocation for data and memory faulting and what IBM i tools are available for use to monitor important IBM i disk performance parameters to identify if performance issue is impending or not and how to handle the issue. Various good performance guidelines are also provided to help you effectively handle this matter.

IBM i Performance FAQ updated.

14. Juni 2014 Posted by Ralf Petter

One of the most valuable source for information's about performance on the IBM i  is the "IBM i Performance FAQ" got and update in June. This document contains many hints about performance topics and links to other IBM performance resources like:
  • What is Performance?
  • How to benchmark performance?
  • How to size as system?
  • Capacity Planning?
  • Proactive Performance Monitoring.
  • Performance Data Collectors and Analysis Tools.
  • Native I/O
  • Compiler Optimization
  • Java
  • Job and Diskwatcher
So be sure to read this document when you need a deep understanding of performance on the IBM i.


Isolation and multi-tenancy in the IBM PureApplication System – Cloud Groups are the NEW Virtual Systems

9. April 2014 Posted by Yathish Kumar

(This is a guest entry posted on behalf of Georg Ember)

Almost any application running in the cloud is designed to share resources. Virtualization is the key enabler for cloud computing in integrated or converged systems. Applications run in the cloud as workloads that share system resources, such as CPU, memory and networking.  However, there are legal or organizational requirements where workloads must be isolated from each other and the key question is: What type of isolation is the right way to protect the application environments from each other?

Isolation (also as know as multi-tenancy) is a key requirement for cloud computing. An application deployed into a cloud environment must be able to run independently and separately from other applications in the cloud. Each application requires it to move traffic along the network and protect its data as well.

Isolation of applications and data, by physical separation or by virtualization within an integrated system, may satisfy security requirements and ensure that a failure of one application will not cause the failure of other applications. While the data has to be kept isolated, in many cases, other departments within a company are not allowed to see deployed resources (Virtual Machines) of other environments.

An ideal solution to implement such an application and virtual systems isolation is to exploit the multi-tenancy features of the IBM PureApplication System.

A comfortable and easy way to isolate LAN, SAN and Server resources, on a physical as well as a logical level in PureApplication System, is to use the concept of Cloud Groups and environment profiles.

Using the isolation techniques that are incorporated within the IBM PureApplication System can help minimize business risks and increase the availability. By selecting nodes to Cloud Groups which are placed in separate chassis modules, the performance and availability of a Cloud Group can be greatly increased.

image

If you are required to isolate applications and data not only on a logical level, the concept of Cloud Groups in the PureApplication Systems is the right choice for you. You do not need to acquire multiple physical systems, except for high availability or disaster recovery reasons, when you need to separate multiple application environments in a multi-tenant infrastructure. PureApplication System offers the concept of dedicated Cloud Groups.

IBM PureApplication System Cloud Groups physically separate:

  • Compute Nodes (server nodes), across IBM Flex Chassis,
  • LANs by defining VLANs (on dedicated LAN ports) and IP groups (IP address ranges),
  • Services running on the System (so called shared services), each Cloud Group can have “private” services running, without affecting other Cloud Groups. Examples of shared services are monitoring, OS updates, Load Balancers and clustered file systems services, just to name a few.
  • Workload (deployment) users, where each user belongs to one or more environment profiles, can deploy an application to the designated Cloud Group, without seeing other deployed resources from other users or being seen by other users on the Cloud Groups.

image

Companies normally separate environments according to application development lifecycle. The typical divisions are:

  • Development (DEV): An environment used for developing applications.
  • Testing (TEST): Used for testing applications.
  • Production (PROD): Used for running applications; this is the realm of business or end users.

Each of these environments typically runs on totally independent sets of hardware and networks to avoid cross-environment issues. But, when using Cloud Groups in the PureApplication System, application environments are totally isolated from each other, if required, even by the users and shared services they use. Consecutively, you do not need to acquire multiple physical systems – one PureApplication System does it all for isolation of application environments. There is full isolation and protection in any layer of the stack.

XPages: Use async / defer option for external CSJS Script Libraries

10. März 2014 Posted by Sven Hasselbach

When adding CSJS libraries to your XPage, try to use the defer or the async option for a better user experience. When not using this options, the Page might be blocked during page load.

Have a look at this example XPage which contains two external CSJS scripts (for demonstration purposes they are computed to get a remote script out of nowhere):

<?xml version="1.0" encoding="UTF-8"?>
<xp:view xmlns:xp="http://www.ibm.com/xsp/core">
    Foo!
    <xp:this.resources>
        <xp:script clientSide="true">
            <xp:this.src>
               <![CDATA[#{javascript:"http://" + @Unique() + ".null";}]]>
            </xp:this.src>
        </xp:script>
    </xp:this.resources>
    <xp:scriptBlock id="scriptBlock1">
        <xp:this.src>
           <![CDATA[#{javascript:"http://" + @Unique() + ".null";}]]>
        </xp:this.src>
    </xp:scriptBlock>
    Bar!
</xp:view>

When opening the XPage, the DOM is blocked, until the operation times out:

The best you can do is to use the async or the defer option of external CSJS scripts. For script blocks, there is an option in the DDE available:

The async option can be set with an attribute:

<xp:this.attrs>
    <xp:attr name="async" value="async" minimized="true" />
</xp:this.attrs>

To use the option for a resource, you must add them as an attribute for both options:

<?xml version="1.0" encoding="UTF-8"?>
<xp:view xmlns:xp="http://www.ibm.com/xsp/core">
    Foo!
    <xp:this.resources>
        <xp:script clientSide="true">
            <xp:this.src>
               <![CDATA[#{javascript:"http://" + @Unique() + ".null";}]]>
            </xp:this.src>
            <xp:this.attrs>
                <xp:attr name="async" value="async" minimized="true" />
            </xp:this.attrs>
        </xp:script>
    </xp:this.resources>
    <xp:scriptBlock id="scriptBlock1" defer="true">
        <xp:this.src>
           <![CDATA[#{javascript:"http://" + @Unique() + ".null";}]]>
        </xp:this.src>
    </xp:scriptBlock>
    Bar!
</xp:view>

There are some other techniques, but this is the simplest way and supported in most browsers:

XPages: Optimized Partial Refreshs (2)

7. März 2014 Posted by Sven Hasselbach

With the Optimized Partial Refresh you can do a lot of nice things: If only a part of the form is sent to the server, only this part of the components in the JSF component tree will be processed. This means that only submitted values are applied, coverted and validated, which can result in less server usage and a better performance.

Normally, if you have two required fields on you XPage and do a Partial Refresh, both fields will have a validation error:

But with this technique, you can choose which component should be refreshed. When clicking of Button Refresh 1, only the first field is marked as a required field:

When filling in the first field, but clicking on Refresh 2

… the value of the first field gets lost, because it was not sent to the server (if a value was already stored there, it won’t get lost). And the second field is marked as required:

This is the example XPage, the CSJS code is moved to the Custom Control ccOptimizedPR.

<?xml version="1.0" encoding="UTF-8"?>
<xp:view
    xmlns:xp="http://www.ibm.com/xsp/core"
    xmlns:xc="http://www.ibm.com/xsp/custom">

    <xc:ccOptimizedPR />

    <xp:div id="refreshMe">
        <xp:messages id="messagesError" />
        <xp:inputText
            id="inputText1"
            value="#{sessionScope.inputText1}">
            <xp:this.validators>
                <xp:validateRequired message="Field 1 is empty!" />
            </xp:this.validators>
        </xp:inputText>
        <xp:inputText
            id="inputText2"
            value="#{sessionScope.inputText2}">
            <xp:this.validators>
                <xp:validateRequired message="Field 2 is empty!" />
            </xp:this.validators>
        </xp:inputText>
    </xp:div>

    <xp:button
        value="Normal Refresh"
        id="buttonNormal">
        <xp:eventHandler
            event="onclick"
            submit="true"
            refreshMode="partial"
            refreshId="refreshMe">
        </xp:eventHandler>
    </xp:button>

    <xp:button
        value="Refresh 1"
        id="buttonCleaned1">
        <xp:eventHandler
            event="onclick"
            submit="false">
            <xp:this.script>
                <![CDATA[
                    XSP.partialRefreshPost(
                        '#{id:refreshMe}',{
                            clearForm: true,
                            additionalFields: ['#{id:inputText1}' ]
                        }
                    );]]>
            </xp:this.script>
        </xp:eventHandler>
    </xp:button>
    <xp:button
        value="Refresh 2"
        id="buttonCleaned2">
        <xp:eventHandler
            event="onclick"
            submit="false">
            <xp:this.script>
                <![CDATA[
                    XSP.partialRefreshPost(
                        '#{id:refreshMe}',{
                            clearForm: true,
                            additionalFields: ['#{id:inputText2}' ]
                        }
                    );]]>
            </xp:this.script>
        </xp:eventHandler>
    </xp:button>

</xp:view>

XPages: Optimized Partial Refreshs

7. März 2014 Posted by Sven Hasselbach

Inspired by the last post of Mark, I have created a small CSJS snippet which allows to optimize the behaviour of a Partial Refresh. Normally, if you execute a Partial Refresh, all elements of a form are sent to the server. Take a look at this XPage:

<?xml version="1.0" encoding="UTF-8"?>
<xp:view xmlns:xp="http://www.ibm.com/xsp/core">

    <xp:inputText
        id="inputText01"
        value="#{sessionScope.inputText01}" />
    <xp:inputText
        id="inputText02"
        value="#{sessionScope.inputText02}" />
    <xp:inputText
        id="inputText03"
        value="#{sessionScope.inputText03}" />
    <xp:inputText
        id="inputText04"
        value="#{sessionScope.inputText04}" />
    <xp:inputText
        id="inputText05"
        value="#{sessionScope.inputText05}" />
    <xp:inputText
        id="inputText06"
        value="#{sessionScope.inputText06}" />
    <xp:inputText
        id="inputText07"
        value="#{sessionScope.inputText07}" />
    <xp:inputText
        id="inputText08"
        value="#{sessionScope.inputText08}" />
    <xp:inputText
        id="inputText09"
        value="#{sessionScope.inputText09}" />
    <xp:inputText
        id="inputText10"
        value="#{sessionScope.inputText10}" >
    </xp:inputText>

    <xp:div id="refreshMe">
        <xp:label
            value="#{javascript:java.lang.System.currentTimeMillis()}"
            id="labelNow" />
    </xp:div>

    <xp:button
        value="Normal Refresh"
        id="buttonNormal">
        <xp:eventHandler
            event="onclick"
            submit="true"
            refreshMode="partial" refreshId="refreshMe">
        </xp:eventHandler>
    </xp:button>

</xp:view>

The button refreshes only a small portion of the XPage, the DIV element refreshMe. It does not require any of the posted field values, it just refreshes the DOM element in the frontend. But when clicking the button, the posted data to the server contain all the fields and their values, which is not necessary in this case.

This is how the request looks like in Firebug (I have prefilled all fields with the values 1..9):

The response of the server is – as expected – the actual HTML code for the refreshed DOM element:

The optimized  version adds the option clearForm to partial refreshs. When using this option, only the XPages internal fields are sent to the server, but DOM will be refreshed correctly:

<xp:button
        value="Cleaned Refresh"
        id="buttonCleaned">
        <xp:eventHandler
            event="onclick"
            submit="false">
            <xp:this.script>
                <![CDATA[
                    XSP.partialRefreshPost(
                        '#{id:refreshMe}',{
                            clearForm: true,
                        }
                    );]]>
            </xp:this.script>
        </xp:eventHandler>
    </xp:button>

Now, the POST looks like this:

But wait, this is useless, you can do a XSP.partialRefreshGet instead!

That’s why there is the second option additionalFields. This allows to define all fields you want to update during the refresh:

<xp:button
        value="Cleaned Refresh"
        id="buttonCleaned">
        <xp:eventHandler
            event="onclick"
            submit="false">
            <xp:this.script>
                <![CDATA[
                    XSP.partialRefreshPost(
                        '#{id:refreshMe}',{
                            clearForm: true,
                            additionalFields: ['#{id:inputText01}',
                                              '#{id:inputText02}' ],
                        }
                    );]]>
            </xp:this.script>
        </xp:eventHandler>
    </xp:button>

When clicking the button now, the specified fields are added to the POST request (and will be updated in the JSF tree:

Here is the snippet (Tested on IE 11, Chrome 33 & FF 27 with ND9 & ND 8.5.3 )

<xp:scriptBlock id="scriptBlockPROptimized">
        <xp:this.value><![CDATA[
XSP.addOnLoad(function(){

    // hijack the existing partial refresh method
    if( !XSP.__partialRefresh ){
        XSP.__partialRefresh = XSP._partialRefresh;
    }

    // add the new one to the XSP object
    XSP._partialRefresh = function x_prfh(method, form, refreshId, options){

        // clear the form?
        if( options.clearForm ){

            // create a new HTML form...
            var newForm = document.createElement( "form" );
            newForm.setAttribute( "method", form.method );
            newForm.setAttribute( "action", form.action );

            // ... and loop all existing fields
            for( var i = 0; i<form.length; i++ ){
                var field = form[i];
                var fieldName = field.name;
                var includeField = false;

                try{

                    // check for addition fields
                    if( options.additionalFields ){
                        includeField = dojo.indexOf(options.additionalFields, fieldName)!=(-1)?true:false;
                    }

                    // only add XPages relevant fields and addtional fields
                    if( fieldName == form.id || fieldName.substr(0,2) == '$$' || includeField ){

                        var newField = null;
                        if( field.options ){
                            // special handling for fields with options
                            for( var j=0; j<field.length; j++ ){
                                if( field.options[j].selected ){
                                    newField = document.createElement( "input" );
                                    newField.setAttribute( "type", "hidden" );
                                    newField.setAttribute( "name", fieldName );
                                    newField.setAttribute( "value", field.options[j].value );
                                    newForm.appendChild( newField );
                                }
                            }
                        }else{
                            // default field handling: just clone the DOM element
                            newField = field.cloneNode( true );
                            newForm.appendChild( newField );
                        }
                    }
                }catch(e){
                    console.log(e);
                }
            }

            // call the original refresh method with the new form
            return XSP.__partialRefresh(method, newForm, refreshId, options);
        }

        XSP.__partialRefresh(method, form, refreshId, options);
    };
});]]></xp:this.value>
    </xp:scriptBlock>

Just add the script block above to your XPage, or move it into a CSJS library. But keep in mind that you have to think twice when removing data from the request. It can lead in an inconsistence between the data in the client and the data stored in the component tree on the server.

Neue Version des NRPC Parser auf OpenNTF

11. November 2013 Posted by Ralf Petter

Eines meiner wichtigsten Werkzeuge zur Optimierung von Domino Performance Problemen wurde aktualisiert. Die neue Version des NRPC Parser 1.0.12 kann jetzt mit der Angabe der Thread ID in neueren Versionen von Notes umgehen. Eine Beschreibung wie man den NRPC Parser verwenden kann, findet man unter Lösen von Notes Performanceproblemen mit dem NRPC Parser.

Downloaden kann man man das Tool unter http://www.openntf.org/Projects/pmt.nsf/ProjectLookup/NotesRPCParser


Wer es noch nicht kennt, sollte es unbedingt mal probieren. Es kann einen wirklich die Augen öffnen, wo in Anwendungen die größten Bremser sind.