تاریخ انتشار: ۶ فوریه ۲۰۱۹، آخرین بهروزرسانی: ۵ ژانویه ۲۰۲۶
یکی از تصمیمات اصلی که توسعهدهندگان وب باید بگیرند این است که منطق و پردازش را در کجای برنامه خود پیادهسازی کنند. این کار میتواند دشوار باشد زیرا روشهای بسیار زیادی برای ساختن وبسایت وجود دارد.
درک ما از این فضا از کار ما در Chrome در گفتگو با سایتهای بزرگ در چند سال گذشته نشأت میگیرد. بهطور کلی، توسعهدهندگان را تشویق میکنیم که بهجای رویکرد بازآبرسانی کامل، رندر کردن سمت سرور یا رندر کردن ایستا را درنظر بگیرند.
برای درک بهتر معماریهایی که هنگام اتخاذ این تصمیم از بین آنها انتخاب میکنیم، به اصطلاحات منسجم و چارچوب مشترک برای هر رویکرد نیاز داریم. سپس میتوانید مبادلات هر رویکرد پردازشی را از دیدگاه عملکرد صفحه بهتر ارزیابی کنید.
اصطلاحات
ابتدا، برخیاز اصطلاحاتی را که استفاده خواهیم کرد تعریف میکنیم.
اندودکاری
- پرداز زدن سمت سرور (SSR)
- پرداخت کردن برنامه در سرور برای ارسال HTML، بهجای JavaScript، به کارخواه.
- پرداز زدن سمت کارخواه (CSR)
- پرداز یک برنامه در مرورگر، بااستفاده از جاوا اسکریپت برای اصلاح DOM.
- پیشپرداززنی
- اجرای برنامه سمت کارخواه در زمان ساخت برای ضبط وضعیت اولیه آن بهعنوان HTML ایستا. توجه داشته باشید که «پیشپرداز» در این مفهوم با پیشپرداز مرورگر برای پیمایشهای آینده متفاوت است.
- آبرسانی
- اجرای اسکریپتهای سمت کارخواه برای افزودن وضعیت برنامه و تعاملپذیری به HTML ارائهشده توسط سرور. فرض بر این است که DOM در فرایند فعالسازی تغییر نمیکند.
- آبرسانی مجدد
- اگرچه اغلب برای اشاره به همان مفهوم «آبرسانی» استفاده میشود، اما «آبرسانی مجدد» بهمعنای بهروزرسانی منظم DOM با جدیدترین وضعیت است، ازجمله پساز آبرسانی اولیه.
عملکرد
- زمان تا اولین بایت (TTFB)
- زمان بین کلیک کردن روی پیوند و بار شدن اولین بایت محتوا در صفحه جدید.
- اولین نقاشی دارای محتوا (FCP)
- زمانی که محتوای درخواستی (بدنه مقاله، و غیره) رؤیتپذیر میشود.
- تأخیر در تعاملها (INP)
- سنجهای معرف که ارزیابی میکند آیا صفحه بهطور مداوم به ورودیهای کاربر سریع پاسخ میدهد یا نه.
- مجموع زمان مسدودسازی (TBT)
- سنجهای نیابتی برای INP که مدتزمان مسدود شدن رشته اصلی را درطول بار شدن صفحه محاسبه میکند.
پرداز زدن سمت سرور
پرداز زدن سمت سرور، HTML کامل را برای صفحهای در سرور در پاسخ به پیمایش تولید میکند. این کار از رفتوبرگشتهای اضافی برای واکشی داده و قالبسازی در سمت کارخواه جلوگیری میکند، زیرا موتور پردازشگر قبلاز اینکه مرورگر پاسخ دریافت کند، آنها را مدیریت میکند.
پرداخت سمت سرور معمولاً FCP سریعی تولید میکند. اجرای منطق صفحه و پردازش در سرور به شما امکان میدهد از ارسال مقدار زیادی جاوا اسکریپت به کارخواه اجتناب کنید. این کار به کاهش TBT صفحه کمک میکند که میتواند به INP پایینتر نیز منجر شود، زیرا رشته اصلی درطول بار شدن صفحه کمتر مسدود میشود. وقتی رشته اصلی کمتر مسدود شود، تعاملات کاربر فرصتهای بیشتری برای اجرا شدن سریعتر دارند.
این منطقی است، زیرا با پردازش سمت سرور، شما واقعاً فقط درحال ارسال نوشتار و پیوند به مرورگر کاربر هستید. این رویکرد میتواند برای شرایط مختلف دستگاه و شبکه بهخوبی کار کند و بهینهسازیهای جالب مرورگر را ممکن کند، مانند تجزیه سند جاری.
با پردازش سمت سرور، احتمال اینکه کاربران منتظر بمانند تا جاوا اسکریپت محدود به CPU اجرا شود تا بتوانند از سایت شما استفاده کنند کمتر است. حتی وقتی نمیتوانید از جاوا اسکریپت طرف سوم اجتناب کنید، استفاده از رندرینگ سمت سرور برای کاهش هزینههای جاوا اسکریپت طرف اول خودتان میتواند بودجه بیشتری برای بقیه موارد دراختیارتان قرار دهد. بااینحال، یک معاوضه بالقوه با این رویکرد وجود دارد: تولید صفحات در سرور زمان میبرد، که میتواند TTFB صفحه شما را افزایش دهد.
اینکه آیا پردازش سمت سرور برای برنامه شما کافی است یا نه، تا حد زیادی به نوع تجربهای که میسازید بستگی دارد. بحثی طولانی درباره کاربردهای صحیح پردازش سمت سرور درمقابل پردازش سمت کارخواه وجود دارد، اما همیشه میتوانید انتخاب کنید که از پردازش سمت سرور برای برخی صفحهها استفاده کنید و برای برخی دیگر استفاده نکنید. برخیاز سایتها تکنیکهای پردازش ترکیبی را با موفقیت اتخاذ کردهاند. برای مثال، Netflix صفحههای مقصد نسبتاً ثابت خود را در سرور پردازش میکند، درحالیکه جاوا اسکریپت را برای صفحههایی با تعامل سنگین prefetching میکند، و به این صفحههای سنگینتر پردازششده در سمت کارخواه شانس بهتری برای بارگیری سریع میدهد.
با بسیاری از چارچوبها، کتابخانهها، و معماریهای مدرن، میتوانید همان برنامه را هم در کارخواه و هم در سرور پرداز کنید. میتوانید از این تکنیکها برای پرداخت سمت سرور استفاده کنید. بااینحال، معماریهایی که در آنها پردازش هم در سرور و هم در کارخواه انجام میشود، کلاس راهحل خاص خود را دارند و ویژگیهای عملکردی و معاوضههای بسیار متفاوتی دارند. کاربران React میتوانند از میاناهای برنامهسازی کاربردی DOM سرور یا راهحلهای ساختهشده براساس آنها مانند Next.js برای پردازش سمت سرور استفاده کنند. کاربران Vue میتوانند از راهنمای پردازش سمت سرور Vue یا Nuxt استفاده کنند. Angular دارای Universal است.
بااینحال، اکثر راهحلهای پرطرفدار از نوعی آبرسانی استفاده میکنند، بنابراین از رویکردهایی که ابزارتان استفاده میکند آگاه باشید.
پرداز زدن ایستا
پرداز ایستا در زمان ساخت اتفاق میافتد. این رویکرد FCP سریع و همچنین TBT و INP پایینتری ارائه میدهد، بهشرطی که مقدار JavaScript سمت کارخواه را در صفحههایتان محدود کنید. برخلاف پرداززنی سمت سرور، این روش به TTFB سریع و ثابتی نیز دست مییابد، زیرا HTML برای یک صفحه نباید بهصورت پویا در سرور تولید شود. بهطور کلی، پردازش ایستا بهمعنای تولید فایل HTML جداگانه برای هر نشانی وب ازقبل است. با پاسخهای HTML که ازقبل تولید شدهاند، میتوانید پردازشهای ایستا را در چندین CDN مستقر کنید تا از ذخیرهسازی موقت لبه بهرهمند شوید.
راهحلهای پردازش ایستا در انواع و اندازههای مختلف وجود دارند. ابزارهایی مانند Gatsby بهگونهای طراحی شدهاند که توسعهدهندگان احساس کنند برنامهشان بهصورت پویا ارائه میشود، نه اینکه بهعنوان یک مرحله ساخت تولید شود. ابزارهای تولید سایت ایستا مانند 11ty، Jekyll، و Metalsmith ماهیت ایستا خود را دربرمیگیرند و رویکردی بیشتر مبتنی بر الگو ارائه میدهند.
یکی از معایب پردازش ایستا این است که باید برای هر نشانی وب ممکن، فایلهای HTML جداگانه تولید کند. این کار میتواند چالشبرانگیز یا حتی غیرممکن باشد، بهویژه زمانی که باید این نشانیهای وب را ازقبل پیشبینی کنید و برای سایتهایی با تعداد زیادی صفحه منحصربهفرد.
کاربران React ممکن است با Gatsby، صادر کردن ایستا Next.js، یا Navi آشنا باشند که همه آنها ایجاد صفحه از مؤلفهها را آسان میکنند. بااینحال، پرداز ایستا و پیشپرداز رفتار متفاوتی دارند: صفحههای پردازششده بهصورت ایستا بدون نیاز به اجرای مقدار زیادی جاوا اسکریپت در سمت کارخواه تعاملی هستند، درحالیکه پیشپرداز «اولین رنگآمیزی محتوایی» (FCP) «برنامه تکصفحهای» را بهبود میبخشد که باید در کارخواه راهاندازی شود تا صفحهها واقعاً تعاملی شوند.
اگر مطمئن نیستید که راهحل ارائهشده پرداز پیشساخته است یا پیشپرداز، جاوا اسکریپت را غیرفعال کنید و صفحهای را که میخواهید آزمایش کنید بار کنید. برای صفحههایی که بهصورت ایستا پردازش شدهاند، بیشتر ویژگیهای تعاملی همچنان بدون جاوا اسکریپت وجود دارند. صفحههای پیشپردازششده ممکن است همچنان برخیاز ویژگیهای پایه را داشته باشند، مثل پیوندهایی که جاوا اسکریپت آنها غیرفعال است، اما بیشتر صفحه غیرفعال است.
آزمایش مفید دیگر استفاده از محدود کردن شبکه در Chrome DevTools و دیدن مقدار بارگیری جاوا اسکریپت قبلاز تعاملی شدن صفحه است. پیشپرداز معمولاً برای تعاملی شدن به جاوا اسکریپت بیشتری نیاز دارد و این جاوا اسکریپت معمولاً پیچیدهتر از رویکرد ارتقای پیشرو است که در پرداز ایستا استفاده میشود.
پرداز زدن سمت سرور درمقابل پرداز زدن ایستا
پرداز سمت سرور بهترین راهحل برای همه چیز نیست، زیرا ماهیت پویای آن میتواند هزینههای سربار محاسباتی قابلتوجهی داشته باشد. بسیاری از راهحلهای ارائه سمت سرور زود پاکسازی نمیکنند، TTFB را بهتأخیر میاندازند، یا دادههای ارسالی را دوبرابر میکنند (برای مثال، حالتهای درونخطی استفادهشده توسط جاوا اسکریپت در سمت کارخواه). در React،
renderToString() میتواند کند باشد زیرا همگام و تکرشتهای است.
React server DOM APIs جدیدتر
از جاریسازی پشتیبانی میکنند که میتواند بخش اولیه پاسخ HTML را زودتر به مرورگر برساند، درحالیکه بقیه آن هنوز در سرور درحال تولید است.
«درست» انجام دادن پردازش سمت سرور میتواند شامل پیدا کردن یا ساختن راهحلی برای ذخیره مؤلفه در حافظه نهان، مدیریت مصرف حافظه، استفاده از تکنیکهای یادسپاری، و نگرانیهای دیگر باشد. اغلب یک برنامه را دو بار پردازش یا بازسازی میکنید، یک بار در کلاینت و یک بار در سرور. پرداخت سمت سرور که محتوا را زودتر نشان میدهد لزوماً کار شما را کمتر نمیکند. اگر پساز رسیدن پاسخ HTML تولیدشده توسط سرور به کارخواه، کارهای زیادی در کارخواه داشته باشید، این امر همچنان میتواند منجر به TBT و INP بالاتر برای وبسایت شما شود.
پرداخت سمت سرور HTML را براساس تقاضا برای هر نشانی وب تولید میکند، اما میتواند کندتر از ارائه محتوای پرداختشده ایستا باشد. اگر بتوانید کارهای مقدماتی بیشتری انجام دهید، پرداز زدن سمت سرور بهعلاوه ذخیره HTML در حافظه نهان میتواند زمان پرداز زدن سرور را بهطور قابلتوجهی کاهش دهد. مزیت پردازش سمت سرور توانایی واکشی دادههای «زنده» بیشتر و پاسخ دادن به مجموعه کاملتری از درخواستها نسبتبه پردازش ایستا است. صفحههایی که به شخصیسازی نیاز دارند نمونهای ملموس از نوع درخواستی هستند که با پرداز ایستا بهخوبی کار نمیکنند.
پرداز سمت سرور همچنین میتواند تصمیمات جالبی را هنگام ساختن یک PWA ارائه دهد. آیا بهتر است از حافظه پنهان کارگر سرویس تمامصفحه استفاده شود یا بخشهای مجزای محتوا در سرور ارائه شود؟
پرداز زدن سمت کارخواه
پرداز زدن سمت کارخواه یعنی پرداز زدن صفحهها مستقیماً در مرورگر با جاوااسکریپت. همه منطق، واکشی داده، الگو، و مسیریابی بهجای سرور در کارخواه انجام میشود. نتیجه مؤثر این است که دادههای بیشتری از سرور به دستگاه کاربر منتقل میشود و این امر با مجموعهای از معاوضهها همراه است.
ساختن و سریع نگه داشتن پرداز سمت کارخواه برای دستگاههای همراه میتواند دشوار باشد.
با کمی تلاش برای حفظ بودجه محدود جاوا اسکریپت
و ارائه ارزش در کمترین رفتوبرگشت
ممکن، میتوانید پرداز زدن سمت کارخواه را تقریباً به عملکرد پرداز زدن خالص سمت سرور برسانید. با ارائه دادهها و اسکریپتهای مهم بااستفاده از <link rel=preload> میتوانید کاری کنید که تجزیهکننده سریعتر برای شما کار کند.
همچنین توصیه میکنیم استفاده از الگوهایی مثل PRPL را مدنظر قرار دهید تا مطمئن شوید پیمایشهای اولیه و بعدی فوری بهنظر میرسند.
نکته منفی اصلی پرداز سمت کارخواه این است که مقدار جاوا اسکریپت موردنیاز با رشد برنامه افزایش مییابد، که میتواند بر INP صفحه تأثیر بگذارد. این امر بهویژه با افزودن کتابخانههای جدید جاوا اسکریپت، شبیهسازهای مرورگر، و کد طرف سوم دشوارتر میشود، زیرا این موارد برای قدرت پردازش رقابت میکنند و اغلب باید قبلاز اینکه محتوای صفحه بتواند ارائه شود پردازش شوند.
تجربههایی که از پردازش سمت کارخواه استفاده میکنند و به بستههای بزرگ جاوا اسکریپت متکی هستند باید تقسیم کد تهاجمی را درنظر بگیرند تا «زمان مسدودسازی کل» و «تعامل با بازنمایی بعدی» را درطول بار کردن صفحه کاهش دهند، و همچنین بار کردن کُند جاوا اسکریپت را درنظر بگیرند تا فقط آنچه را کاربر نیاز دارد، در زمان نیاز ارائه دهند. برای تجربههایی با تعامل کم یا بدون تعامل، پرداز طرف سرور میتواند راهحل مقیاسپذیرتری برای این مشکلات ارائه دهد.
برای افرادی که برنامههای تکصفحهای میسازند، شناسایی بخشهای اصلی میانای کاربر که در اکثر صفحهها مشترک است به شما امکان میدهد از تکنیک ذخیره پوسته برنامه در حافظه نهان استفاده کنید. در ترکیب با عاملهای خدماتی، این میتواند عملکرد درکشده را در بازدیدهای تکراری بهطور چشمگیری بهبود بخشد، زیرا صفحه میتواند پوسته برنامه HTML و وابستگیهای خود را از CacheStorage بسیار سریع بارگیری کند.
بازآبرسانی پرداز زدن سمت سرور و سمت کارخواه را ترکیب میکند
آبرسانی رویکردی است که با انجام هر دو، معاوضههای بین سمت کارخواه و سمت سرور را کاهش میدهد. درخواستهای پیمایش، مثل بار کردن یا بازبار کردن کامل صفحه، توسط سروری مدیریت میشود که برنامه را به HTML تبدیل میکند. سپس جاوا اسکریپت و دادههای استفادهشده برای پردازش در سند حاصل جاسازی میشود. اگر این کار با دقت انجام شود، به FCP سریعی مانند پردازش سمت سرور دست مییابد، سپس با پردازش مجدد در سمت کارخواه «ادامه میدهد».
این راهحل مؤثری است، اما میتواند معایب قابلتوجهی در عملکرد داشته باشد.
نقطه ضعف اصلی رندر کردن سمت سرور با بازآبرسانی این است که میتواند تأثیر منفی قابلتوجهی بر TBT و INP داشته باشد، حتی اگر FCP را بهبود بخشد. صفحههایی که در سمت سرور رندر میشوند ممکن است بارشده و تعاملی بهنظر برسند، اما تا زمانی که اسکریپتهای سمت کارخواه برای مؤلفهها اجرا نشوند و گردانندههای رویداد پیوست نشوند، نمیتوانند به ورودی پاسخ دهند. در تلفن همراه، این کار میتواند چند دقیقه طول بکشد و باعث سردرگمی و ناامیدی کاربر شود.
مشکل بازگرداندن به حالت اولیه: یک برنامه با قیمت دو برنامه
برای اینکه جاوا اسکریپت سمت کارخواه بتواند بهطور دقیق از جایی که سرور متوقف شده است ادامه دهد، بدون اینکه دوباره همه دادههایی را که سرور HTML خود را با آنها ارائه کرده است درخواست کند، اکثر راهحلهای ارائه سمت سرور، پاسخ را از وابستگیهای دادههای رابط کاربری بهصورت برچسبهای دستورگان در سند سریالسازی میکنند. Because this duplicates a lot of HTML, rehydration can cause more problems than just delayed interactivity.
سرور در پاسخ به درخواست پیمایش، شرحی از واسط کاربر برنامه را برمیگرداند، اما دادههای منبع استفادهشده برای ترکیب آن واسط کاربر و یک نسخه کامل از پیادهسازی واسط کاربر را نیز برمیگرداند که سپس در کلاینت راهاندازی میشود. رابط کاربری تا زمانی که بار کردن و اجرای bundle.js تمام نشده باشد، تعاملی نمیشود.
سنجههای عملکرد جمعآوریشده از وبسایتهای واقعی که از بازپرداخت و بازآرایی سمت سرور استفاده میکنند نشان میدهد که این روش بهندرت بهترین گزینه است. مهمترین دلیل تأثیر آن بر تجربه کاربری است، زمانی که صفحه آماده بهنظر میرسد اما هیچکدام از ویژگیهای تعاملی آن کار نمیکند.
امیدواریم که رندر کردن سمت سرور با بازآبرسانی انجام شود. در کوتاهمدت، استفاده از پردازش سمت سرور فقط برای محتوای با قابلیت ذخیره بالا در حافظه نهان میتواند TTFB را کاهش دهد و نتایجی مشابه پیشپردازش تولید کند. آبرسانی مجدد افزایشی، تدریجی، یا جزئی ممکن است کلید قابلاجراتر کردن این تکنیک در آینده باشد.
جاریسازی پرداز زدن سمت سرور و بازآبرسانی تدریجی
پرداز سمت سرور در چند سال گذشته پیشرفتهای زیادی داشته است.
جاریسازی پردازش سمت سرور
به شما امکان میدهد HTML را بهصورت تکهتکه ارسال کنید تا مرورگر بتواند بهتدریج آن را پردازش کند. این کار میتواند نشانهگذاری را سریعتر به کاربران شما برساند و «اولین رنگآمیزی محتوایی» شما را تسریع کند. در React، جاریسازیها در renderToPipeableStream() ناهمگام هستند، درحالیکه در renderToString() همگام هستند، یعنی فشار برگشتی بهخوبی مدیریت میشود.
آبرسانی پیشرونده نیز ارزش بررسی دارد (React آن را پیادهسازی کرده است). با این رویکرد، بخشهای تکی برنامه ارائهشده توسط سرور بهمرور زمان «راهاندازی» میشوند، بهجای رویکرد رایج فعلی که کل برنامه را بهطور همزمان مقداردهی اولیه میکند. این کار میتواند به کاهش مقدار جاوا اسکریپت موردنیاز برای تعاملی کردن صفحهها کمک کند، زیرا به شما امکان میدهد ارتقای سمت کارخواه بخشهای با اولویت پایین صفحه را بهتعویق بیندازید تا از مسدود شدن رشته اصلی جلوگیری کنید و اجازه دهید تعاملات کاربر زودتر پساز شروع آنها توسط کاربر اتفاق بیفتد.
بازآبرسانی تدریجی همچنین میتواند به شما کمک کند از یکی از رایجترین تلههای بازآبرسانی در پردازش سمت سرور اجتناب کنید: درخت DOM پردازششده در سمت سرور ازبین میرود و سپس بلافاصله بازسازی میشود، اغلب به این دلیل که پردازش همگام اولیه در سمت کارخواه به دادههایی نیاز دارد که کاملاً آماده نیستند، معمولاً یک Promise که هنوز حل نشده است.
آبرسانی جزئی
اجرای آبرسانی جزئی دشوار بوده است. این رویکرد، افزونهای از آبرسانی تدریجی است که بخشهای مجزای صفحه (مؤلفهها، نماها، یا درختها) را تجزیهوتحلیل میکند و بخشهایی را که تعاملپذیری کم یا واکنشپذیری ندارند شناسایی میکند. برای هریک از این بخشهای عمدتاً ایستا، کد جاوا اسکریپت مربوطه سپس به ارجاعهای بیاثر و ویژگیهای تزئینی تبدیل میشود و ردپای سمت کارخواه آنها را تقریباً به صفر کاهش میدهد.
رویکرد آبرسانی جزئی با مشکلات و سازشهای خاص خود همراه است. این امر چالشهای جالبی را برای ذخیرهسازی موقت ایجاد میکند و ناوبری سمت کارخواه به این معنی است که نمیتوانیم فرض کنیم HTML ارائهشده توسط سرور برای بخشهای غیرفعال برنامه بدون بارگیری کامل صفحه دردسترس است.
پرداز زدن سهریختی
اگر کارگران خدمات گزینهای برای شما هستند، ارائه تریزومورفیک را درنظر بگیرید. این تکنیک به شما امکان میدهد از رندرینگ سمت سرور جاریسازی برای پیمایشهای اولیه یا غیرجاوا اسکریپت استفاده کنید و سپس به کارگر سرویس خود اجازه دهید رندرینگ HTML را برای پیمایشها پساز نصب برعهده بگیرد. این کار میتواند مؤلفهها و الگوهای ذخیرهشده در حافظه نهان را بهروز نگه دارد و پیمایشهای سبک SPA را برای ارائه نماهای جدید در همان جلسه فعال کند. این رویکرد زمانی بهترین عملکرد را دارد که بتوانید همان کد الگو و مسیریابی را بین سرور، صفحه کارخواه، و کارگر سرویس همرسانی کنید.
ملاحظات بهینهسازی موتور جستجو
هنگام انتخاب استراتژی پرداز وب، تیمها اغلب تأثیر بهینهسازی موتور جستجو را درنظر میگیرند. پرداخت سمت سرور انتخابی پرطرفدار برای ارائه تجربهای با «ظاهر کامل» است که خزندهها بتوانند آن را تفسیر کنند. خزندهها میتوانند جاوا اسکریپت را درک کنند، اما اغلب محدودیتهایی در نحوه پردازش آنها وجود دارد. پرداز طرف کارخواه میتواند کار کند، اما اغلب به آزمایش و سربار اضافی نیاز دارد. اخیراً، پرداز پویای نیز به گزینهای تبدیل شده است که اگر معماری شما بهشدت به جاوا اسکریپت سمت کارخواه وابسته است، ارزش بررسی دارد.
نتیجهگیری
هنگام تصمیمگیری درباره رویکردی برای ارائه، گلوگاههایتان را بسنجید و درک کنید. بررسی کنید که آیا پردازش ایستا یا پردازش سمت سرور میتواند بخش عمدهای از کار را برایتان انجام دهد. ارسال HTML با حداقل جاوا اسکریپت برای تعاملی کردن تجربه مشکلی ندارد. در اینجا یک اینفوگرافیک مفید وجود دارد که طیف سرور-کارخواه را نشان میدهد:
دستاندرکاران
از همه بهخاطر مرورها و الهامبخشیهایشان سپاسگزاریم:
جفری پوزنیک، حسین جیرده، شوبی پانیکر، کریس هارلسون، و سباستین مارکباگه.