Performance and scalability are crucial business requirements that can determine the success or failure of a project. Thus performance expectations must be clearly defined on project inception, and we should consider the performance implications of design decisions throughout the project lifecycle. As this is such an important consideration, I have discussed the performance and scalability implications of each major design choice covered throughout this tutorial. There is usually some scope to improve an app's performance through optimization, even when it is functionally complete, but because high-level design decisions have such an impact on the performance of J2EE apps, it's often impossible to achieve really significant improvements at such a late stage. We've seen the importance of basing performance-driven design choices on hard evidence, rather than hunches. We've look at using load-testing tools and profiling tools to enable us to gather evidence about performance and throughput, and seen some practical examples. We've seen that such testing should not be left until the end of the project lifecycle, and that "vertical slices" of app functionality should be implemented early to verify that performance targets can be met. We've looked at some techniques for addressing performance problems, including:

We also discussed code-level optimization, although this will usually produce limited returns in J2EE apps unless app code is particularly inefficient to begin with. We've looked at the unique performance problems of distributed apps. Remote method invocation is many times slower than local method invocation, so it's vital to minimize the number of remote calls in distributed apps and minimize the total amount of data exchanged across network boundaries. We've also looked at some web-tier performance issues. We've seen some benchmarks comparing the performance of some of the web view technologies discussed in . We've examined how proxy and browser caching can reduce the load on and improve the performance of web containers, and how we can use HTTP headers to make this more likely. Finally, we looked at some common causes of performance problems in J2EE apps, and the lessons we should draw from them.


With a few J2EE projects under your belt, you'll develop a fairly reliable instinct for sniffing out potential performance problems. However, regardless of your level of experience, it's important to base decisions empirically.