So I finally got back to my office and found the project I told you about.
As I said, I use Browsershot to create a PDF from a route that renders a Inertia/Vue page. So it has to wait for JavaScript boot time.
The simplified script to test in isolation I wrote is this:
<?php
use Illuminate\Support\Facades\Artisan;
use Illuminate\Support\Facades\Config;
use Spatie\Browsershot\Browsershot;
Artisan::command('app:pdf', function () {
// model I need to render the page
$estimate = \App\Models\Estimate::query()->find(1);
// As the route has sensitive data, I have a simple
// token guard on it, to prevent unauthorized access
$token = Config::get('services.pdf.token');
$url = route('estimates.pdf', ['estimate' => $estimate->getRouteKey(), 'api_token' => $token]);
foreach (range(1, 30) as $index) {
$filename = storage_path("app/test-{$index}.pdf");
$start = microtime(true);
Browsershot::url($url)
->paperSize(210, 297)
->setOption('margin', 'none')
->setOption('preferCSSPageSize', true)
->setOption('displayHeaderFooter', false)
->showBackground()
->savePdf($filename);
$renderTime = microtime(true) - $start;
$this->info(str_pad($index, 2) . ': ' . number_format($renderTime, 3) . ' seconds');
}
});
And the results are this:
$ php artisan app:pdf
1 : 0.883 seconds
2 : 0.864 seconds
3 : 0.846 seconds
4 : 0.944 seconds
5 : 0.882 seconds
6 : 0.864 seconds
7 : 0.860 seconds
8 : 0.948 seconds
9 : 0.849 seconds
10: 0.916 seconds
11: 0.870 seconds
12: 0.936 seconds
13: 0.852 seconds
14: 0.916 seconds
15: 0.856 seconds
16: 0.933 seconds
17: 0.860 seconds
18: 0.878 seconds
19: 0.856 seconds
20: 0.968 seconds
21: 0.857 seconds
22: 0.848 seconds
23: 0.855 seconds
24: 0.927 seconds
25: 0.921 seconds
26: 0.848 seconds
27: 0.899 seconds
28: 0.933 seconds
29: 0.868 seconds
30: 0.856 seconds
As you can see, all runs were less than a second.
As this project is a bit old (Laravel 6.0, last updated in 2019), here are the relevant info about package versions:
"inertiajs/inertia-laravel": "^0.1.0",
"spatie/browsershot": "^3.32",
"@inertiajs/inertia": "^0.1.3",
"@inertiajs/inertia-vue": "^0.1.1",
"bootstrap": "^4.3",
"laravel-mix": "^4.0.7",
"node-sass": "^4.11.0",
"puppeteer": "^1.19.0",
"vue": "^2.6",
"vue-svg-loader": "^0.12.0",
"vue-template-compiler": "^2.6.8",
For reference I wrote this other command to output the generated HTML:
Artisan::command('app:html', function () {
// model I need to render the page
$estimate = \App\Models\Estimate::query()->find(1);
// As the route has sensitive data, I have a simple
// token guard on it, to prevent unauthorized access
$token = Config::get('services.pdf.token');
$url = route('estimates.pdf', ['estimate' => $estimate->getRouteKey(), 'api_token' => $token]);
$content = Browsershot::url($url)->bodyHtml();
$this->info($content);
});
And this was the generated HTML
<!DOCTYPE html><html lang="pt-BR"><head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0, shrink-to-fit=no">
<meta name="format-detection" content="telephone=no">
<meta name="format-detection" content="date=no">
<meta name="format-detection" content="address=no">
<meta name="format-detection" content="email=no">
<meta http-equiv="Cache-Control" content="max-age=0">
<meta http-equiv="Cache-Control" content="no-cache, no-store, must-revalidate">
<meta http-equiv="Pragma" content="no-cache">
<meta http-equiv="Expires" content="0">
<meta http-equiv="Expires" content="Tue, 01 Jan 1980 1:00:00 GMT">
<meta name="robots" content="none,noarchive">
<meta name="googlebot" content="noarchive">
<meta name="csrf-token" content="f6l4iuXdGOiCQcv9KbSMlCzRdY36qQHTaZ4SoubE">
<title>Project</title>
<link rel="shortcut icon" href="http://example.test/favicon.ico" type="image/x-icon">
<link rel="icon" href="http://example.test/favicon.ico" type="image/x-icon">
<link rel="stylesheet" href="http://example.test/css/app.css?id=c23285a690bb9f55ad79">
<script src="http://example.test/js/manifest.js?id=7db827d654313dce4250"></script>
<script src="http://example.test/js/vendor.js?id=6c59242688a21c4c0ce1"></script>
<script src="http://example.test/js/common.js?id=e48577af589747383b23"></script>
<link rel="stylesheet" href="http://example.test/css/print.css?id=54fe4662a6cc2e457f76">
<script src="http://example.test/js/pdf.js?id=b13e2a101e69c1bc702a"></script><style type="text/css">.modal-dialog > .modal-content[data-v-189bddbf] {
border-radius: 2px;
box-shadow: 0 0 20px 0 rgba(0, 0, 0, 0.5);
background-color: white;
color: var(--app-color);
}
.modal-dialog > .modal-content.\--dark[data-v-189bddbf] {
background-color: var(--app-color);
color: var(--body-bg-color);
}
.modal-dialog > .modal-content.\--dark > .modal-body > .close svg[data-v-189bddbf] {
fill: var(--body-bg-color);
}
.modal-dialog > .modal-content.\--dark > .modal-body > .close[data-v-189bddbf]:hover {
background-color: #414d59;
}
.modal-dialog > .modal-content > .modal-body > .close[data-v-189bddbf] {
display: flex;
align-items: center;
justify-content: center;
width: 26px;
height: 26px;
border-radius: 50%;
opacity: 1 !important;
}
.modal-dialog > .modal-content > .modal-body > .close svg[data-v-189bddbf] {
width: 18px;
height: 18px;
color: var(--text-color);
}
.modal-dialog > .modal-content > .modal-body > .close[data-v-189bddbf]:hover {
background-color: var(--light-gray);
}
</style><style type="text/css">.confirm-box[data-v-3a98e5b6] {
text-align: center;
padding: 14px 19px;
}
.confirm-box > .confirm-box-icon[data-v-3a98e5b6] {
display: block;
margin: 0 auto 25px auto;
}
.confirm-box > .confirm-box-title[data-v-3a98e5b6] {
font-size: 16px;
font-weight: 600;
line-height: 1.69;
letter-spacing: 0.5px;
text-align: center;
color: var(--app-color);
margin: 0 15px;
}
.confirm-box > .alert-box-content[data-v-3a98e5b6] {
font-size: 15px;
line-height: 1.33;
letter-spacing: 0.4px;
text-align: center;
color: var(--app-color);
margin: 0 15px;
}
.confirm-box > .confirm-box-buttons[data-v-3a98e5b6] {
margin-top: 40px;
display: flex;
align-items: center;
justify-content: space-between;
text-align: center;
}
.confirm-box > .confirm-box-buttons > .btn-app[data-v-3a98e5b6] {
width: 130px;
}
</style><style type="text/css">.cart-tag-marker {
display: block;
width: 23px;
height: 23px;
border-radius: 50%;
text-align: center;
vertical-align: middle;
font-size: 15px;
letter-spacing: 0.3px;
line-height: 25px;
color: white;
background-color: #4079ab;
cursor: inherit;
}
.cart-tag-marker.\--has-border {
width: 26px;
height: 26px;
padding-left: 1px;
border: solid 2px white;
}
.cart-tag-marker.\--has-error {
background-color: #c83226;
}
</style><style type="text/css">.radio-checkbox {
display: inline-flex;
align-items: center;
justify-content: center;
min-width: 22px;
height: 22px;
border: solid 2px transparent;
border-radius: 50%;
background-color: var(--light-gray);
box-shadow: 0 0 0 1px var(--medium-gray);
cursor: pointer;
}
.radio-checkbox.\--spin {
border-top-color: var(--heavy-gray);
}
.radio-checkbox[disabled] {
opacity: 0.6;
cursor: not-allowed;
}
.radio-checkbox .radio-checkbox-toggle {
width: 14px;
height: 14px;
border-radius: 50%;
background-color: var(--text-color);
}
</style><style type="text/css">.cart-details-item-description {
width: 314px;
height: 174px;
padding: 15px;
border-radius: 3px;
box-shadow: var(--light-shadow);
background-color: var(--body-bg-color);
}
.cart-details-item-description > header {
margin-bottom: 10px;
color: var(--app-color);
}
.cart-details-item-description > header > h3 {
font-size: 16px;
font-weight: 600;
line-height: 1.25;
letter-spacing: 0.5px;
margin-bottom: 0;
}
.cart-details-item-description > header > p {
font-size: 15px;
font-weight: 400;
letter-spacing: 0.5px;
margin: 0;
}
.cart-details-item-description > .cart-details-item-description-content {
max-height: 66px;
overflow: hidden;
font-size: 15px;
line-height: 1.47;
letter-spacing: 0.5px;
color: var(--dark-gray);
}
</style><style type="text/css">.cart-details-items[data-v-3a181d20] {
width: 100%;
border-collapse: collapse;
border-spacing: 0;
}
.cart-details-items tbody > tr[data-v-3a181d20] {
border-bottom: solid 1px rgba(49, 58, 67, 0.3);
height: 97px;
}
.cart-details-items thead > tr > th.cart-details-items-cell[data-v-3a181d20] {
font-size: 17px;
letter-spacing: 0.8px;
color: var(--text-color);
}
.cart-details-items[data-v-3a181d20] .cart-details-items-cell {
padding: 16px 12px;
font-size: 16px;
font-weight: 600;
letter-spacing: 0.4px;
color: var(--text-color);
}
.cart-details-items[data-v-3a181d20] .cart-details-items-cell > strong {
display: block;
max-width: 350px;
}
.cart-details-items[data-v-3a181d20] .cart-details-items-cell > small {
font-size: inherit;
font-weight: 400;
}
.cart-details-items[data-v-3a181d20] .cart-details-items-cell:first-child {
padding-left: 0;
}
.cart-details-items[data-v-3a181d20] .cart-details-items-cell:last-child {
padding-right: 0;
}
.cart-details-items[data-v-3a181d20] .cart-details-items-cell .cart-details-item-image {
position: relative;
display: inline-block;
width: 56px;
height: 56px;
overflow: hidden;
background-color: #eaeaea;
background-size: 90%;
}
.cart-details-items[data-v-3a181d20] .cart-details-items-cell .cart-details-item-image > img {
display: block;
max-width: 100%;
height: 100%;
margin: 0 auto;
color: transparent;
}
.cart-details-items[data-v-3a181d20] .cart-details-items-cell.\--poster {
width: 100px;
text-align: left;
}
.cart-details-items[data-v-3a181d20] .cart-details-items-cell.\--poster .cart-details-item-poster {
position: relative;
width: 56px;
height: 56px;
margin: 5px 0;
}
.cart-details-items[data-v-3a181d20] .cart-details-items-cell.\--poster .cart-details-item-poster .cart-details-item-tag {
position: absolute;
right: 0;
bottom: 0;
transform: translate(30%, 30%);
}
.cart-details-items[data-v-3a181d20] .cart-details-items-cell.\--details {
position: relative;
}
.cart-details-items[data-v-3a181d20] .cart-details-items-cell.\--details .cart-details-item-description {
position: absolute;
top: 85%;
left: 15px;
z-index: 10;
}
.cart-details-items[data-v-3a181d20] .cart-details-items-cell.\--credit {
width: 111px;
text-align: center;
}
.cart-details-items[data-v-3a181d20] .cart-details-items-cell.\--reference {
width: 111px;
text-align: center;
}
.cart-details-items[data-v-3a181d20] .cart-details-items-cell.\--total {
width: 160px;
text-align: right;
}
.cart-details-items[data-v-3a181d20] .cart-details-items-cell.\--action {
width: 50px;
text-align: center;
}
.cart-details-items[data-v-3a181d20] .cart-details-items-cell.\--action .remove-button {
position: relative;
bottom: 4px;
}
.cart-details-items[data-v-3a181d20] .cart-details-items-cell.\--action .remove-button svg {
width: 26px;
height: 26px;
fill: currentColor;
}
.cart-details-items[data-v-3a181d20] .cart-details-items-cell.\--action .credit-button.\--is-active svg {
fill: #404040;
}
.cart-details-items[data-v-3a181d20] .cart-details-items-cell.\--action .credit-button svg {
transition: linear all 100ms;
fill: rgba(68, 81, 99, 0.5);
width: 22px;
height: 23px;
}
</style><style type="text/css">.tag-marker[data-v-b7295bca] {
position: absolute;
}
.tag-marker .tag-marker-toggle[data-v-b7295bca] {
display: flex;
align-items: center;
justify-content: center;
width: 25px;
height: 25px;
border-radius: 50%;
transform: translate(-50%, -50%);
transition: ease-in-out all 150ms;
color: var(--body-bg-color);
border: solid 2px var(--body-bg-color);
box-shadow: 0 0 10px 0 rgba(49, 58, 67, 0.5);
background-color: var(--indicator-color);
background-image: linear-gradient(to bottom, var(--indicator-color), var(--dark-indicator-color));
}
.tag-marker .tag-marker-toggle.\--clickable[data-v-b7295bca] {
cursor: pointer;
}
.tag-marker .tag-marker-toggle.\--clickable[data-v-b7295bca]:hover {
background-image: linear-gradient(to bottom, rgba(248, 249, 250, 0.3), rgba(248, 249, 250, 0.3)), linear-gradient(to bottom, var(--indicator-color), var(--dark-indicator-color));
}
.tag-marker .tag-marker-toggle.\--is-active[data-v-b7295bca] {
width: 35px;
height: 35px;
box-shadow: 0 0 20px 0 var(--app-color);
border: solid 3px var(--body-bg-color);
background-image: linear-gradient(to bottom, var(--indicator-color), var(--dark-indicator-color));
}
.tag-marker .tag-marker-toggle .tag-marker-label[data-v-b7295bca] {
display: block;
height: 16px;
font-size: 16px;
font-weight: 600;
line-height: 1.1875;
text-align: center;
color: var(--light-gray);
}
.tag-marker .tag-marker-toggle[data-v-b7295bca] svg {
display: block;
width: 20px;
height: 20px;
fill: var(--light-gray);
}
.tag-marker.\--has-error .tag-marker-toggle[data-v-b7295bca], .tag-marker.\--standard.\--has-error .tag-marker-toggle[data-v-b7295bca], .tag-marker.\--flat.\--has-error .tag-marker-toggle[data-v-b7295bca], .tag-marker.\--dark.\--has-error .tag-marker-toggle[data-v-b7295bca] {
background-color: #c83226;
}
.tag-marker.\--flat .tag-marker-toggle[data-v-b7295bca] {
width: 26px;
height: 26px;
background-color: #4079ab;
background-image: none;
box-shadow: none;
}
.tag-marker.\--flat .tag-marker-toggle[data-v-b7295bca] svg {
position: relative;
left: -1px;
}
.tag-marker.\--dark > .tag-marker-toggle[data-v-b7295bca] {
width: 35px;
height: 35px;
color: var(--light-gray);
box-shadow: 0 2px 5px 0 var(--app-color);
border: solid 2px var(--body-bg-color);
background-color: var(--text-color);
background-image: none;
}
.tag-marker.\--dark > .tag-marker-toggle[data-v-b7295bca]:hover {
box-shadow: 0 2px 10px 0 var(--app-color);
border: solid 2px var(--body-bg-color);
background-color: var(--text-color);
background-image: linear-gradient(to bottom, rgba(248, 249, 250, 0.3), rgba(248, 249, 250, 0.3));
}
.tag-marker.\--dark > .tag-marker-toggle.\--is-active[data-v-b7295bca] {
box-shadow: 0 2px 5px 0 var(--app-color);
border: solid 3px var(--body-bg-color);
background-color: var(--text-color);
background-image: none;
}
.tag-marker.\--standard > .tag-marker-toggle[data-v-b7295bca] {
width: 35px;
height: 35px;
color: var(--light-gray);
box-shadow: 0 2px 5px 0 var(--app-color);
border: solid 2px var(--body-bg-color);
background-color: #29bb9c;
background-image: none;
}
.tag-marker.\--standard > .tag-marker-toggle[data-v-b7295bca]:hover {
box-shadow: 0 2px 10px 0 var(--app-color);
border: solid 2px var(--body-bg-color);
background-color: #29bb9c;
background-image: linear-gradient(to bottom, rgba(248, 249, 250, 0.3), rgba(248, 249, 250, 0.3));
}
.tag-marker.\--standard > .tag-marker-toggle.\--is-active[data-v-b7295bca] {
box-shadow: 0 2px 5px 0 var(--app-color);
border: solid 3px var(--body-bg-color);
background-color: #29bb9c;
background-image: none;
}
</style><style type="text/css">.cart-details-tags[data-v-523b7d10] {
position: relative;
width: 100%;
}
.cart-details-tags > img[data-v-523b7d10] {
display: block;
margin: 0 auto;
max-width: 100%;
max-height: 523px;
color: transparent;
}
</style><style type="text/css">.cart-details-room[data-v-18c0745a] {
margin-bottom: 60px;
}
.cart-details-room[data-v-18c0745a] .cart-details-tags {
margin-bottom: 50px;
}
.cart-details-room > h2[data-v-18c0745a] {
margin: 0 0 20px 0;
font-size: 30px;
letter-spacing: 0.6px;
color: var(--app-color);
}
.cart-details-room > h3[data-v-18c0745a] {
margin: 30px 0 10px 0;
font-size: 25px;
letter-spacing: 0.6px;
color: var(--app-color);
}
.cart-details-room > h4[data-v-18c0745a] {
margin: 50px 0 10px 0;
font-size: 18px;
letter-spacing: 0.6px;
color: var(--app-color);
}
.cart-details-room > .cart-details-room-subtotal[data-v-18c0745a] {
margin: 16px 0;
padding-right: 62px;
font-size: 18px;
font-weight: 600;
letter-spacing: 0.5px;
text-align: right;
color: #404040;
}
</style><style type="text/css">@page {
size: A4 portrait;
margin: 0;
}
body {
margin: 0 !important;
padding: 0 !important;
}
</style><style type="text/css">#estimate-pdf-page[data-v-caace272] {
width: 995px;
border-collapse: collapse;
}
#estimate-pdf-page tr[data-v-caace272], #estimate-pdf-page td[data-v-caace272], #estimate-pdf-page th[data-v-caace272], #estimate-pdf-page thead[data-v-caace272], #estimate-pdf-page tbody[data-v-caace272] {
border: none;
}
#estimate-pdf-page .content[data-v-caace272] {
margin: 0 !important;
padding: 1px 40px;
page-break-inside: avoid;
}
#estimate-pdf-page thead tr:first-of-type td > div[data-v-caace272] {
display: flex;
align-items: center;
padding: 20px 40px;
background-color: var(--app-color);
color: white;
}
#estimate-pdf-page thead tr:first-of-type td > div #logo[data-v-caace272] {
flex: 0 0 112px;
height: 30px;
margin-right: 40px;
}
#estimate-pdf-page thead tr:first-of-type td > div #title[data-v-caace272] {
flex: 1 1 auto;
text-align: center;
line-height: 1.1;
}
#estimate-pdf-page thead tr:last-of-type td > div[data-v-caace272] {
display: flex;
align-items: center;
padding: 12px 40px;
background-color: #e4e6f2;
color: var(--app-color);
}
#estimate-pdf-page thead tr:last-of-type td > div[data-v-caace272] > :first-child {
flex: 0 0 40%;
margin-right: 40px;
line-height: 1.2;
}
#estimate-pdf-page thead tr:last-of-type td > div[data-v-caace272] > :last-child {
flex: 1 1 auto;
line-height: 1.2;
}
#estimate-pdf-page tbody .body[data-v-caace272] .cart-details-room .cart-details-room-subtotal {
padding-right: 0;
}
#estimate-pdf-page tbody .body[data-v-caace272] .cart-details-room .cart-details-items-cell.\--action {
display: none;
}
#estimate-pdf-page tbody .body[data-v-caace272] .cart-details-tags img {
max-height: 250px;
}
#estimate-pdf-page tbody #footer[data-v-caace272] {
display: flex;
flex-wrap: wrap;
align-items: stretch;
}
#estimate-pdf-page tbody #footer > div[data-v-caace272] {
flex: 0 0 calc(50% - 20px);
width: calc(50% - 20px);
padding: 20px;
margin: 10px;
}
#estimate-pdf-page tbody #footer > div.signatures[data-v-caace272] {
margin-top: 80px;
border-top: solid 1px var(--app-color);
text-align: center;
}
#estimate-pdf-page tbody #footer #comments > .comments-content[data-v-caace272] {
border: solid 1px var(--app-color);
padding: 12px;
}
</style>
<script src="http://example.test/js/app.js?id=dda4650ac75687d24146"></script>
</head>
<body>
<table data-v-caace272="" id="estimate-pdf-page"><thead data-v-caace272=""><tr data-v-caace272=""><td data-v-caace272=""><div data-v-caace272="" class="content"><img data-v-caace272="" id="logo" src="data:image/png;base64,redacted==" alt=""> <div data-v-caace272="" id="title">
ANEXO I - Orçamento
Building Name
</div></div></td></tr> <tr data-v-caace272=""><td data-v-caace272=""><div data-v-caace272="" class="content"><div data-v-caace272=""><strong data-v-caace272="">Orçamento:</strong>
000000000 <br data-v-caace272=""> <strong data-v-caace272="">Unidade:</strong>
00000 <br data-v-caace272=""></div> <div data-v-caace272=""><strong data-v-caace272="">Data:</strong>
10/12/19 <br data-v-caace272=""> <strong data-v-caace272="">Cliente:</strong>
CUSTOMER NAME <br data-v-caace272=""></div></div></td></tr></thead> <tbody data-v-caace272=""><tr data-v-caace272=""><td data-v-caace272=""><div data-v-caace272="" class="body content"><section data-v-18c0745a="" data-v-caace272="" class="cart-details-room"><h3 data-v-18c0745a="">Lavabo</h3> <div data-v-523b7d10="" data-v-18c0745a="" class="cart-details-tags"><img data-v-523b7d10="" alt="Lavabo" class="no-select"> <div data-v-b7295bca="" data-v-523b7d10="" class="tag-marker no-select --flat" style="left: 0px; top: 0px;"><span data-v-b7295bca="" draggable="true" class="tag-marker-toggle"><span data-v-b7295bca="" class="tag-marker-label">1</span></span> </div></div> <table data-v-3a181d20="" data-v-18c0745a="" class="cart-details-items"><thead data-v-3a181d20=""><tr data-v-3a181d20=""><th data-v-3a181d20="" class="cart-details-items-cell --poster">
</th> <th data-v-3a181d20="" class="cart-details-items-cell --details">
</th> <th data-v-3a181d20="" class="cart-details-items-cell --reference">
Referência
</th> <th data-v-3a181d20="" class="cart-details-items-cell --total">
Preço
</th> <th data-v-3a181d20="" class="cart-details-items-cell --action"><button data-v-3a181d20="" type="button" class="credit-button reset-button"><svg data-v-3a181d20="" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 20 20" class=""><path data-v-3a181d20="" d="M9.9758 3.6105c-4.4935 0-8.3161 2.7544-9.8875 6.6653 1.5714 3.9108 5.394 6.6652 9.8875 6.6652s8.316-2.7544 9.8875-6.6652c-1.5714-3.9109-5.394-6.6653-9.8875-6.6653zm0 11.1102c-2.4719 0-4.4935-1.9995-4.4935-4.445s2.0216-4.4449 4.4935-4.4449 4.4935 1.9996 4.4935 4.445-2.0216 4.445-4.4935 4.445zm0-7.111c-1.4831 0-2.697 1.2006-2.697 2.666s1.2139 2.6662 2.697 2.6662 2.697-1.2007 2.697-2.6661-1.2139-2.6661-2.697-2.6661z"></path></svg></button></th></tr></thead> <tbody data-v-3a181d20=""><tr data-v-3a181d20=""><td class="cart-details-items-cell --poster"><div class="cart-details-item-poster"><div class="cart-details-item-image placeholder-image"><!----></div> <span class="cart-tag-marker no-select cart-details-item-tag">1</span></div></td> <td class="cart-details-items-cell --details"><strong title="RALO LINEAR T2" class="text-truncate">RALO LINEAR T2</strong> <button type="button" class="btn-app btn-app-link d-print-none">
Ver descrição
</button> <!----></td> <td class="cart-details-items-cell --reference"><div class="cart-details-item-image placeholder-image"><!----></div></td> <td class="cart-details-items-cell --total">
R$ 16,84
</td> <td class="cart-details-items-cell --action"><button type="button" class="remove-button reset-button"><svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 20 20" class=""><path d="M20 3.6768a.739.739 0 0 1-.2453.5495.8074.8074 0 0 1-.579.2358h-.4452v13.9684c0 .4337-.1558.8032-.4673 1.1095a1.5337 1.5337 0 0 1-1.1137.46H3.0737c-.4316 0-.8021-.1537-1.1137-.46a1.499 1.499 0 0 1-.4674-1.1095V4.4621H.8021a.7705.7705 0 0 1-.5684-.2358.7684.7684 0 0 1-.2337-.56.7684.7684 0 0 1 .2337-.561.7705.7705 0 0 1 .5684-.2358h4.12v-1.3c0-.4337.1526-.8032.4568-1.1095A1.5232 1.5232 0 0 1 6.5032 0h6.9936c.4306 0 .8021.1537 1.1137.46.3116.3053.4674.6758.4674 1.1095v1.3h4.0979c.2379 0 .4347.079.5895.2358A.779.779 0 0 1 20 3.6768zM6.481 1.5926v1.2769h7.0158v-1.278H6.4811zm10.6685 16.838V4.462H3.0737v13.9684h14.0758zM10.5347 7.3988c.1632.1495.2453.3369.2453.5611v7.4884a.781.781 0 0 1-.2347.5716.7579.7579 0 0 1-.5569.2358.7579.7579 0 0 1-.5568-.2358.781.781 0 0 1-.2337-.5716V7.96c0-.2242.0779-.4147.2337-.5726a.7579.7579 0 0 1 .5579-.2348c.2147 0 .3968.0821.5452.2463zm-4.321 0c.1631.1495.2452.3369.2452.5611v7.4884a.781.781 0 0 1-.2336.5716.7705.7705 0 0 1-.5685.2358.7705.7705 0 0 1-.5684-.2358.781.781 0 0 1-.2337-.5716V7.96c0-.2242.079-.4147.2348-.5726a.7705.7705 0 0 1 .5684-.2348c.221 0 .4074.0821.5558.2463zm8.619 0c.163.1495.2452.3369.2452.5611v7.4884a.781.781 0 0 1-.2337.5716.7705.7705 0 0 1-.5684.2358.7705.7705 0 0 1-.5684-.2358.781.781 0 0 1-.2327-.5716V7.96c0-.2242.078-.4147.2337-.5726a.7705.7705 0 0 1 .5684-.2348c.221 0 .4074.0821.5558.2463z"></path></svg></button></td></tr></tbody></table> <!----> <p data-v-18c0745a="" class="cart-details-room-subtotal">
Subtotal Lavabo (um item) : R$ 16,84
</p></section></div></td></tr></tbody> <tbody data-v-caace272=""><tr data-v-caace272=""><td data-v-caace272=""><div data-v-caace272="" id="footer" class="content"><div data-v-caace272="" id="comments" class=""><strong data-v-caace272="">Comentários</strong> <div data-v-caace272="" class="comments-content small">Teste</div></div> <div data-v-caace272=""><strong data-v-caace272="">Resumo Orçamentário</strong> <table data-v-caace272="" class="w-100"><tbody data-v-caace272=""><tr data-v-caace272=""><td data-v-caace272="">Valor:</td> <th data-v-caace272="" class="text-right">
R$ 16,84
</th></tr> <tr data-v-caace272=""><td data-v-caace272="">Desconto:</td> <th data-v-caace272="" class="text-right">
R$ 0,00
</th></tr> <tr data-v-caace272=""><td data-v-caace272="">Valor do orçamento:</td> <th data-v-caace272="" class="text-right">
R$ 16,84
</th></tr></tbody></table></div> <div data-v-caace272="" class="signatures">
CUSTOMER NAME
</div> <div data-v-caace272="" class="signatures">
Building Name
</div> <div data-v-caace272="" class="signatures">
Testemunha 1
</div> <div data-v-caace272="" class="signatures">
Testemunha 2
</div></div></td></tr></tbody></table>
<script>
+(function (window, undefined) {
'use strict';
var init = function () {
toastr.options.progressBar = true;
toastr.options.newestOnTop = true;
toastr.options.closeButton = true;
toastr.options.positionClass = 'toast-bottom-right';
toastr.options.timeOut = 3500;
toastr.options.extendedTimeOut = 3500;
};
window.document.addEventListener('DOMContentLoaded', init);
}(window));
</script>
</body></html>
You can see it has the scoped CSS data- attributes generated by Vue.
Let me know if you need any additional info.
Hope it helps.