Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

docs: optimizing frontend apps touchups #3574

Merged
merged 4 commits into from
Jan 10, 2025
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
28 changes: 22 additions & 6 deletions apps/docs/src/guide/transactions/optimizing-frontend-apps.md
Original file line number Diff line number Diff line change
@@ -1,10 +1,10 @@
# Optimizing Frontend Apps

Your application must perform a series of operations to estimate, submit and receive the result of a transaction. However, the flow in which it performs these actions can be organized or performed optimistically in order to optimize the perceived speed of transactions for your users.
Your application must perform a series of operations to estimate, submit and receive the result of a transaction. However, the flow in which it performs these actions can be organized or performed optimistically, increasing it's perceived speed.

In a frontend application, imagine we have a button that executes a contract call:
## Use Case

> **Note:** This is a generic and framework agnostic example, for a React snippet check out the [React Advanced Example](/guide/getting-started/react-example.md#advanced-example).
In a frontend application, imagine we have a button that executes a contract call:

```tsx
<Button onClick={handleSubmit}>Submit</Button>
Expand All @@ -14,10 +14,26 @@ The handler would be implemented as follows:

<<< @./snippets/transaction-speed/transaction-speed-init.ts#main{ts:line-numbers}

Once the user presses the button, the contract call is executed and the transaction is estimated, funded, submitted and multiple calls are made to the network. With optimizations, the flow can be organized as follows:
Once the user clicks the button, multiple sequential calls are made to the network, which can take long, because the transaction must be:

1. Estimated
1. Funded
1. Submitted

## Optimization Strategy

With a few optimizations, the flow can be organized as follows:

<<< @./snippets/transaction-speed/transaction-speed-optimized.ts#main{ts:line-numbers}

Now, we have moved all the transaction preparation to happen on page load. So when the user presses the button, they only need to sign and submit the transaction. This vastly improves the perceived speed of the transaction.
## Conclusion

Then, when users click the button, they only need to sign and submit the transaction, which vastly improves the perceived speed of the transaction because many of the necessary requests were done upfront, under the hood.

Just remember:

- _After preparation, any changes made to the transaction request will require it to be re-estimated and re-funded before it can be signed and submitted._

# See Also

> **Note:** Any changes or additions made to the transaction request after preparation, will mean that the transaction will need to be re-estimated and re-funded before it can be submitted.
- Check a full example at [React Advanced Example](/guide/getting-started/react-example#advanced-example)
Original file line number Diff line number Diff line change
Expand Up @@ -8,19 +8,19 @@ const { info } = console;
// Initialize the provider, sender and the contract
const provider = new Provider(LOCAL_NETWORK_URL);
const wallet = Wallet.fromPrivateKey(WALLET_PVT_KEY, provider);

const deployTx = await CounterFactory.deploy(wallet);
const { contract } = await deployTx.waitForResult();

// #region main
async function handleSubmit() {
// Calling the `call` function for a contract method will create a
// transaction request using the contract call, estimate, fund and then
// submit it to the network
// 1. Calling the `call` function for a contract method will create
// a transaction request, estimate it, fund it and then submit it
const transaction = await contract.functions.increment_count(1).call();
info(`Transaction ID Submitted: ${transaction.transactionId}`);

// Calling `waitForResult` will wait for the transaction to settle and
// will build it's response
// 2. Calling `waitForResult` will wait for the transaction to
// settle, then assemble and return it
const result = await transaction.waitForResult();
info(`Transaction ID Successful: ${result.transactionId}`);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,30 +9,41 @@ const { info } = console;
// Initialize the provider, sender and the contract
const provider = new Provider(LOCAL_NETWORK_URL);
const chainId = await provider.getChainId();

const wallet = Wallet.fromPrivateKey(WALLET_PVT_KEY, provider);
const deployTx = await CounterFactory.deploy(wallet);

const { contract } = await deployTx.waitForResult();

let request: ScriptTransactionRequest;
// #region main
/**
* Here we'll prepare our transaction upfront on page load, so that
* by the time the user interacts with your app (i.e., clicking a btn),
* the transaction is ready to be signed and submitted.
*/
async function onPageLoad() {
// On page load, we will create a transaction request for the contract call
// 1. Create the transaction request for the contract call
request = await contract.functions.increment_count(1).getTransactionRequest();

// Then we will estimate and fund the transaction so it is fully prepared for submission
// 2. Estimate and fund the transaction so it is ready for submission
await request.estimateAndFund(wallet);
}

/**
* By the time user user clicks the submit button, they can just
* sign the finalized transaction and submit it.
*/
async function handleSubmit() {
// When the user presses the submit button, the user can now sign the finalized transaction
// 1. Sign the transaction with the wallet
const signature = await wallet.signTransaction(request);
request.updateWitnessByOwner(wallet.address, signature);

// And we can solely submit the transaction to the network
// 2. Submit the transaction to the network
info(`Transaction ID Submitted: ${await request.getTransactionId(chainId)}`);
const response = await provider.sendTransaction(request);

// We can then wait for the transaction to settle and get the result
// 3. Wait for the transaction to settle and get the result
const result = await response.waitForResult();
info(`Transaction ID Successful: ${result.id}`);
}
Expand Down
Loading