III. Tối ưu hiệu quả Interstitial với Firebase
Dạo qua phần 1 và phần 2, ta sẽ thấy cho dù tuân thủ tuyệt đối policy, preload chuẩn chỉnh, thì đôi khi show rate vẫn không đẹp, lòng ta vẫn sẽ đầy thắc mắc tại sao lại thế, rồi làm sao để tối ưu doanh thu, giữ chân người dùng. Ta cùng tham khảo một phương pháp mà theo kinh nghiệm bản thân mình là khá ổn, cũng nhận thấy nhiều game/app lớn sử dụng phương pháp tương tự.
1. Các yếu tố ảnh hướng đến performance:
Ở đây ta chỉ bàn về các yếu tố trong tầm kiểm soát, không bàn đến các yếu tố do ad networks kiểm soát. Vậy ta kiểm soát được những gì? Đó là vị trí đặt quảng cáo, và tần suất hiện quảng cáo.
Vậy, câu hỏi thứ nhất là làm sao để chọn các vị trí đặt quảng cáo “dễ” có CTR cao nhất (tất nhiên phải tuân thủ policy), và có nhiều chỗ để hiển thị quảng cáo nhất.
Tần suất hiện quảng cáo thì ai cũng nghĩ càng cao càng tốt, càng hiển thị được nhiều. Nhưng có một thực tế là hiển thị quá nhiều quảng cáo cho cùng một user, trong cùng một phiên chơi sẽ làm tụt eCpm; đồng thời quá nhiều quảng cáo cũng làm user khó chịu (bad experience), dễ quit app, bỏ game, xóa game sớm. Vậy câu hỏi thứ 2 sẽ là làm sao để hiển thị được tối đa quảng cáo mà vẫn duy trì eCpm cũng như các thông số user experience (retention, daily engagement).
Bản thân AdMob đã tích hợp sẵn tính năng Frequency Capping trên giao diện của AdMob. Bạn không cần phải thay đổi gì trong code cũng có thể đặt được tính năng capping này. Nguyên lý khá đơn giản, bạn có thể đặt một con số giới hạn X impression trong Y phút (hoặc giờ/ngày). AdMob sẽ tự động dừng trả về quảng cáo khi đạt con số này
![](https://i2.wp.com/dumbcoder.org/wp-content/uploads/2019/08/admob-capping.jpg?fit=640%2C141&ssl=1)
Tuy nhiên, cách này theo bản thân mình thì tuy có ưu điểm dễ dàng, thuận tiện, phù hợp với các bạn muốn đơn giản nhưng cũng có các hạn chế sau:
- khó đặt được giới hạn theo đúng ý: ví dụ bạn muốn đặt 5 impressions/30 phút, coi như là mỗi session người chơi (khoảng 30p) chỉ hiện 5 impressions thôi. Tuy nhiên cách này vẫn có thể dẫn đến trường hợp 5 impressions này được show ra toàn bộ trong vòng 1p (thậm chí 30s). Hoàn toàn không tốt cho UX (users experience)
- không tìm được đâu là giá trị tốt nhất: việc thay đổi có thể nhìn thấy kết quả theo doanh thu tức thời, nhưng hoàn toàn khó để đánh giá các yếu tố về UX, cũng như khó đánh giá kết quả lâu dài.
Với Firebase A/B testing, bạn có một công cụ tuyệt hảo để có thể thử nghiệm các vị trí đặt quảng cáo, các tần suất hiện quảng cáo khác nhau để tìm ra bộ giá trị thích hợp nhất cho ứng dụng của mình.
![](https://i0.wp.com/dumbcoder.org/wp-content/uploads/2019/08/feature.jpg?resize=390%2C192&ssl=1)
Cặp đôi hoàn hảo cho ứng dụng của bạn
2. Kiểm soát tần suất quảng cáo (frequency)
Ta xét trước một cách dùng đơn giản nhất của Interstitial, đó là chỉ hiển thi quảng cáo tại một ví trí: khi GameOver. Nếu đơn giản vậy có gì mà phải suy nghĩ nhỉ? Cứ GameOver thì hiện thôi? 30s chết, hiện. 5s chết, cũng hiện. Thậm chí 2s chết cũng hiện luôn. Như vậy liệu có thật sự ổn?
Theo mình thì không hề ổn. Kể cả các game casual, siêu quảng cáo như của Voodoo, họ cũng không hiển thị quảng cáo tất cả các lần GameOver, mà có một giới hạn.
Vậy cần đặt một giới hạn cho việc hiển thị. Đặt giới hạn có nhiều cách, như là 3 lần game over thì hiện 1 lần. Tuy nhiên cách này có thể có hạn chế, là tùy vào “khả năng” của users, mà thời gian họ game over rất khác nhau. Users kém có thể chỉ 10s, 20s. Users khá có thể chơi tận 1p, 2p, hoặc 5p lận. Hiển thị cách này “cào bằng” số lần chơi của users, làm cho thời gian hiển thị ads quá khác nhau, có thể là quá ngắn, hoặc quá dài. Ngắn quá thì không tốt dễ mất users, mà dài quá cũng không hay, thiệt hại doanh thu.
Một cách khá ổn đó là dùng 1 khoảng ngắt quãng (interval) giữa 2 lần quảng cáo. Mình đánh giá cách này tốt nhất. Từ góc nhìn của users, với một khoảng thời gian đủ lớn khi chơi game, họ có thể “quên” là vừa nhìn thấy 1 impression rồi, và dễ chấp nhận impression tiếp theo. Quãng thời gian này tùy thuộc rất nhiều vào dòng game, tập users. Đây sẽ chính là giá trị chúng ta có thể kiểm soát trong code và A/B test được nó.
Đây là các bước để kiểm soát interstitial frequency bằng 1 quãng ngắt (interval) và A/B test để tìm ra giá trị tốt nhất này:
- Tạo giá trị interstitial_interval trên Firebase RemoteConfig
- Trong code của ứng dụng, sử dụng giá trị này để kiểm soát việc hiển thị interstitial
- Chạy Firebase A/B experiment để đo đếm các tác động đến UX cũng như revenue.
a.Tạo giá trị Interstitial_interval trên Firebase RemoteConfig:
Cách setup cơ bản của RemoteConfig và A/B testing bạn có thể tham khảo lại tại đây. Ta sẽ tạo 1 key là interstitial_interval với giá trị mặc định là 120 (ứng với 120 giây – 2 phút). Tất nhiên, giá trị mặc định này là tùy bạn quyết định.
![](https://i2.wp.com/dumbcoder.org/wp-content/uploads/2019/08/interval.jpg?fit=640%2C142&ssl=1)
b. Sử dụng giá trị interval để kiểm soát interstitial trong ứng dụng:
Cách thực hiện khá đơn giản. Mỗi lần “cần” hiển thị interstitial, thay vì gọi trực tiếp hàm show, ta sẽ thực hiện check thời gian trước. Ta lưu lại thời gian từ lần gần nhất hiển thị interstitial (sẽ khởi tạo giá trị âm rất lớn cho biến này để lần đầu hiển thị không bị giới hạn). Dựa vào đó để kiểm tra nếu quãng thời gian từ lần gần nhất show interstitial đã vượt qua thời gian giới hạn thì ta hiển thị quảng cáo và cập nhật lại giá trị. Còn nếu không thì bỏ qua, không show Interstitial.
![](https://i2.wp.com/dumbcoder.org/wp-content/uploads/2019/08/code2.jpg?fit=640%2C209&ssl=1)
Chú ý: nếu bạn sử dụng phương pháp Singleton giống bài viết của mình, hoặc bạn cũng có callback để thực hiện sau khi hiển thị-đóng interstitial thì cần nhớ thực hiện callback đó nếu quảng cáo không được hiển thị do chưa đủ thời gian.
c. Chạy Firebase Experiment cho giá trị interval
Mục đích của việc A/B là để tìm ra giá trị interval tốt nhất, có thể tối đa doanh thu qua cân bằng giữa 2 việc: số lượng quảng cáo/click (doanh thu tức thời) và users experience (giữa chân users, từ đó duy trì doanh thu lâu dài). Như vậy ta cần để ý đến các metrics kết quả là:
- UX (user experience) metrics: daily engagement, retention từ D1->D7
- Revenue metrics: nếu muốn chính xác 100% revenue thì bạn có thể làm test chi tiết hơn bằng cách tạo các ad unit khác nhau cho từng giá trị interval, từ đó xem doanh thu (revenue, eCpm, CTR) chính xác trên AdMob cho từng AdUnit. Tuy nhiên, để đơn giản trong ví dụ này mình sử dụng luôn 2 metrics có sẵn khi link AdMob với Firebase đó là ad_impression và ad_click.
![](https://i1.wp.com/dumbcoder.org/wp-content/uploads/2019/08/metrics.jpg?fit=640%2C293&ssl=1)
Giá trị mặc định cho interval ở trên là 2 phút. Giả sử ta muốn A/B test, xem giữa các giá trị 1 phút – 2 phút – 3 phút, giá trị nào là tốt nhất. Vậy ta chia đều users ngẫu nhiên thành 3 tập và nhận lần lượt các giá trị này:
![](https://i2.wp.com/dumbcoder.org/wp-content/uploads/2019/08/variant.jpg?fit=640%2C594&ssl=1)
Chú ý: với sức mạnh của Firebase A/B test, bạn có thể custom (tùy chỉnh) việc test cực kỳ chi tiết. Một số ví dụ:
- lo sợ việc ảnh hưởng doanh thu cho các thị trường top? Hoàn toàn có thể giới hạn việc test chỉ cho các thị trường “thấp giá trị”
- lo sợ test toàn bộ users gây ảnh hưởng quá lớn đến doanh thu? Dễ dàng lựa chọn chỉ test trên một tập users nhỏ (10, 20, 30% users tùy ý)
- tùy ý lựa chọn giới hạn tập users test dựa vào event, property hoặc tập audience. Một ví dụ “dị” là chỉ test Ads Frequency cho users đã vượt qua level 10, highScore lớn hơn 100 etc… Hãy lắng nghe trí tưởng tượng của bạn!
Thả cho test chạy ít nhất 1 tuần (khuyến khích 2 tuần cho chắc chắn), Firebase sẽ báo về một bảng kết quả tương tự như sau:
![](https://i2.wp.com/dumbcoder.org/wp-content/uploads/2019/08/result.jpg?fit=640%2C632&ssl=1)
Cần chú ý rằng, Firebase đánh giá nhóm thắng/thua/tốt nhất (leader) dựa vào duy nhất metric chủ đạo mà bạn lựa chọn (trong hình là mình chọn Daily Engagement), chứ không tự cân bằng toàn bộ các thông số. Do đó, thực tế là: có thể UX metrics sẽ tăng, nhưng revenue (ngắn hạn) sẽ giảm hoặc ngược lại. Bạn sẽ phải là người tự cân bằng và chọn ra phương án tốt nhất.
Lấy ví dụ, retention tụt 5% D1, 2%D2-D3 và 1% D7; nhưng bạn có nhiều hơn 10% ad_impression và ad_click. Vậy nên chọn gì đây?
Bạn có thể thực hiện test nhiều lần, thay đổi từ từ. Lần một test 1p, 2p, 3p. Nếu 1p tốt nhất thì có thể thử thêm 45s, 1p, 1p15s xem có khác biệt không. Kiên trì và thử sai là cách duy nhất để tìm ra phương án tối ưu. Rất may là chúng ta có Firebase giúp quá trình thử sai này nhanh và ít đau đớn hơn.
3. Kiểm soát các vị trí đặt quảng cáo:
Thực sự thì tham khảo từ các dòng game nặng về quảng cáo, cũng như từ kinh nghiệm bản thân, mình thấy gần như không nên hạn chế vị trí quảng cáo. Có ý kiến cho rằng dù là GameOver (kết thúc ván) nhưng cũng chỉ nên show quảng cáo khi users thắng, không show khi users thua. Hoặc không nên show khi mới vào game, khi users thoát etc… Tuy nhiên, phải nói là tùy dòng game, cũng như tập users mà mọi thứ sẽ khác.
Mình cảm thấy không quá cần thiết khi phải hạn chế vị trí quảng cáo. Do thường nó có thể làm ảnh hưởng khá nặng đến lượng impression (show rate, revenue), mà không thay đổi quá nhiều users experience (retention, daily engagement). Tuy nhiên, nếu có đủ nguồn lực, cũng như traffic rất lớn, thì việc tối ưu vài % là vẫn nên làm.
Ta xem xét thử một ví dụ A/B test 2 vị trí đặt quảng cáo: GameOver (kết thúc ván) và GameStart (trước khi bắt đầu ván chơi). Để xem xét hiệu quả doanh thu của các vị trí đặt khác nhau, ta nên tạo các ad unit khác nhau cho từng vị trí. Vậy các bước thực hiện việc A/B test trong trường hợp này sẽ là:
- tạo ad unit ứng với các vị trí hiển thị trên AdMob của bạn
- tạo biến kiểm soát việc có hiển thị quảng cáo tại từng vị trí hay không trên Firebase RemoteConfig
- kiểm tra biến đó trong code để hiện quảng cáo
- chạy Firebase experiment để đo đếm hiệu quả
Ta tạo 2 ad units cho 2 vị trí đặt quảng cáo:
![](https://i2.wp.com/dumbcoder.org/wp-content/uploads/2019/08/ad-units.jpg?resize=446%2C118&ssl=1)
Tạo tiếp 2 cặp giá trị trên RemoteConfig để điều chỉnh việc hiển thị quảng cáo:
![](https://i0.wp.com/dumbcoder.org/wp-content/uploads/2019/08/remote.jpg?resize=404%2C222&ssl=1)
Tiếp theo trong code của mình ta check 2 biến này, để kiểm tra có cần hiển thị quảng cáo tại mỗi placement hay không:
![](https://i2.wp.com/dumbcoder.org/wp-content/uploads/2019/08/code-3.jpg?fit=640%2C318&ssl=1)
Cuối cùng là tương tự phần 2, ta sẽ tạo nhóm users thành các group khác nhau để test: hiện quảng cáo chỉ khi game over, hiện quảng cáo chỉ khi game start, hay là hiện quảng cáo ở cả 2 vị trí:
![](https://i2.wp.com/dumbcoder.org/wp-content/uploads/2019/08/varian-2.jpg?fit=640%2C198&ssl=1)
Ghi nhớ là duy trì việc test trong ít nhất 1 tuần (nên là 2 tuần) để có kết quả chính xác.
4. Tổng kết:
A/B test là một công cụ mạnh, và việc tích hợp A/B test để tối ưu hết cỡ hiệu năng quảng cáo trong ứng dụng là điều “phải” làm. Một số kinh nghiệm/chú ý khi thực hiện việc A/B test của mình:
- nên thực hiện từng test một để tránh lẫn kết quả. Trừ khi bạn test 2 cái hoàn toàn không liên quan gì đến nhau (rất khó)
- với trường hợp tối ưu interstitial, thì có thể test frequency trước, tìm được quãng ngắt (interval) phù hợp rồi thì có thể mở rộng thêm test để tìm các placement mới (hoặc cắt các placement hiệu quả kém mà ảnh hưởng users)
Không chỉ tối ưu performance của ứng dụng qua việc thay đổi UI, cập nhật tính năng etc… việc tối ưu performance monetization (hiệu năng kiếm tiền quảng cáo) cũng là cực kỳ cần thiết. Again, monetization là một nghệ thuật, và người làm monetizing là nghệ sĩ.
Chia sẻ để cùng trở thành nghệ sĩ nhé ^^