Web Application Performance Design Inspection Checklist
From Guidance Share
J.D. Meier, Srinath Vasireddy, Ashish Babbar, and Alex Mackman
Contents |
[edit]
Deployment and Infrastructure
- Use distributed architectures appropriately. Do not introduce distribution unnecessarily.
- Carefully select appropriate distributed communication mechanisms.
- Locate components that interact frequently within the same boundary or as close to each other as possible.
- Take infrastructure restrictions into account in your design.
- Consider network bandwidth restrictions.
- Identify resource restrictions.
- Ensure your design does not prevent you from scaling up.
- Ensure your design does not prevent you from scaling out and it uses logical layers, does not unwittingly introduce affinity, and supports load balancing.
[edit]
Coupling and Cohesion
- Ensure your design is loosely coupled.
- Exhibit appropriate degrees of cohesion in your design and group together logically related entities, such as classes and methods.
- Restrict use of late binding and only use late binding where it is necessary and appropriate.
[edit]
Communication
- Interfaces do not enforce chatty communication.
- Ensure your application only makes remote calls where necessary. Impact is minimized by client-side validation, client-side caching, and batching of work.
- Optimize remote data exchange.
- Choose appropriate secure communication mechanisms.
- Use message queues to decouple component parts of your system.
- Mitigate the impact of long-running calls by using message queues, "fire-and forget" approaches, and asynchronous method calls.
- Do not use processes where application domains are more appropriate.
[edit]
Concurrency
- In your application do not create threads on a per-request basis, and use the common language runtime (CLR) thread pool instead.
- Only types that need to be thread-safe are made thread-safe.
- Carefully consider lock granularity..
- Ensure your application acquires shared resources and locks late and releases them early to reduce contention.
- Choose appropriate synchronization primitives.
- Choose an appropriate transaction isolation level.
- Ensure your application uses asynchronous execution for I/O bound tasks and not for CPU bound tasks.
[edit]
Resource Management
- Ensure your design supports and makes effective use of pooling.
- Ensure your application acquires resources late and releases them early.
[edit]
Caching
- Use caching for data that is expensive to retrieve, compute, and render.
- Cache appropriate data such as relatively static Web pages, specific items of output data, stored procedure parameters, and query results.
- Do not use caching for data that is too volatile.
- Select an appropriate cache location.
- Select an appropriate cache expiration policy.
[edit]
State Management
- Your design favors stateless components. Or, you considered the negative impact on scalability if you decided to use stateful components.
- If you use Microsoft® .NET Framework remoting and need to support load balancing, you use single call server-activated objects (SAO).
- If you use Web services, you also use a message-based stateless programming model.
- If you use Enterprise Services, also use stateless components to facilitate object pooling.
- Objects that you want to store in state stores support serialization.
- Consider the performance impact of view state.
- Use statistics relating to the number of concurrent sessions and average session data per user to help choose an appropriate session state store.
[edit]
Data Structures and Algorithms
- Ensure your design uses appropriate data structures.
- Use custom collections only where absolutely necessary.
- Extend the IEnumerable interface for your custom collections.
[edit]
Data Access
- Pass data across the layers by using the most appropriate data format. Carefully consider the performance implications.
- Use stored procedures with the Parameters collection for data access.
- Only process the data that is required.
- Where appropriate, provide data paging solutions for large result sets.
- Use Enterprise Services declarative transactions for transactions that span multiple resource managers or where you need to flow transaction context across components.
- If you manipulate binary large objects (BLOBs), use appropriate chunking techniques, and do not repeatedly move the same BLOB.
- Consolidate repeated data access code into helper classes.
[edit]
Exception Handling
- Do not use exceptions to control regular application flow.
- Use well-defined exception handling boundaries.
- Structured exception handling is the preferred error handling mechanism. Do not rely on error codes.
- Only catch exceptions for a specific reason and when it is required.
[edit]
Class Design Considerations
- Classes own the data that they act upon.
- Do not use explicit interfaces unnecessarily. Use explicit interfaces for versioning and for polymorphism where you have common functionality across multiple classes.
- Classes do not contain virtual methods when they are not needed.
- Prefer overloaded methods to methods that take variable parameters.